From: Andres Mejia Date: Wed, 27 Jul 2011 02:43:07 +0000 (-0400) Subject: Imported Upstream version 0.4.5+svn3450 X-Git-Tag: archive/raspbian/1.0.1+dfsg1-4+rpi1~1^2~15^2~30 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=252c33779642abb4a61ce35757f0a0d230d03d15;p=gpac.git Imported Upstream version 0.4.5+svn3450 --- diff --git a/INSTALLME b/INSTALLME index 7f548e4..ae0f038 100644 --- a/INSTALLME +++ b/INSTALLME @@ -1,3 +1,14 @@ +Installation instructions for latest GPAC svn version: + +For Windows, Linux and Mac OS X versions, follow the instructions on http://gpac.sourceforge.net/home_download.php + +For WindowsMobile platform, get the latest package of gpac extra libs available on GPAC svn: +http://gpac.svn.sourceforge.net/viewvc/gpac/trunk/gpac_extra_libs/gpac_extra_libs.zip +and follow the instructions in gpac/doc/INSTALL.wCE + + + + Installation instructions for GPAC 0.4.5 - December 2008: diff --git a/Makefile b/Makefile index 3bfe4ce..a04681a 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ all: version $(MAKE) -C modules all version: - @if which svnversion >/dev/null; then echo "#define GPAC_SVN_REVISION \"$(shell svnversion \"$(SRC_PATH)\")\"" > $(SRC_PATH)/include/gpac/version.h ; else echo "No SVN Version found"; fi + @if which svnversion >/dev/null; then echo "#define GPAC_SVN_REVISION \"$(shell svnversion $(SRC_PATH) )\"" > $(SRC_PATH)/include/gpac/version.h ; else echo "No SVN Version found"; fi lib: version $(MAKE) -C src all @@ -57,7 +57,7 @@ install: $(INSTALL) -d "$(DESTDIR)$(prefix)" $(INSTALL) -d "$(DESTDIR)$(prefix)/bin" $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/MP4Box "$(DESTDIR)$(prefix)/bin" - $(MAKE) -C applications install + $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/MP4Client "$(DESTDIR)$(prefix)/bin" $(INSTALL) -d "$(DESTDIR)$(moddir)" $(INSTALL) bin/gcc/*.$(DYN_LIB_SUFFIX) "$(DESTDIR)$(moddir)" rm -f $(DESTDIR)$(moddir)/libgpac.$(DYN_LIB_SUFFIX) @@ -86,14 +86,14 @@ install: uninstall: $(MAKE) -C applications uninstall - rm -rf $(moddir) - rm -rf $(prefix)/$(libdir)/libgpac* - rm -rf $(prefix)/bin/MP4Box - rm -rf $(prefix)/bin/MP4Client - rm -rf $(mandir)/man1/mp4box.1 - rm -rf $(mandir)/man1/mp4client.1 - rm -rf $(mandir)/man1/gpac.1 - rm -rf $(prefix)/share/gpac + rm -rf $(DESTDIR)$(moddir) + rm -rf $(DESTDIR)$(prefix)/$(libdir)/libgpac* + rm -rf $(DESTDIR)$(prefix)/bin/MP4Box + rm -rf $(DESTDIR)$(prefix)/bin/MP4Client + rm -rf $(DESTDIR)$(mandir)/man1/mp4box.1 + rm -rf $(DESTDIR)$(mandir)/man1/mp4client.1 + rm -rf $(DESTDIR)$(mandir)/man1/gpac.1 + rm -rf $(DESTDIR)$(prefix)/share/gpac installdylib: ifeq ($(CONFIG_WIN32),yes) @@ -121,7 +121,7 @@ install-lib: $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/include/gpac/internal/*.h "$(DESTDIR)$(prefix)/include/gpac/internal" mkdir -p "$(DESTDIR)$(prefix)/include/gpac/modules" $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/include/gpac/modules/*.h "$(DESTDIR)$(prefix)/include/gpac/modules" - $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/config.h "$(DESTDIR)$(prefix)/include/gpac/configuration.h" + $(INSTALL) $(INSTFLAGS) -m 644 config.h "$(DESTDIR)$(prefix)/include/gpac/configuration.h" ifeq ($(GPAC_ENST), yes) mkdir -p "$(DESTDIR)$(prefix)/include/gpac/enst" $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/include/gpac/enst/*.h "$(DESTDIR)$(prefix)/include/gpac/enst" diff --git a/applications/GPAX/GPAXPlugin.cpp b/applications/GPAX/GPAXPlugin.cpp index 98e3ff6..d37e823 100644 --- a/applications/GPAX/GPAXPlugin.cpp +++ b/applications/GPAX/GPAXPlugin.cpp @@ -294,62 +294,10 @@ BOOL CGPAXPlugin::PreTranslateMessage(MSG* pMsg) LRESULT CGPAXPlugin::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { if (m_term) return 0; - - char config_path[GF_MAX_PATH], config_test_file[GF_MAX_PATH]; - char *gpac_cfg; const char *str; if (m_hWnd==NULL) return 0; - - gpac_cfg = "GPAC.cfg"; - - //Here we retrieve GPAC config file in the install diractory, which is indicated in the - //Registry - HKEY hKey = NULL; - DWORD dwSize; -#ifdef _WIN32_WCE - u16 w_path[1024]; - RegOpenKeyEx(GPAC_REG_KEY, TEXT("Software\\GPAC"), 0, KEY_READ, &hKey); - DWORD dwType = REG_SZ; - dwSize = GF_MAX_PATH; -#ifdef _DEBUG - if (RegQueryValueEx(hKey, TEXT("DebugDir"), 0, &dwType, (LPBYTE) w_path, &dwSize) != ERROR_SUCCESS) -#endif - RegQueryValueEx(hKey, TEXT("InstallDir"), 0, &dwType, (LPBYTE) w_path, &dwSize); - CE_WideToChar(w_path, (char *)config_path); - RegCloseKey(hKey); -#else - /*locate the key in current user, then in local machine*/ - if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\GPAC", 0, KEY_READ, &hKey) != ERROR_SUCCESS) - RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\GPAC", 0, KEY_READ, &hKey); - dwSize = GF_MAX_PATH; -#ifdef _DEBUG - if (RegQueryValueEx(hKey, "DebugDir", NULL, NULL,(unsigned char*) config_path, &dwSize) != ERROR_SUCCESS) -#endif - RegQueryValueEx(hKey, "InstallDir", NULL, NULL,(unsigned char*) config_path, &dwSize); - RegCloseKey(hKey); - - /*do we have write access?*/ - strcpy(config_test_file, config_path); - assert(strlen(config_path)+strlen(gpac_cfg)+1familly, bf->name, bf->type); } } + if (!strcmp(n->name, "CacheTexture")) { + fprintf(f, "\t/*GPAC private*/\n"); + fprintf(f, "\tu8 *data;\n"); + fprintf(f, "\tu32 data_len;\n"); + } fprintf(f, "} M_%s;\n\n\n", n->name); } @@ -878,6 +883,9 @@ void WriteNodeCode(GF_List *BNodes) } } } + if (!strcmp(n->name, "CacheTexture")) { + fprintf(f, "\tif (p->data) gf_free(p->data);\n"); + } if (is_parent) fprintf(f, "\tgf_sg_vrml_parent_destroy((GF_Node *) p);\t\n"); fprintf(f, "\tgf_node_free((GF_Node *) p);\n}\n\n"); @@ -1686,7 +1694,7 @@ int main (int argc, char **argv) BNode *n; BField *bf; - if (argc < 2) { + if (argc < 1) { PrintUsage(); return 0; } @@ -1697,16 +1705,18 @@ int main (int argc, char **argv) fskip = NULL; - i=1; - if (!strcmp(argv[i], "-ndt")) { - generate_ndt = 1; - } else if (argv[i][0]=='-') { - fskip = fopen(argv[i+1], "rt"); - if (!fskip) { - printf("file %s not found\n", argv[i+1]); - return 0; + if (argc>1) { + i=1; + if (!strcmp(argv[i], "-ndt")) { + generate_ndt = 1; + } else 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; } - i+=2; } nbVersion=1; while (1) { diff --git a/applications/generators/MPEG4/templates10.txt b/applications/generators/MPEG4/templates10.txt index 70b3d0c..1c4898a 100644 --- a/applications/generators/MPEG4/templates10.txt +++ b/applications/generators/MPEG4/templates10.txt @@ -1,53 +1,53 @@ -PROTO CacheTexture [#%NDT=SFWorldNode,SF2DNode,SF3DNode,SFTextureNode %COD=N -field SFInt32 objectTypeIndication 0 -field SFString decoderSpecificInfo "" -field SFString image "" -field SFString cacheURL "" -field MFURL cacheOD [] -field SFInt32 expirationDate 0 -field SFBool repeatS TRUE -field SFBool repeatT TRUE -]{} - -PROTO EnvironmentTest [ #%NDT=SFWorldNode,SF2DNode,SF3DNode %COD=N -eventIn SFBool evaluate -exposedField SFBool enabled TRUE -exposedField SFInt32 parameter 0 -exposedField SFString compareValue "" -exposedField SFBool evaluateOnChange TRUE -eventOut SFBool valueLarger -eventOut SFBool valueEqual -eventOut SFBool valueSmaller -eventOut SFString parameterValue -] {} - - -PROTO KeyNavigator [ #%NDT=SFWorldNode,SF2DNode,SF3DNode %COD=N -eventIn SFBool setFocus -exposedField SF3DNode sensor NULL -exposedField SF2DNode left NULL -exposedField SF2DNode right NULL -exposedField SF2DNode up NULL -exposedField SF2DNode down NULL -exposedField SF2DNode select NULL -exposedField SF2DNode quit NULL -exposedField SFFloat step 0 -eventOut SFBool focusSet -]{} - -PROTO SpacePartition [ #%NDT=SFWorldNode,SF3DNode %COD=N -eventIn MF3DNode addChildren -eventIn MF3DNode removeChildren -exposedField MF3DNode children [] -exposedField SFUrl SPStream NULL -]{} - -PROTO Storage [ #%NDT=SFWorldNode,SF2DNode,SF3DNode %COD=N -eventIn SFBool forceSave -eventIn SFBool forceRestore -exposedField SFBool auto TRUE -field SFInt32 expireAfter 0 -field SFString name "" -field MFAttrRef storageList [] -]{} - +PROTO CacheTexture [#%NDT=SFWorldNode,SF2DNode,SF3DNode,SFTextureNode %COD=N +field SFInt32 objectTypeIndication 0 +field SFString decoderSpecificInfo "" +field SFString image "" +field SFString cacheURL "" +field MFURL cacheOD [] +field SFInt32 expirationDate 0 +field SFBool repeatS TRUE +field SFBool repeatT TRUE +]{} + +PROTO EnvironmentTest [ #%NDT=SFWorldNode,SF2DNode,SF3DNode %COD=N +eventIn SFBool evaluate +exposedField SFBool enabled TRUE +exposedField SFInt32 parameter 0 +exposedField SFString compareValue "" +exposedField SFBool evaluateOnChange TRUE +eventOut SFBool valueLarger +eventOut SFBool valueEqual +eventOut SFBool valueSmaller +eventOut SFString parameterValue +] {} + + +PROTO KeyNavigator [ #%NDT=SFWorldNode,SF2DNode,SF3DNode %COD=N +eventIn SFBool setFocus +exposedField SF3DNode sensor NULL +exposedField SF2DNode left NULL +exposedField SF2DNode right NULL +exposedField SF2DNode up NULL +exposedField SF2DNode down NULL +exposedField SF2DNode select NULL +exposedField SF2DNode quit NULL +exposedField SFFloat step 0 +eventOut SFBool focusSet +]{} + +PROTO SpacePartition [ #%NDT=SFWorldNode,SF3DNode %COD=N +eventIn MF3DNode addChildren +eventIn MF3DNode removeChildren +exposedField MF3DNode children [] +exposedField SFURL SPStream NULL +]{} + +PROTO Storage [ #%NDT=SFWorldNode,SF2DNode,SF3DNode %COD=N +eventIn SFBool forceSave +eventIn SFBool forceRestore +exposedField SFBool auto TRUE +field SFInt32 expireAfter 0 +field SFString name "" +field MFAttrRef storageList [] +]{} + diff --git a/applications/generators/MPEG4/templates8.txt b/applications/generators/MPEG4/templates8.txt index 93f2a87..2a907b2 100644 --- a/applications/generators/MPEG4/templates8.txt +++ b/applications/generators/MPEG4/templates8.txt @@ -1,124 +1,124 @@ -#-- Version 8 --# -# -# Beta for Symbolic Music Representation (SMR) -# -# templates for the BIFS nodes -# ============================= -# Notations I = Infinity -# %q=x Quantization method x -# 0 None -# 1 3D Position (SFVec3F) -# 2 2D Position (SFVec2F) -# 3 drawing Order -# 4 Color (SFColor) -# 5 Texture Coordinate -# 6 Angle (SFFloat 0-2PI) -# 7 Scale (SFVec2F or SFVec3F) -# 8 Interpolators keys -# 9 Normals -# 10 Rotations (SFRotation) -# 11 Object Size 3D (SFVec3F and SFFloat) -# 12 Object Size 2D -# 13 Linear Quantization (+ Nb Bits) -# 14 Index (of IndexedFaceSet,...) -# 15 SFVec4f -# 16 Reserved -# -# %a=y Animation method for fields that can be animated -# -## OO 081498 To match BIFS's update numbering -# 0 None -# 1 Position 3D -# 2 Position 2D -# 4 Color -# 6 Angle -# 7 Float -# 8 BoundFloat (intensities, transparencies,...) -# 9 Normal -# 10 Rotation -# 11 Size 3D -# 12 Size 2D -# 13 Integer -# 14 Reserved -## 0 3D Position -## 1 2D positon -## 2 Color (SFColor) -## 3 Angle (SFFloat 0-2pi) -## 4 Normals -## 5 Scale (SFVec2F) -## 6 Rotation (SFRotation) -## 7 Object Size or Scalar (SFFloat) -# -# %b=[min,max] bounds of value -# For each scalar or vectorial value, bounds may be specified. -# This will be used to check if user-specified values are out of bounds. In -# this case, bounds specified in the templates will be used (if not infinity). -# -# %NDT=Node Data Type -# For each node, one or several Node Data Types are assigned, specifying which node sub -# types the node belongs to. Moreover, each field of type SF/MF3DNode is re assigned -# a unique correct NodeDataType according to specify the allowed values of the field -# -# %COD Type of encoding -# N Normal Syntax : The node syntax follos the generic syntax for nodes -# S Special Syntax : The node has a specific syntax -# -# -# NCT => VRML type equivalence -# -# SF/MFxxxNode => SF/MFNode -# SF/MFURL => SF/MFString -# SF/MFCommandBuffer => SF/MFString -# SF/MFScript => SF/MFString -# -# -# Modification History -# ------------------------------------------------ -# October 9, 2006 [MBS] Added SMR nodes based on w8121 - -# -# Symbolic Music Representation (SMR) nodes -# - - -PROTO ScoreShape [ #%NDT=SFWorldNode,SF2DNode,SF3DNode %COD=N -exposedField SFMusicScoreNode score NULL -exposedField SFNode geometry NULL -]{} - - -PROTO MusicScore [ #%NDT=SFWorldNode,SFMusicScoreNode %COD=N -eventIn SFBool executeCommand -eventIn SFString gotoLabel -eventIn SFInt32 gotoMeasure -eventIn SFTime highlightTimePosition -eventIn SFVec3f mousePosition -exposedField MFString argumentsOnExecute [] -exposedField SFString commandOnExecute "" -exposedField SFInt32 firstVisibleMeasure 0 -exposedField SFBool hyperlinkEnable TRUE -exposedField SFBool loop FALSE -exposedField MFString partsLyrics [] -exposedField MFInt32 partsShown [] -exposedField SFTime scoreOffset 0.0 -exposedField SFVec2f size -1, -1 -exposedField SFFloat speed 1.0 #%b=(-I,+I) #%q=0 #%a=7 -exposedField SFTime startTime 0 #%b=(-I,+I) -exposedField SFTime stopTime 0 #%b=(-I,+I) -exposedField SFFloat transpose 0.0 -exposedField MFURL url [] -exposedField MFURL urlSA [] -exposedField SFString viewType "" -eventOut SFString activatedLink -eventOut MFString availableCommands -eventOut MFString availableLabels -eventOut MFString availableLyricLanguages -eventOut MFString availableViewTypes -eventOut SFBool isActive -eventOut SFVec3f highlightPosition -eventOut SFInt32 lastVisibleMeasure -eventOut SFInt32 numMeasures -eventOut MFString partNames -]{} - - +#-- Version 8 --# +# +# Beta for Symbolic Music Representation (SMR) +# +# templates for the BIFS nodes +# ============================= +# Notations I = Infinity +# %q=x Quantization method x +# 0 None +# 1 3D Position (SFVec3F) +# 2 2D Position (SFVec2F) +# 3 drawing Order +# 4 Color (SFColor) +# 5 Texture Coordinate +# 6 Angle (SFFloat 0-2PI) +# 7 Scale (SFVec2F or SFVec3F) +# 8 Interpolators keys +# 9 Normals +# 10 Rotations (SFRotation) +# 11 Object Size 3D (SFVec3F and SFFloat) +# 12 Object Size 2D +# 13 Linear Quantization (+ Nb Bits) +# 14 Index (of IndexedFaceSet,...) +# 15 SFVec4f +# 16 Reserved +# +# %a=y Animation method for fields that can be animated +# +## OO 081498 To match BIFS's update numbering +# 0 None +# 1 Position 3D +# 2 Position 2D +# 4 Color +# 6 Angle +# 7 Float +# 8 BoundFloat (intensities, transparencies,...) +# 9 Normal +# 10 Rotation +# 11 Size 3D +# 12 Size 2D +# 13 Integer +# 14 Reserved +## 0 3D Position +## 1 2D positon +## 2 Color (SFColor) +## 3 Angle (SFFloat 0-2pi) +## 4 Normals +## 5 Scale (SFVec2F) +## 6 Rotation (SFRotation) +## 7 Object Size or Scalar (SFFloat) +# +# %b=[min,max] bounds of value +# For each scalar or vectorial value, bounds may be specified. +# This will be used to check if user-specified values are out of bounds. In +# this case, bounds specified in the templates will be used (if not infinity). +# +# %NDT=Node Data Type +# For each node, one or several Node Data Types are assigned, specifying which node sub +# types the node belongs to. Moreover, each field of type SF/MF3DNode is re assigned +# a unique correct NodeDataType according to specify the allowed values of the field +# +# %COD Type of encoding +# N Normal Syntax : The node syntax follos the generic syntax for nodes +# S Special Syntax : The node has a specific syntax +# +# +# NCT => VRML type equivalence +# +# SF/MFxxxNode => SF/MFNode +# SF/MFURL => SF/MFString +# SF/MFCommandBuffer => SF/MFString +# SF/MFScript => SF/MFString +# +# +# Modification History +# ------------------------------------------------ +# October 9, 2006 [MBS] Added SMR nodes based on w8121 + +# +# Symbolic Music Representation (SMR) nodes +# + + +PROTO ScoreShape [ #%NDT=SFWorldNode,SF2DNode,SF3DNode %COD=N +exposedField SFMusicScoreNode score NULL +exposedField SF2DNode geometry NULL +]{} + + +PROTO MusicScore [ #%NDT=SFWorldNode,SFMusicScoreNode %COD=N +eventIn SFBool executeCommand +eventIn SFString gotoLabel +eventIn SFInt32 gotoMeasure +eventIn SFTime highlightTimePosition +eventIn SFVec3f mousePosition +exposedField MFString argumentsOnExecute [] +exposedField SFString commandOnExecute "" +exposedField SFInt32 firstVisibleMeasure 0 +exposedField SFBool hyperlinkEnable TRUE +exposedField SFBool loop FALSE +exposedField MFString partsLyrics [] +exposedField MFInt32 partsShown [] +exposedField SFTime scoreOffset 0.0 +exposedField SFVec2f size -1 -1 +exposedField SFFloat speed 1.0 #%b=(-I,+I) #%q=0 #%a=7 +exposedField SFTime startTime 0 #%b=(-I,+I) +exposedField SFTime stopTime 0 #%b=(-I,+I) +exposedField SFFloat transpose 0.0 +exposedField MFURL url [] +exposedField MFURL urlSA [] +exposedField SFString viewType "" +eventOut SFString activatedLink +eventOut MFString availableCommands +eventOut MFString availableLabels +eventOut MFString availableLyricLanguages +eventOut MFString availableViewTypes +eventOut SFBool isActive +eventOut SFVec3f highlightPosition +eventOut SFInt32 lastVisibleMeasure +eventOut SFInt32 numMeasures +eventOut MFString partNames +]{} + + diff --git a/applications/generators/MPEG4/templates9.txt b/applications/generators/MPEG4/templates9.txt index 465437b..16f86b4 100644 --- a/applications/generators/MPEG4/templates9.txt +++ b/applications/generators/MPEG4/templates9.txt @@ -1,68 +1,68 @@ -PROTO FootPrintSetNode [#%NDT=SFWorldNode,SF3DNode,SFGeometryNode %COD=N -exposedField MFGeometryNode children [] -]{} - -PROTO FootPrintNode [#%NDT=SFWorldNode,SF3DNode,SFGeometryNode %COD=N - -exposedField SFInt32 index -1 #%b=[0,65535] -exposedField SFGeometryNode footprint NULL -]{} - -PROTO BuildingPartNode [#%NDT=SFWorldNode,SF3DNode,SFGeometryNode %COD=N - -exposedField SFInt32 index -1 #%b=[0,65535] -exposedField SFGeometryNode footprint NULL -exposedField SFInt32 buildingIndex -1 #%b=[0,65535] -exposedField SFFloat height 0 #%b=[0,I] -exposedField SFFloat altitude 0 #%b=[0,I] -exposedField MFGeometryNode alternativeGeometry [] -exposedField MFGeometryNode roofs [] -exposedField MFGeometryNode facades [] -]{} - - - -PROTO RoofNode [#%NDT=SFWorldNode,SF3DNode,SFGeometryNode %COD=N - -exposedField SFInt32 Type 0 #%b=[0,65535] -exposedField SFFloat Height 0.0 #%b=[0,I] -exposedField MFFloat SlopeAngle [0.0] #%b=[0,6.2831854] -exposedField SFFloat EaveProjection 0.0 -exposedField SFInt32 EdgeSupportIndex -1 #%b=[0,65535] -exposedField SFURL RoofTextureURL "" -exposedField SFBool IsGenericTexture TRUE -exposedField SFFloat TextureXScale 1.0 #%b=[0,I] -exposedField SFFloat TextureYScale 1.0 #%b=[0,I] -exposedField SFFloat TextureXPosition 0.0 #%b=[0,I] -exposedField SFFloat TextureYPosition 0.0 #%b=[0,I] -exposedField SFFloat TextureRotation 0.0 #%b=[0,I] -]{} - - - -PROTO FacadeNode [#%NDT=SFWorldNode,SF3DNode,SFGeometryNode %COD=N -exposedField SFFloat WidthRatio 1.0 #%b=[-I,I] -exposedField SFFloat XScale 1.0 #%b=[-I,I] -exposedField SFFloat YScale 1.0 #%b=[-I,I] -exposedField SFFloat XPosition 0.0 #%b=[-I,I] -exposedField SFFloat YPosition 0.0 #%b=[-I,I] -exposedField SFFloat XRepeatInterval 0.0 #%b=[-I,I] -exposedField SFFloat YRepeatInterval 0.0 #%b=[-I,I] -exposedField SFBool Repeat FALSE -exposedField SFURL FacadePrimitive "" -exposedField SFInt32 NbStories 0 #%b=[0,65535] -exposedField MFInt32 NbFacadeCellsByStorey 0 -exposedField MFFloat StoreyHeight 1.0 #%b=[0,I] -exposedField MFGeometryNode FacadeCellsArray [] -]{} - - -PROTO Shadow [#%NDT=SFWorldNode,SF3DNode,SFGeometryNode %COD=N -eventIn SF3DNode addChildren -eventIn SF3DNode removeChildren -exposedField MF3DNode children [] -exposedField SFBool enabled TRUE -exposedField SFBool cast TRUE -exposedField SFBool receive TRUE -exposedField SFFloat penumbra 0 #%b=[0,I] -]{} +PROTO FootPrintSetNode [#%NDT=SFWorldNode,SF3DNode,SFGeometryNode %COD=N +exposedField MFGeometryNode children [] +]{} + +PROTO FootPrintNode [#%NDT=SFWorldNode,SF3DNode,SFGeometryNode %COD=N + +exposedField SFInt32 index -1 #%b=[0,65535] +exposedField SFGeometryNode footprint NULL +]{} + +PROTO BuildingPartNode [#%NDT=SFWorldNode,SF3DNode,SFGeometryNode %COD=N + +exposedField SFInt32 index -1 #%b=[0,65535] +exposedField SFGeometryNode footprint NULL +exposedField SFInt32 buildingIndex -1 #%b=[0,65535] +exposedField SFFloat height 0 #%b=[0,I] +exposedField SFFloat altitude 0 #%b=[0,I] +exposedField MFGeometryNode alternativeGeometry [] +exposedField MFGeometryNode roofs [] +exposedField MFGeometryNode facades [] +]{} + + + +PROTO RoofNode [#%NDT=SFWorldNode,SF3DNode,SFGeometryNode %COD=N + +exposedField SFInt32 Type 0 #%b=[0,65535] +exposedField SFFloat Height 0.0 #%b=[0,I] +exposedField MFFloat SlopeAngle [0.0] #%b=[0,6.2831854] +exposedField SFFloat EaveProjection 0.0 +exposedField SFInt32 EdgeSupportIndex -1 #%b=[0,65535] +exposedField SFURL RoofTextureURL "" +exposedField SFBool IsGenericTexture TRUE +exposedField SFFloat TextureXScale 1.0 #%b=[0,I] +exposedField SFFloat TextureYScale 1.0 #%b=[0,I] +exposedField SFFloat TextureXPosition 0.0 #%b=[0,I] +exposedField SFFloat TextureYPosition 0.0 #%b=[0,I] +exposedField SFFloat TextureRotation 0.0 #%b=[0,I] +]{} + + + +PROTO FacadeNode [#%NDT=SFWorldNode,SF3DNode,SFGeometryNode %COD=N +exposedField SFFloat WidthRatio 1.0 #%b=[-I,I] +exposedField SFFloat XScale 1.0 #%b=[-I,I] +exposedField SFFloat YScale 1.0 #%b=[-I,I] +exposedField SFFloat XPosition 0.0 #%b=[-I,I] +exposedField SFFloat YPosition 0.0 #%b=[-I,I] +exposedField SFFloat XRepeatInterval 0.0 #%b=[-I,I] +exposedField SFFloat YRepeatInterval 0.0 #%b=[-I,I] +exposedField SFBool Repeat FALSE +exposedField SFURL FacadePrimitive "" +exposedField SFInt32 NbStories 0 #%b=[0,65535] +exposedField MFInt32 NbFacadeCellsByStorey 0 +exposedField MFFloat StoreyHeight 1.0 #%b=[0,I] +exposedField MFGeometryNode FacadeCellsArray [] +]{} + + +PROTO Shadow [#%NDT=SFWorldNode,SF3DNode,SFGeometryNode %COD=N +eventIn SF3DNode addChildren +eventIn SF3DNode removeChildren +exposedField MF3DNode children [] +exposedField SFBool enabled TRUE +exposedField SFBool cast TRUE +exposedField SFBool receive TRUE +exposedField SFFloat penumbra 0 #%b=[0,I] +]{} diff --git a/applications/m3u82mpd/main.c b/applications/m3u82mpd/main.c index e3732e2..114c4d4 100644 --- a/applications/m3u82mpd/main.c +++ b/applications/m3u82mpd/main.c @@ -1,116 +1,116 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) Telecom ParisTech 2010 - - * All rights reserved - * - * This file is part of GPAC / m3u82mpd application - * - * GPAC is gf_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 "../modules/mpd_in/m3u8.h" -#include -#include - -int main(int argc, char **argv) -{ - GF_Err e; - VariantPlaylist * pl = NULL; - char *url = argv[1]; - char *cache_m3u8_file; - u32 i, count; - FILE *fmpd; - Bool verbose = 0; - u32 update_interval = 0; - char *m3u8_local_name = "file.m3u8"; - Bool is_local = 0; - - gf_sys_init(0); - - gf_log_set_level(verbose ? GF_LOG_DEBUG : GF_LOG_INFO); - gf_log_set_tools(GF_LOG_NETWORK); - - while (1) { - - if (gf_url_is_local(url)) { - m3u8_local_name = url; - is_local = 1; - } else { - e = gf_dm_wget(url, m3u8_local_name); - if (e != GF_OK) return -1; - } - - e = parse_root_playlist(m3u8_local_name, &pl, "."); - if (e != GF_OK) return -1; - - fmpd = fopen(argv[2], "wt"); - - fprintf(fmpd, "\n"); - fprintf(fmpd, " \n"); - fprintf(fmpd, " Media Presentation Description for file %s\n", url); - fprintf(fmpd, " Generated by GPAC %s\n", GPAC_FULL_VERSION); - - fprintf(fmpd, " \n"); - fprintf(fmpd, " \n"); - - count = gf_list_count(pl->programs); - for (i=0; iprograms, i); - count2 = gf_list_count(prog->bitrates); - for (j = 0; jbitrates, j); - fprintf(stdout, "%d, %d, %s, %s, %d\n", pe->durationInfo, pe->bandwidth, pe->title, pe->url, pe->elementType); - if (pe->elementType == TYPE_PLAYLIST) { - u32 k, count3; - char *tmp; - char c; - char baseURL[GF_MAX_PATH]; - tmp = strrchr(url, '/'); - tmp++; - c = tmp[0]; - tmp[0] = 0; - strcpy(baseURL, url); - tmp[0] = c; - fprintf(fmpd, " \n"); - fprintf(fmpd, " \n", pe->durationInfo, baseURL); - count3 = gf_list_count(pe->element.playlist.elements); - update_interval = (count3 - 1) * pe->durationInfo * 1000; - for (k=0; kelement.playlist.elements, k); - if (k) fprintf(fmpd, " \n", elt->url); - else fprintf(fmpd, " \n", elt->url); - } - fprintf(fmpd, " \n"); - fprintf(fmpd, " \n"); - } else if (pe->elementType == TYPE_STREAM) { - fprintf(stdout, "Stream\n"); - } - } - } - fprintf(fmpd, " \n"); - fprintf(fmpd, ""); - fclose(fmpd); - variant_playlist_del(pl); - if (is_local) break; - gf_sleep(update_interval); - - } - - gf_sys_close(); - return 0; -} +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Telecom ParisTech 2010 - + * All rights reserved + * + * This file is part of GPAC / m3u82mpd application + * + * GPAC is gf_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 "../modules/mpd_in/m3u8.h" +#include +#include + +int main(int argc, char **argv) +{ + GF_Err e; + VariantPlaylist * pl = NULL; + char *url = argv[1]; + char *cache_m3u8_file; + u32 i, count; + FILE *fmpd; + Bool verbose = 0; + u32 update_interval = 0; + char *m3u8_local_name = "file.m3u8"; + Bool is_local = 0; + + gf_sys_init(0); + + gf_log_set_level(verbose ? GF_LOG_DEBUG : GF_LOG_INFO); + gf_log_set_tools(GF_LOG_NETWORK); + + while (1) { + + if (gf_url_is_local(url)) { + m3u8_local_name = url; + is_local = 1; + } else { + e = gf_dm_wget(url, m3u8_local_name); + if (e != GF_OK) return -1; + } + + e = parse_root_playlist(m3u8_local_name, &pl, "."); + if (e != GF_OK) return -1; + + fmpd = fopen(argv[2], "wt"); + + fprintf(fmpd, "\n"); + fprintf(fmpd, " \n"); + fprintf(fmpd, " Media Presentation Description for file %s\n", url); + fprintf(fmpd, " Generated by GPAC %s\n", GPAC_FULL_VERSION); + + fprintf(fmpd, " \n"); + fprintf(fmpd, " \n"); + + count = gf_list_count(pl->programs); + for (i=0; iprograms, i); + count2 = gf_list_count(prog->bitrates); + for (j = 0; jbitrates, j); + fprintf(stdout, "%d, %d, %s, %s, %d\n", pe->durationInfo, pe->bandwidth, pe->title, pe->url, pe->elementType); + if (pe->elementType == TYPE_PLAYLIST) { + u32 k, count3; + char *tmp; + char c; + char baseURL[GF_MAX_PATH]; + tmp = strrchr(url, '/'); + tmp++; + c = tmp[0]; + tmp[0] = 0; + strcpy(baseURL, url); + tmp[0] = c; + fprintf(fmpd, " \n"); + fprintf(fmpd, " \n", pe->durationInfo, baseURL); + count3 = gf_list_count(pe->element.playlist.elements); + update_interval = (count3 - 1) * pe->durationInfo * 1000; + for (k=0; kelement.playlist.elements, k); + if (k) fprintf(fmpd, " \n", elt->url); + else fprintf(fmpd, " \n", elt->url); + } + fprintf(fmpd, " \n"); + fprintf(fmpd, " \n"); + } else if (pe->elementType == TYPE_STREAM) { + fprintf(stdout, "Stream\n"); + } + } + } + fprintf(fmpd, " \n"); + fprintf(fmpd, ""); + fclose(fmpd); + variant_playlist_del(pl); + if (is_local) break; + gf_sleep(update_interval); + + } + + gf_sys_close(); + return 0; +} diff --git a/applications/mp42avi/main.c b/applications/mp42avi/main.c index de19cc4..ad7def4 100644 --- a/applications/mp42avi/main.c +++ b/applications/mp42avi/main.c @@ -233,58 +233,6 @@ void dump_frame(BIFSVID b2v, char *conv_buf, char *out_path, u32 dump_type, avi_ gf_sc_release_screen_buffer(b2v.sr, &fb); } - - -GF_Config *loadconfigfile() -{ - GF_Config *cfg; - char *cfg_dir; - char szPath[GF_MAX_PATH]; - -#ifdef WIN32 - GetModuleFileNameA(NULL, szPath, GF_MAX_PATH); - cfg_dir = strrchr(szPath, '\\'); - if (cfg_dir) cfg_dir[1] = 0; - - cfg = gf_cfg_new(szPath, "GPAC.cfg"); - if (cfg) goto success; - -#ifdef _DEBUG - strcpy(szPath, "C:\\Users\\Cyril\\sourceforge\\gpac\\bin\\w32_deb\\"); -#else - strcpy(szPath, "C:\\Users\\Cyril\\sourceforge\\gpac\\bin\\w32_rel\\"); -#endif - cfg = gf_cfg_new(szPath, "GPAC.cfg"); - if (cfg) goto success; - strcpy(szPath, "."); - cfg = gf_cfg_new(szPath, "GPAC.cfg"); - if (cfg) goto success; - strcpy(szPath, "C:\\Program Files\\GPAC"); - cfg = gf_cfg_new(szPath, "GPAC.cfg"); - if (cfg) goto success; - strcpy(szPath, "."); - cfg = gf_cfg_new(szPath, "GPAC.cfg"); -#else - /*linux*/ - cfg_dir = getenv("HOME"); - if (cfg_dir) { - strcpy(szPath, cfg_dir); - } else { - fprintf(stdout, "WARNING: HOME env var not set - using current directory for config file\n"); - strcpy(szPath, "."); - } - cfg = gf_cfg_new(szPath, ".gpacrc"); - if (cfg) goto success; -#endif - if (!cfg) { - fprintf(stdout, "cannot create config file in %s directory\n", szPath); - return NULL; - } - success: - fprintf(stdout, "Using config file in %s directory\n", szPath); - return cfg; -} - /*generates an intertwined bmp from a scene file with 5 different viewpoints*/ void bifs3d_viewpoints_merger(GF_ISOFile *file, char *szConfigFile, u32 width, u32 height, char *rad_name, u32 dump_type, char *out_dir, Double fps, s32 frameID, s32 dump_time) { @@ -305,20 +253,11 @@ void bifs3d_viewpoints_merger(GF_ISOFile *file, char *szConfigFile, u32 width, u const char *test; char config_path[GF_MAX_PATH]; memset(&user, 0, sizeof(GF_User)); - if (szConfigFile && strlen(szConfigFile)) { - user.config = gf_cfg_new(config_path, GPAC_CFG_FILE); - } else { - user.config = loadconfigfile(); - } + user.config = gf_cfg_init(szConfigFile, NULL); if (!user.config) { - fprintf(stdout, "Configuration File \"GPAC.cfg\" not found\nPlease enter full path to config file:\n"); - scanf("%s", config_path); - user.config = gf_cfg_new(config_path, GPAC_CFG_FILE); - if (!user.config) { - fprintf(stdout, "Error: Configuration File \"%s\" not found in %s\n", GPAC_CFG_FILE, config_path); - return; - } + fprintf(stdout, "Error: Configuration File \"%s\" not found in %s\n", GPAC_CFG_FILE, config_path); + return; } test = gf_cfg_get_key(user.config, "General", "ModulesDirectory"); @@ -528,19 +467,14 @@ void bifs_to_vid(GF_ISOFile *file, char *szConfigFile, u32 width, u32 height, ch memset(&user, 0, sizeof(GF_User)); if (szConfigFile && strlen(szConfigFile)) { - user.config = gf_cfg_new(config_path, GPAC_CFG_FILE); + user.config = gf_cfg_init(config_path, NULL); } else { - user.config = loadconfigfile(); + user.config = gf_cfg_init(NULL, NULL); } if (!user.config) { - fprintf(stdout, "Configuration File \"GPAC.cfg\" not found\nPlease enter full path to config file:\n"); - scanf("%s", config_path); - user.config = gf_cfg_new(config_path, GPAC_CFG_FILE); - if (!user.config) { - fprintf(stdout, "Error: Configuration File \"%s\" not found in %s\n", GPAC_CFG_FILE, config_path); - return; - } + fprintf(stdout, "Error: Configuration File \"%s\" not found in %s\n", GPAC_CFG_FILE, config_path); + return; } avi_out = NULL; conv_buf = NULL; diff --git a/applications/mp42ts/main.c b/applications/mp42ts/main.c index 5a6c12d..4f9261a 100644 --- a/applications/mp42ts/main.c +++ b/applications/mp42ts/main.c @@ -29,7 +29,8 @@ #include #include -#define TDMB_PSI_REFRESH_RATE 500 /*repeat PAT/PMT every TDMB_PSI_REFRESH_RATE ms*/ + +#define DEFAULT_PCR_OFFSET 18000 #define UDP_BUFFER_SIZE 0x40000 @@ -40,16 +41,23 @@ static GFINLINE void usage(const char * progname) { fprintf(stderr, "USAGE: %s -rate=R [[-prog=prog1]..[-prog=progn]] [-audio=url] [-video=url] [-mpeg4-carousel=n] [-mpeg4] [-time=n] [-src=file] DST [[DST]]\n" "\n" +#ifdef GPAC_MEMORY_TRACKING + "\t-mem-track: enables memory tracker\n" +#endif "\t-rate=R specifies target rate in kbps of the multiplex (mandatory)\n" - /* "\t If not set transport stream will be of variable bitrate\n" */ + "\t-real-time specifies the muxer will work in real-time mode\n" + "\t * automatically set for SDP or BT input\n" + "\t-pcr-init=V sets initial value V for PCR - if not set, random value is used\n" + "\t-pcr-offset=V offsets all timestamps from PCR by V, in 90kHz. Default value: %d\n" + "\t-psi-rate=V sets PSI refresh rate V in ms (default 100ms). If 0, PSI data is only send once at the begining\n" + "\t-time=n request the program to stop after n ms\n" + "\t-single-au forces 1 PES = 1 AU (disabled by default)\n" + "\t-prog=filename specifies an input file used for a TS service\n" "\t * currently only supports ISO files and SDP files\n" "\t * can be used several times, once for each program\n" "\t-audio=url may be mp3/udp or aac/http (shoutcast/icecast)\n" - "\t-video=url shall be raw h264\n" - "\t-mpeg4-carousel=n carousel period in ms\n" - "\t-mpeg4 forces usage of MPEG-4 signaling (IOD and SL Config)\n" - "\t-time=n request the program to stop after n ms\n" + "\t-video=url shall be a raw h264 frame\n" "\t-src=filename update file: must be either an .sdp or a .bt file\n\n" "\tDST : Destinations, at least one is mandatory\n" "\t -dst-udp UDP_address:port (multicast or unicast)\n" @@ -60,7 +68,18 @@ static GFINLINE void usage(const char * progname) "\t -segment-manifest=file m3u8 file basename\n" "\t -segment-http-prefix=p client address for accessing server segments\n" "\t -segment-number=n only n segments are used using a cyclic pattern\n" - "\n", progname + "\t\n" + "\tMPEG-4 options\n" + "\t-mpeg4-carousel=n carousel period in ms\n" + "\t-mpeg4 or -4on2 forces usage of MPEG-4 signaling (IOD and SL Config)\n" + "\t-4over2 same as -4on2 and uses PMT to carry OD Updates\n" + "\t-bifs-pes carries BIFS over PES instead of sections\n" + "\t-bifs-pes-ex carries BIFS over PES without writing timestamps in SL\n" + "\t\n" + "\t-ll=LogLevel specifies log level to use (by default error)\n" + "\t-lt=LogTools specifies log tools to use (by default all)\n" + "\t-h or -help Print this screen\n" + "\n", progname, DEFAULT_PCR_OFFSET ); } @@ -79,6 +98,10 @@ typedef struct Bool repeat; u32 mpeg4_signaling; Bool audio_configured; + u64 samples_done, samples_count; + u32 nb_real_streams; + Bool real_time; + GF_List *od_updates; } M2TSProgram; typedef struct @@ -93,7 +116,10 @@ typedef struct u32 nalu_size; void *dsi_and_rap; Bool loop; + Bool is_repeat; u64 ts_offset; + M2TSProgram *prog; + char nalu_delim[6]; } GF_ESIMP4; typedef struct @@ -146,6 +172,7 @@ static GF_Err mp4_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param) pck.flags = GF_ESI_DATA_AU_START | GF_ESI_DATA_HAS_CTS; if (priv->sample->IsRAP) pck.flags |= GF_ESI_DATA_AU_RAP; pck.cts = priv->sample->DTS + priv->ts_offset; + if (priv->is_repeat) pck.flags |= GF_ESI_DATA_REPEAT; if (priv->nb_repeat_last) { pck.cts += priv->nb_repeat_last*ifce->timescale * priv->image_repeat_ms / 1000; @@ -157,19 +184,24 @@ static GF_Err mp4_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param) pck.flags |= GF_ESI_DATA_HAS_DTS; } - if (priv->sample->IsRAP && priv->dsi) { + if (priv->sample->IsRAP && priv->dsi && priv->dsi_size) { pck.data = priv->dsi; pck.data_len = priv->dsi_size; ifce->output_ctrl(ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &pck); pck.flags = 0; } + + if (priv->nalu_size) { + Bool nalu_delim_sent = 0; u32 remain = priv->sample->dataLength; char *ptr = priv->sample->data; u32 v, size; - char sc[4]; - sc[0] = sc[1] = sc[2] = 0; sc[3] = 1; + char sc[10]; + + /*send nalus*/ + sc[0] = sc[1] = sc[2] = 0; sc[3] = 1; while (remain) { size = 0; v = priv->nalu_size; @@ -182,12 +214,25 @@ static GF_Err mp4_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param) } remain -= size; + if (!nalu_delim_sent) { + nalu_delim_sent = 1; + /*send a NALU delim: copy over NAL ref idc*/ + sc[4] = (ptr[0] & 0x60) | GF_AVC_NALU_ACCESS_UNIT; + sc[5] = 0xF0 /*7 "all supported NALUs" (=111) + rbsp trailing (10000)*/; + + pck.data = sc; + pck.data_len = 6; + ifce->output_ctrl(ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &pck); + pck.flags &= ~GF_ESI_DATA_AU_START; + } + + pck.data = sc; pck.data_len = 4; ifce->output_ctrl(ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &pck); - pck.flags &= ~GF_ESI_DATA_AU_START; if (!remain) pck.flags |= GF_ESI_DATA_AU_END; + pck.flags &= ~GF_ESI_DATA_AU_START; pck.data = ptr; pck.data_len = size; @@ -204,6 +249,12 @@ static GF_Err mp4_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param) gf_isom_sample_del(&priv->sample); priv->sample_number++; + + if (!priv->prog->real_time && !priv->is_repeat) { + priv->prog->samples_done++; + gf_set_progress("Converting to MPEG-2 TS", priv->prog->samples_done, priv->prog->samples_count); + } + if (priv->sample_number==priv->sample_count) { if (priv->loop) { Double scale; @@ -214,12 +265,20 @@ static GF_Err mp4_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param) duration = (u64) (gf_isom_get_duration(priv->mp4) * scale); priv->ts_offset += duration; priv->sample_number = 0; + priv->is_repeat = (priv->sample_count==1) ? 1 : 0; } - else if (priv->image_repeat_ms) { + else if (priv->image_repeat_ms && priv->prog->nb_real_streams) { priv->nb_repeat_last++; priv->sample_number--; + priv->is_repeat = 1; } else { - ifce->caps |= GF_ESI_STREAM_IS_OVER; + if (!(ifce->caps & GF_ESI_STREAM_IS_OVER)) { + ifce->caps |= GF_ESI_STREAM_IS_OVER; + if (priv->sample_count>1) { + assert(priv->prog->nb_real_streams); + priv->prog->nb_real_streams--; + } + } } } } @@ -239,7 +298,7 @@ static GF_Err mp4_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param) } } -static void fill_isom_es_ifce(GF_ESInterface *ifce, GF_ISOFile *mp4, u32 track_num) +static void fill_isom_es_ifce(M2TSProgram *prog, GF_ESInterface *ifce, GF_ISOFile *mp4, u32 track_num, u32 bifs_use_pes) { GF_ESIMP4 *priv; char _lan[4]; @@ -250,9 +309,13 @@ static void fill_isom_es_ifce(GF_ESInterface *ifce, GF_ISOFile *mp4, u32 track_n priv->mp4 = mp4; priv->track = track_num; - priv->loop = 1; + priv->loop = prog->real_time ? 1 : 0; priv->sample_count = gf_isom_get_sample_count(mp4, track_num); + prog->samples_count += priv->sample_count; + if (priv->sample_count>1) + prog->nb_real_streams++; + priv->prog = prog; memset(ifce, 0, sizeof(GF_ESInterface)); ifce->stream_id = gf_isom_get_track_id(mp4, track_num); dcd = gf_isom_get_decoder_config(mp4, track_num, 1); @@ -292,6 +355,9 @@ static void fill_isom_es_ifce(GF_ESInterface *ifce, GF_ISOFile *mp4, u32 track_n gf_bs_get_content(bs, (char **) &priv->dsi, &priv->dsi_size); gf_bs_del(bs); #endif + priv->nalu_delim[3] = 1; + priv->nalu_delim[4] = 0; /*this will be nal header*/ + priv->nalu_delim[5] = 0xF0 /*7 "all supported NALUs" (=111) + rbsp trailing (10000)*/; } break; } @@ -313,6 +379,24 @@ static void fill_isom_es_ifce(GF_ESInterface *ifce, GF_ISOFile *mp4, u32 track_n ifce->duration = (Double) (s64) gf_isom_get_media_duration(mp4, track_num); ifce->duration /= ifce->timescale; + GF_SAFEALLOC(ifce->sl_config, GF_SLConfig); + ifce->sl_config->tag = GF_ODF_SLC_TAG; +// ifce->sl_config->predefined = 3; + ifce->sl_config->useAccessUnitStartFlag = 1; + ifce->sl_config->useAccessUnitEndFlag = 1; + ifce->sl_config->useRandomAccessPointFlag = 1; + ifce->sl_config->useTimestampsFlag = 1; + ifce->sl_config->timestampLength = 33; + ifce->sl_config->timestampResolution = ifce->timescale; + + /*test mode in which time stamps are 90khz and not coded but copied over from PES header*/ + if (bifs_use_pes==2) { + ifce->sl_config->timestampLength = 0; + ifce->sl_config->timestampResolution = 90000; + } + + gf_isom_set_extraction_slc(mp4, track_num, 1, ifce->sl_config); + ifce->input_ctrl = mp4_input_ctrl; if (priv != ifce->input_udta){ if (ifce->input_udta) @@ -476,7 +560,8 @@ static void SampleCallBack(void *calling_object, u16 ESID, char *data, u32 size, prog->streams[i].timescale = esd->slConfig->timestampResolution; e = gf_m2ts_program_stream_update_ts_scale(&prog->streams[i], esd->slConfig->timestampResolution); assert(!e); - gf_m2ts_program_stream_update_sl_config(&prog->streams[i], esd->slConfig); + if (!prog->streams[i].sl_config) prog->streams[i].sl_config = (GF_SLConfig *)gf_odf_desc_new(GF_ODF_SLC_TAG); + memcpy(prog->streams[i].sl_config, esd->slConfig, sizeof(GF_SLConfig)); break; } } @@ -952,69 +1037,157 @@ void fill_seng_es_ifce(GF_ESInterface *ifce, u32 i, GF_SceneEngine *seng, u32 pe } -static Bool open_program(M2TSProgram *prog, char *src, u32 carousel_rate, Bool force_mpeg4, char *update, char *audio_input_ip, u16 audio_input_port, char *video_buffer) +static Bool open_program(M2TSProgram *prog, char *src, u32 carousel_rate, u32 mpeg4_signaling, char *update, char *audio_input_ip, u16 audio_input_port, char *video_buffer, Bool force_real_time, u32 bifs_use_pes) { GF_SDPInfo *sdp; u32 i; GF_Err e; memset(prog, 0, sizeof(M2TSProgram)); - prog->mpeg4_signaling = force_mpeg4 ? GF_M2TS_MPEG4_SIGNALING_FULL : GF_M2TS_MPEG4_SIGNALING_NONE; + prog->mpeg4_signaling = mpeg4_signaling; /*open ISO file*/ if (gf_isom_probe_file(src)) { u32 nb_tracks; + Bool has_bifs_od = 0; u32 first_audio = 0; + u32 first_other = 0; prog->mp4 = gf_isom_open(src, GF_ISOM_OPEN_READ, 0); prog->nb_streams = 0; + prog->real_time = force_real_time; /*on MPEG-2 TS, carry 3GPP timed text as MPEG-4 Part17*/ gf_isom_text_set_streaming_mode(prog->mp4, 1); nb_tracks = gf_isom_get_track_count(prog->mp4); + for (i=0; imp4, i+1) == GF_ISOM_MEDIA_HINT) continue; - fill_isom_es_ifce(&prog->streams[i], prog->mp4, i+1); + + fill_isom_es_ifce(prog, &prog->streams[i], prog->mp4, i+1, bifs_use_pes); + switch(prog->streams[i].stream_type) { - case GF_STREAM_OD: - case GF_STREAM_SCENE: - prog->mpeg4_signaling = GF_M2TS_MPEG4_SIGNALING_FULL; - prog->streams[i].repeat_rate = carousel_rate; - break; - case GF_STREAM_VISUAL: - /*turn on image repeat*/ - switch (prog->streams[i].object_type_indication) { - case GPAC_OTI_IMAGE_JPEG: - case GPAC_OTI_IMAGE_PNG: - ((GF_ESIMP4 *)prog->streams[i].input_udta)->image_repeat_ms = carousel_rate; - break; - } + case GF_STREAM_OD: + has_bifs_od = 1; + prog->streams[i].repeat_rate = carousel_rate; + break; + case GF_STREAM_SCENE: + has_bifs_od = 1; + prog->streams[i].repeat_rate = carousel_rate; + break; + case GF_STREAM_VISUAL: + /*turn on image repeat*/ + switch (prog->streams[i].object_type_indication) { + case GPAC_OTI_IMAGE_JPEG: + case GPAC_OTI_IMAGE_PNG: + ((GF_ESIMP4 *)prog->streams[i].input_udta)->image_repeat_ms = carousel_rate; break; default: - /*log not supported stream type: %s*/ + check_deps = 1; + if (gf_isom_get_sample_count(prog->mp4, i+1)>1) { + /*get first visual stream as PCR*/ + if (!prog->pcr_idx) prog->pcr_idx = i+1; + } break; + } + break; + case GF_STREAM_AUDIO: + if (!first_audio) first_audio = i+1; + check_deps = 1; + break; + default: + /*log not supported stream type: %s*/ + break; } prog->nb_streams++; - /*get first visual stream as PCR*/ - if (!prog->pcr_idx && - (gf_isom_get_media_type(prog->mp4, i+1) == GF_ISOM_MEDIA_VISUAL) && - (gf_isom_get_sample_count(prog->mp4, i+1)>1) ) { - prog->pcr_idx = i+1; - } - if (!first_audio && (gf_isom_get_media_type(prog->mp4, i+1) == GF_ISOM_MEDIA_AUDIO) ) { - first_audio = i+1; + if (gf_isom_get_sample_count(prog->mp4, i+1)>1) first_other = i+1; + + if (check_deps) { + u32 k; + Bool found_dep = 0; + for (k=0; kmp4, k+1) != GF_ISOM_MEDIA_OD) + continue; + + /*this stream is not refered to by any OD, send as regular PES*/ + if (gf_isom_has_track_reference(prog->mp4, k+1, GF_ISOM_REF_OD, gf_isom_get_track_id(prog->mp4, i+1) )==1) { + found_dep = 1; + break; + } + } + if (!found_dep) { + prog->streams[i].caps |= GF_ESI_STREAM_WITHOUT_MPEG4_SYSTEMS; + } } } + if (has_bifs_od && !prog->mpeg4_signaling) prog->mpeg4_signaling = GF_M2TS_MPEG4_SIGNALING_FULL; + /*if no visual PCR found, use first audio*/ if (!prog->pcr_idx) prog->pcr_idx = first_audio; + if (!prog->pcr_idx) prog->pcr_idx = first_other; if (prog->pcr_idx) { GF_ESIMP4 *priv; prog->pcr_idx-=1; priv = prog->streams[prog->pcr_idx].input_udta; gf_isom_set_default_sync_track(prog->mp4, priv->track); } + prog->iod = gf_isom_get_root_od(prog->mp4); - if (!prog->iod) - fprintf(stderr, "NULL IOD for program !\n"); + if (prog->iod) { + GF_ObjectDescriptor*iod = (GF_ObjectDescriptor*)prog->iod; + if (gf_list_count( ((GF_ObjectDescriptor*)prog->iod)->ESDescriptors) == 0) { + gf_odf_desc_del(prog->iod); + prog->iod = NULL; + } else { + fprintf(stderr, "IOD found for program %s\n", src); + + /*if using 4over2, get rid of OD tracks*/ + if (prog->mpeg4_signaling==GF_M2TS_MPEG4_SIGNALING_SCENE) { + for (i=0; iESDescriptors); i++) { + u32 track_num, k; + GF_M2TSDescriptor *oddesc; + GF_ISOSample *sample; + GF_ESD *esd = gf_list_get(iod->ESDescriptors, i); + if (esd->decoderConfig->streamType!=GF_STREAM_OD) continue; + track_num = gf_isom_get_track_by_id(prog->mp4, esd->ESID); + if (gf_isom_get_sample_count(prog->mp4, track_num)>1) continue; + + sample = gf_isom_get_sample(prog->mp4, track_num, 1, NULL); + if (sample->dataLength >= 255-2) { + gf_isom_sample_del(&sample); + continue; + } + /*rewrite ESD dependencies*/ + for (k=0; kESDescriptors); k++) { + GF_ESD *dep_esd = gf_list_get(iod->ESDescriptors, k); + if (dep_esd->dependsOnESID==esd->ESID) dep_esd->dependsOnESID = esd->dependsOnESID; + } + + for (k=0; knb_streams; k++) { + if (prog->streams[k].stream_id==esd->ESID) { + prog->streams[k].stream_type = 0; + break; + } + } + + if (!prog->od_updates) prog->od_updates = gf_list_new(); + GF_SAFEALLOC(oddesc, GF_M2TSDescriptor); + oddesc->data_len = sample->dataLength; + oddesc->data = sample->data; + oddesc->tag = GF_M2TS_MPEG4_ODUPDATE_DESCRIPTOR; + sample->data = NULL; + gf_isom_sample_del(&sample); + gf_list_add(prog->od_updates, oddesc); + + gf_list_rem(iod->ESDescriptors, i); + i--; + gf_odf_desc_del((GF_Descriptor *) esd); + prog->samples_count--; + } + } + + } + } return 1; } @@ -1136,7 +1309,7 @@ static Bool open_program(M2TSProgram *prog, char *src, u32 carousel_rate, Bool f ((GF_ESIStream*)prog->streams[prog->nb_streams].input_udta)->vers_inc = 1; /*increment version number at every audio update*/ assert( prog ); //assert( prog->iod); - if (prog->iod && ((prog->iod->tag!=GF_ODF_IOD_TAG) || ((GF_InitialObjectDescriptor*)prog->iod)->OD_profileAndLevel!=GPAC_MAGIC_OD_PROFILE_FOR_MPEG4_SIGNALING)) { + if (prog->iod && ((prog->iod->tag!=GF_ODF_IOD_TAG) || (mpeg4_signaling != GF_M2TS_MPEG4_SIGNALING_SCENE))) { /*create the descriptor*/ GF_ESD *esd; GF_SimpleDataDescriptor *audio_desc; @@ -1188,7 +1361,7 @@ static Bool open_program(M2TSProgram *prog, char *src, u32 carousel_rate, Bool f ((GF_ESIStream*)prog->streams[prog->nb_streams].input_udta)->vers_inc = 1; /*increment version number at every video update*/ assert(prog); - if (prog->iod && ((prog->iod->tag!=GF_ODF_IOD_TAG) || ((GF_InitialObjectDescriptor*)prog->iod)->OD_profileAndLevel!=GPAC_MAGIC_OD_PROFILE_FOR_MPEG4_SIGNALING)) { + if (prog->iod && ((prog->iod->tag!=GF_ODF_IOD_TAG) || (mpeg4_signaling != GF_M2TS_MPEG4_SIGNALING_SCENE))) { assert(0); /*TODO*/ #if 0 /*create the descriptor*/ @@ -1228,29 +1401,46 @@ static Bool open_program(M2TSProgram *prog, char *src, u32 carousel_rate, Bool f gf_th_run(prog->th, seng_output, prog); return 1; } else { - fprintf(stderr, "Error opening %s - not a supported input media, skipping.\n", src); + FILE *f = fopen(src, "rt"); + if (f) { + fclose(f); + fprintf(stderr, "Error opening %s - not a supported input media, skipping.\n", src); + } else { + fprintf(stderr, "Error opening %s - no such file.\n", src); + } return 0; } } /*parse MP42TS arguments*/ -static GFINLINE GF_Err parse_args(int argc, char **argv, u32 *mux_rate, u32 *carrousel_rate, +static GFINLINE GF_Err parse_args(int argc, char **argv, u32 *mux_rate, u32 *carrousel_rate, u64 *pcr_init_val, u32 *pcr_offset, u32 *psi_refresh_rate, Bool *single_au_pes, u32 *bifs_use_pes, M2TSProgram *progs, u32 *nb_progs, char **src_name, Bool *real_time, u32 *run_time, char **video_buffer, u32 *video_buffer_size, u32 *audio_input_type, char **audio_input_ip, u16 *audio_input_port, u32 *output_type, char **ts_out, char **udp_out, char **rtp_out, u16 *output_port, char** segment_dir, u32 *segment_duration, char **segment_manifest, u32 *segment_number, char **segment_http_prefix) { - Bool rate_found=0, mpeg4_carousel_found=0, prog_found=0, mpeg4_found=0, time_found=0, src_found=0, dst_found=0, audio_input_found=0, video_input_found=0, + Bool rate_found=0, mpeg4_carousel_found=0, time_found=0, src_found=0, dst_found=0, audio_input_found=0, video_input_found=0, seg_dur_found=0, seg_dir_found=0, seg_manifest_found=0, seg_number_found=0, seg_http_found = 0, real_time_found=0; char *prog_name, *arg = NULL, *error_msg = "no argument found"; - Bool mpeg4_signaling = 0; + u32 mpeg4_signaling = GF_M2TS_MPEG4_SIGNALING_NONE; + Bool force_real_time = 0; s32 i; - /*first pass: find audio*/ + /*first pass: find audio - NO GPAC INIT MODIFICATION MUST OCCUR IN THIS PASS*/ for (i=1; iiod = progs[i].iod; + if (progs[i].od_updates) { + program->loop_descriptors = progs[i].od_updates; + progs[i].od_updates = NULL; + } for (j=0; javg_br); } + /*cpu load regulation*/ + gf_sleep(1); } - /*cpu load regulation*/ - gf_sleep(1); if (run_time) { if (gf_m2ts_get_ts_clock(muxer) > run_time) { @@ -1914,6 +2135,11 @@ int main(int argc, char **argv) } } + { + u64 bits = muxer->tot_pck_sent*8*188; + u32 dur_sec = gf_m2ts_get_ts_clock(muxer) / 1000; + fprintf(stdout, "Done muxing - %d sec - average rate %d kbps "LLD" packets written ("LLD" padding)\n", dur_sec, (u32) (bits/dur_sec/1000), muxer->tot_pck_sent, muxer->tot_pad_sent); + } exit: run = 0; @@ -1938,8 +2164,12 @@ exit: if (progs[i].streams[j].input_udta){ gf_free(progs[i].streams[j].input_udta); } - if (progs[i].streams[j].decoder_config) + if (progs[i].streams[j].decoder_config) { gf_free(progs[i].streams[j].decoder_config); + } + if (progs[i].streams[j].sl_config) { + gf_free(progs[i].streams[j].sl_config); + } } if (progs[i].iod) gf_odf_desc_del((GF_Descriptor*)progs[i].iod); if (progs[i].mp4) gf_isom_close(progs[i].mp4); diff --git a/applications/mp4box/filedump.c b/applications/mp4box/filedump.c index 0c09810..2d39a3d 100644 --- a/applications/mp4box/filedump.c +++ b/applications/mp4box/filedump.c @@ -807,7 +807,7 @@ void dump_file_ts(GF_ISOFile *file, char *inName) for (i=0; iDTS; cts = dts + (s32) samp->CTS_Offset; - fprintf(dump, "Sample %d - DTS "LLD" - CTS "LLD"", j+1, LLD_CAST dts, LLD_CAST cts); - if (samp->IsRAP) fprintf(dump, " - RAP"); + fprintf(dump, "Sample %d\tDTS "LLD"\tCTS "LLD"\t%d\t%d", j+1, LLD_CAST dts, LLD_CAST cts, samp->dataLength, samp->IsRAP); if (ctsdecoderConfig->streamType==GF_STREAM_VISUAL) { u32 w, h; + u16 rvc_predef; w = h = 0; if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) { #ifndef GPAC_DISABLE_AV_PARSERS @@ -1230,6 +1230,10 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) if (full_dump) fprintf(stdout, "\t"); fprintf(stdout, "Visual Size %d x %d\n", w, h); } + if (gf_isom_get_rvc_config(file, trackNum, 1, &rvc_predef, NULL, NULL, NULL)==GF_OK) { + fprintf(stdout, "Has RVC signaled - Predefined configuration %d\n", rvc_predef); + } + } else if (esd->decoderConfig->streamType==GF_STREAM_AUDIO) { #ifndef GPAC_DISABLE_AV_PARSERS GF_M4ADecSpecInfo a_cfg; @@ -1889,7 +1893,7 @@ static void m2ts_sidx_add_entry(GF_SegmentIndexBox *sidx, Bool type, ref = &(sidx->refs[sidx->nb_refs-1]); ref->reference_type = type; ref->contains_RAP = has_rap; - ref->reference_offset = size; + ref->reference_size = size; ref->subsegment_duration = duration; ref->RAP_delta_time = (has_rap ? RAP_delta_time: 0); } @@ -1907,9 +1911,9 @@ static void m2ts_sidx_finalize_size(GF_M2TS_IndexingInfo *index_info, u64 file_s GF_SIDXReference *ref; if (index_info->sidx->nb_refs == 0) return; ref = &(index_info->sidx->refs[index_info->sidx->nb_refs-1]); - ref->reference_offset = (u32)(file_size - index_info->prev_base_offset); + ref->reference_size = (u32)(file_size - index_info->prev_base_offset); fprintf(stderr, "Subsegment: position-range ajdustment:%d-%d (%d bytes)\n", - index_info->prev_base_offset, (u32)file_size, ref->reference_offset); + index_info->prev_base_offset, (u32)file_size, ref->reference_size); } static void m2ts_sidx_flush_entry(GF_M2TS_IndexingInfo *index_info) @@ -2393,8 +2397,8 @@ static void write_mpd_segment_info(GF_M2TS_IndexingInfo *index_info, char *media start=index_info->sidx->first_offset; for (i=0; isidx->nb_refs; i++) { GF_SIDXReference *ref = &index_info->sidx->refs[i]; - fprintf(index_info->mpd_file, " \n", start, start+ref->reference_offset-1); - start += ref->reference_offset; + fprintf(index_info->mpd_file, " \n", start, start+ref->reference_size-1); + start += ref->reference_size; } } else { fprintf(index_info->mpd_file, " \n", media_file_name); @@ -2427,7 +2431,7 @@ void dump_mpeg2_ts(char *mpeg2ts_file, char *pes_out_name, Bool prog_num, dumper.index_info.segment_duration = dash_duration; dumper.index_info.segment_at_rap = seg_at_rap; dumper.index_info.subsegs_per_segment = subseg_per_seg; - dumper.index_info.seg_name = gf_strdup(seg_name); + dumper.index_info.seg_name = seg_name ? gf_strdup(seg_name) : NULL; dumper.index_info.use_url_template = use_url_template; dumper.index_info.init_seg_name = NULL; dumper.index_info.use_index_segment = use_index_segment; diff --git a/applications/mp4box/fileimport.c b/applications/mp4box/fileimport.c index 6c5b81c..4c8f456 100644 --- a/applications/mp4box/fileimport.c +++ b/applications/mp4box/fileimport.c @@ -138,11 +138,12 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc s32 par_d, par_n, prog_id, delay; s32 tw, th, tx, ty; Bool do_audio, do_video, do_all, disable, track_layout, chap_ref, is_chap, keep_handler; - u32 group, handler; + u32 group, handler, rvc_predefined; const char *szLan; GF_Err e; GF_MediaImporter import; char *ext, szName[1000], *fmt, *handler_name, *rvc_config; + rvc_predefined = 0; memset(&import, 0, sizeof(GF_MediaImporter)); @@ -183,7 +184,7 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc if (!strnicmp(ext+1, "lang=", 5)) szLan = GetLanguageCode(ext+6); else if (!strnicmp(ext+1, "delay=", 6)) delay = atoi(ext+7); else if (!strnicmp(ext+1, "fps=", 4)) { - if (!strcmp(ext+5, "auto")) force_fps = 10000.0; + if (!strcmp(ext+5, "auto")) force_fps = GF_IMPORT_AUTO_FPS; else if (strchr(ext+5, '-')) { u32 ticks, dts_inc; sscanf(ext+5, "%u-%u", &ticks, &dts_inc); @@ -200,10 +201,11 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc else if (!stricmp(ext+1, "sbr")) import_flags |= GF_IMPORT_SBR_IMPLICIT; else if (!stricmp(ext+1, "sbrx")) import_flags |= GF_IMPORT_SBR_EXPLICIT; else if (!stricmp(ext+1, "ovsbr")) import_flags |= GF_IMPORT_OVSBR; - else if (!stricmp(ext+1, "svc")) import_flags |= GF_IMPORT_SVC_EXPLICIT; - else if (!stricmp(ext+1, "nosvc")) import_flags |= GF_IMPORT_SVC_NONE; else if (!stricmp(ext+1, "ps")) import_flags |= GF_IMPORT_PS_IMPLICIT; else if (!stricmp(ext+1, "psx")) import_flags |= GF_IMPORT_PS_EXPLICIT; + else if (!stricmp(ext+1, "svc")) import_flags |= GF_IMPORT_SVC_EXPLICIT; + else if (!stricmp(ext+1, "nosvc")) import_flags |= GF_IMPORT_SVC_NONE; + else if (!stricmp(ext+1, "subsamples")) import_flags |= GF_IMPORT_SET_SUBSAMPLES; else if (!stricmp(ext+1, "mpeg4")) import_flags |= GF_IMPORT_FORCE_MPEG4; else if (!strnicmp(ext+1, "agg=", 4)) frames_per_sample = atoi(ext+5); else if (!strnicmp(ext+1, "dur=", 4)) import.duration = (u32) (atof(ext+5) * 1000); @@ -218,7 +220,11 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc } } else if (!strnicmp(ext+1, "name=", 5)) handler_name = gf_strdup(ext+6); - else if (!strnicmp(ext+1, "rvc=", 4)) rvc_config = gf_strdup(ext+5); + else if (!strnicmp(ext+1, "rvc=", 4)) { + if (sscanf(ext+5, "%d", &rvc_predefined) != 1) { + rvc_config = gf_strdup(ext+5); + } + } else if (!strnicmp(ext+1, "font=", 5)) import.fontName = gf_strdup(ext+6); else if (!strnicmp(ext+1, "size=", 5)) import.fontSize = atoi(ext+6); else if (!strnicmp(ext+1, "fmt=", 4)) import.streamFormat = gf_strdup(ext+5); @@ -475,19 +481,22 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc if (f) { char *data; u32 size; + size_t read; gf_f64_seek(f, 0, SEEK_END); size = (u32) gf_f64_tell(f); gf_f64_seek(f, 0, SEEK_SET); data = gf_malloc(sizeof(char)*size); - fread(data, 1, size, f); + read = fread(data, 1, size, f); + assert(read); + assert(read == size); fclose(f); gf_gz_compress_payload(&data, size, &size); - e = gf_isom_set_meta_type(import.dest, 0, track, GF_4CC('r','v','c','z')); - gf_isom_modify_alternate_brand(import.dest, GF_ISOM_BRAND_ISO2, 1); - gf_isom_set_meta_xml_memory(import.dest, 0, track, data, size, 1); + gf_isom_set_rvc_config(import.dest, track, 1, 0, "application/rvc-config+xml+gz", data, size); gf_free(data); } + } else if (rvc_predefined>0) { + gf_isom_set_rvc_config(import.dest, track, 1, rvc_predefined, NULL, NULL, 0); } } if (track_id) fprintf(stdout, "WARNING: Track ID %d not found in file\n", track_id); @@ -518,14 +527,15 @@ typedef struct Bool can_duplicate; /*controls import by time rather than by sample (otherwise we would have to remove much more samples video vs audio for example*/ Bool first_sample_done; + Bool next_sample_is_rap; u32 stop_state; } TKInfo; -GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb, char *inName, Double InterleavingTime, Double chunk_start_time, const char *tmpdir, char *outfile) +GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb, char *inName, Double InterleavingTime, Double chunk_start_time, const char *tmpdir) { u32 i, count, nb_tk, needs_rap_sync, cur_file, conv_type, nb_tk_done, nb_samp, nb_done, di; Double max_dur, cur_file_time; - Bool do_add, all_duplicatable, size_exceeded, chunk_extraction; + Bool do_add, all_duplicatable, size_exceeded, chunk_extraction, rap_split; GF_ISOFile *dest; GF_ISOSample *samp; GF_Err e; @@ -535,6 +545,14 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb, chunk_extraction = (chunk_start>=0) ? 1 : 0; + rap_split = 0; + if (split_size_kb==(u32) -1) rap_split = 1; + if (split_dur==-1) rap_split = 1; + if (rap_split) { + split_size_kb = 0; + split_dur = (double) GF_MAX_FLOAT; + } + strcpy(szName, inName); ext = strrchr(szName, '.'); @@ -640,7 +658,7 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb, gf_free(tks); return GF_NOT_SUPPORTED; } - if (max_dur<=split_dur) { + if (!rap_split && (max_dur<=split_dur)) { fprintf(stdout, "Input file (%f) shorter than requested split duration (%f)\n", max_dur, split_dur); gf_free(tks); return GF_NOT_SUPPORTED; @@ -718,11 +736,7 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb, Bool is_last; if (chunk_extraction) { - if (outfile) { - strcpy(szFile, outfile); - } else { - sprintf(szFile, "%s_%d_%d%s", szName, (u32) chunk_start, (u32) (chunk_start+split_dur), ext); - } + sprintf(szFile, "%s_%d_%d%s", szName, (u32) chunk_start, (u32) (chunk_start+split_dur), ext); } else { sprintf(szFile, "%s_%03d%s", szName, cur_file+1, ext); } @@ -821,6 +835,12 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb, fprintf(stdout, "Error cloning track %d sample %d\n", tki->tk, tki->last_sample); goto err_exit; } + + tki->next_sample_is_rap = 0; + if (rap_split && tki->has_non_raps) { + if ( gf_isom_get_sample_sync(mp4, tki->tk, tki->last_sample+1)) + tki->next_sample_is_rap = 1; + } } /*test by size/duration*/ @@ -845,11 +865,20 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb, } time = (Double) (s64) tki->lastDTS; time /= tki->time_scale; - if (size_exceeded || (tki->last_sample==tki->sample_count) || (!tki->can_duplicate && (time>file_split_dur)) ) { + if (size_exceeded + || (tki->last_sample==tki->sample_count) + || (!tki->can_duplicate && (time>file_split_dur)) + || (rap_split && tki->has_non_raps && tki->next_sample_is_rap) + ) { nb_over++; tki->stop_state = 1; if (tki->last_samplesample_count) is_last = 0; if ((!tki->can_duplicate || all_duplicatable) && (tki->last_sample==tki->sample_count)) is_last = 1; + + if (rap_split && tki->next_sample_is_rap) { + file_split_dur = (Double) ( gf_isom_get_sample_dts(mp4, tki->tk, tki->last_sample+1) - tki->firstDTS); + file_split_dur /= tki->time_scale; + } } /*special tracks (not audio, not video)*/ else if (tki->can_duplicate) { @@ -878,12 +907,19 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb, continue; } - if (tki->lastDTS) { - time = (Double) (s64) tki->lastDTS; + //if (tki->lastDTS) + { + //time = (Double) (s64) tki->lastDTS; + time = (Double) (s64) ( gf_isom_get_sample_dts(mp4, tki->tk, tki->last_sample+1) - tki->firstDTS); time /= tki->time_scale; if ((!tki->can_duplicate || all_duplicatable) && timenext_sample_is_rap) file_split_dur = time; } } + if (file_split_dur == (Double) GF_MAX_FLOAT) { + fprintf(stdout, "Cannot split file (duration too small or size too small)\n"); + goto err_exit; + } if (chunk_extraction) file_split_dur = split_dur; /*don't split if eq to copy...*/ @@ -911,11 +947,15 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb, while (1) { u64 dts; last_samp = gf_isom_get_sample_count(dest, tki->dst_tk); - if (!last_samp) break; + if (last_samp<=1) break; dts = gf_isom_get_sample_dts(dest, tki->dst_tk, last_samp); time = (Double) (s64) dts; time /= tki->time_scale; + + time = (Double) (s64) gf_isom_get_media_duration(dest, tki->dst_tk); + time /= tki->time_scale; + /*done*/ if (tki->last_sample==tki->sample_count) { if (!chunk_extraction && !tki->can_duplicate) { @@ -923,7 +963,11 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb, break; } } - if (time /*+ (Double) GF_EPSILON_FLOAT*/ < file_split_dur) break; + if (rap_split) { + if (time <= file_split_dur) break; + } else { + if (time < file_split_dur) break; + } gf_isom_remove_sample(dest, tki->dst_tk, last_samp); tki->last_sample--; @@ -1064,7 +1108,8 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou e = import_file(orig, fileName, import_flags, force_fps, frames_per_sample); if (e) return e; } else { - orig = gf_isom_open(fileName, GF_ISOM_OPEN_READ, NULL); + /*we open the original file in edit mode since we may have to rewrite AVC samples*/ + orig = gf_isom_open(fileName, GF_ISOM_OPEN_EDIT, tmp_dir); } nb_samp = 0; @@ -1147,11 +1192,7 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou if (gf_isom_get_sample_description_count(orig, i+1) != gf_isom_get_sample_description_count(dest, dst_tk)) dst_tk = 0; /*if not forcing cat, check the media codec config is the same*/ if (!gf_isom_is_same_sample_description(orig, i+1, dest, dst_tk)) { - if (!force_cat) { - dst_tk = 0; - } else { - fprintf(stdout, "WARNING: Concatenating track ID %d even though sample descriptions do not match\n", tk_id); - } + dst_tk = 0; } /*we force the same visual resolution*/ else if (mtype==GF_ISOM_MEDIA_VISUAL) { @@ -1159,40 +1200,82 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou gf_isom_get_visual_info(orig, i+1, 1, &ow, &oh); gf_isom_get_visual_info(dest, dst_tk, 1, &w, &h); if ((ow!=w) || (oh!=h)) { - if (!force_cat) { - dst_tk = 0; - } else { - fprintf(stdout, "WARNING: Concatenating track ID %d even though visual sizes do not match\n", tk_id); - } + dst_tk = 0; } } + /*merge AVC config if possible*/ if (!dst_tk && ((stype == GF_ISOM_SUBTYPE_AVC_H264) || (stype == GF_ISOM_SUBTYPE_AVC2_H264)) ) { GF_AVCConfig *avc_src, *avc_dst; dst_tk = gf_isom_get_track_by_id(dest, tk_id); avc_src = gf_isom_avc_config_get(orig, i+1, 1); avc_dst = gf_isom_avc_config_get(dest, dst_tk, 1); - - if (avc_src->nal_unit_size != avc_dst->nal_unit_size) dst_tk = 0; - else if (avc_src->AVCLevelIndication!=avc_dst->AVCLevelIndication) dst_tk = 0; - else if (avc_src->AVCProfileIndication!=avc_dst->AVCProfileIndication) dst_tk = 0; + + if (avc_src->AVCLevelIndication!=avc_dst->AVCLevelIndication) { + fprintf(stdout, "Cannot concatenate files: Different AVC Level Indication between source (%d) and destination (%d)\n", avc_src->AVCLevelIndication, avc_dst->AVCLevelIndication); + dst_tk = 0; + } else if (avc_src->AVCProfileIndication!=avc_dst->AVCProfileIndication) { + fprintf(stdout, "Cannot concatenate files: Different AVC Profile Indication between source (%d) and destination (%d)\n", avc_src->AVCProfileIndication, avc_dst->AVCProfileIndication); + dst_tk = 0; + } else { - while (gf_list_count(avc_src->sequenceParameterSets)) { - GF_AVCConfigSlot *slc = gf_list_get(avc_src->sequenceParameterSets, 0); - gf_list_rem(avc_src->sequenceParameterSets, 0); - gf_list_add(avc_dst->sequenceParameterSets, slc); + u32 j, k; + /*rewrite all samples if using different NALU size*/ + if (avc_src->nal_unit_size > avc_dst->nal_unit_size) { + gf_media_avc_rewrite_samples(dest, dst_tk, 8*avc_dst->nal_unit_size, 8*avc_src->nal_unit_size); + avc_dst->nal_unit_size = avc_src->nal_unit_size; + } else if (avc_src->nal_unit_size < avc_dst->nal_unit_size) { + gf_media_avc_rewrite_samples(orig, i+1, 8*avc_src->nal_unit_size, 8*avc_dst->nal_unit_size); + } + + /*merge SPS*/ + for (j=0; jsequenceParameterSets); j++) { + Bool found = 0; + GF_AVCConfigSlot *slc = gf_list_get(avc_src->sequenceParameterSets, j); + for (k=0; ksequenceParameterSets); k++) { + GF_AVCConfigSlot *slc_dst = gf_list_get(avc_dst->sequenceParameterSets, k); + if ( (slc->size==slc_dst->size) && !memcmp(slc->data, slc_dst->data, slc->size) ) { + found = 1; + break; + } + } + if (!found) { + gf_list_rem(avc_src->sequenceParameterSets, j); + j--; + gf_list_add(avc_dst->sequenceParameterSets, slc); + } } - while (gf_list_count(avc_src->pictureParameterSets)) { - GF_AVCConfigSlot *slc = gf_list_get(avc_src->pictureParameterSets, 0); - gf_list_rem(avc_src->pictureParameterSets, 0); - gf_list_add(avc_dst->pictureParameterSets, slc); + /*merge PPS*/ + for (j=0; jpictureParameterSets); j++) { + Bool found = 0; + GF_AVCConfigSlot *slc = gf_list_get(avc_src->pictureParameterSets, j); + for (k=0; kpictureParameterSets); k++) { + GF_AVCConfigSlot *slc_dst = gf_list_get(avc_dst->pictureParameterSets, k); + if ( (slc->size==slc_dst->size) && !memcmp(slc->data, slc_dst->data, slc->size) ) { + found = 1; + break; + } + } + if (!found) { + gf_list_rem(avc_src->pictureParameterSets, j); + j--; + gf_list_add(avc_dst->pictureParameterSets, slc); + } } + gf_isom_avc_config_update(dest, dst_tk, 1, avc_dst); - gf_odf_avc_cfg_del(avc_src); - gf_odf_avc_cfg_del(avc_dst); } + + + gf_odf_avc_cfg_del(avc_src); + gf_odf_avc_cfg_del(avc_dst); + } + + if (!dst_tk && force_cat) { + dst_tk = gf_isom_get_track_by_id(dest, tk_id); + fprintf(stdout, "WARNING: Concatenating track ID %d even though sample descriptions do not match\n", tk_id); } } diff --git a/applications/mp4box/live.c b/applications/mp4box/live.c index b0c1d63..ef26ac2 100644 --- a/applications/mp4box/live.c +++ b/applications/mp4box/live.c @@ -163,7 +163,8 @@ typedef struct u32 timescale, init_time; u32 carousel_period, ts_delta; u16 aggregate_on_stream; - Bool adjust_carousel_time, discard, aggregate, rap, critical, m2ts_vers_inc; + Bool adjust_carousel_time, discard, aggregate, rap, m2ts_vers_inc; + u32 critical; } RTPChannel; typedef struct @@ -234,11 +235,16 @@ static void live_session_callback(void *calling_object, u16 ESID, char *data, u3 } /*send data*/ else { + u32 critical = 0; Bool rap = rtpch->rap; if (livesess->carousel_generation) rap = 1; - ts += rtpch->timescale*(gf_sys_clock()-rtpch->init_time + rtpch->ts_delta)/1000; - gf_rtp_streamer_send_au_with_sn(rtpch->rtp, data, size, ts, ts, rap, (livesess->critical || rtpch->critical) ? 1 : 0 ); - fprintf(stdout, "Stream %d: Sending update at TS "LLD", %d bytes - RAP %d - critical %d\n", ESID, ts, size, rap, (livesess->critical || rtpch->critical) ? 1 : 0); + ts += rtpch->timescale*((u64)gf_sys_clock()-rtpch->init_time + rtpch->ts_delta)/1000; + if (rtpch->critical) critical = rtpch->critical; + else if (livesess->critical) critical = 1; + + gf_rtp_streamer_send_au_with_sn(rtpch->rtp, data, size, ts, ts, rap, critical); + + fprintf(stdout, "Stream %d: Sending update at TS "LLD", %d bytes - RAP %d - critical %d\n", ESID, ts, size, rap, critical); rtpch->rap = rtpch->critical = 0; if (rtpch->manual_rtcp) gf_rtp_streamer_send_rtcp(rtpch->rtp, 0, 0); @@ -254,7 +260,7 @@ static void live_session_send_carousel(LiveSession *livesess, RTPChannel *ch) u64 ts=0; if (ch) { if (ch->carousel_size) { - ts = ch->carousel_ts + ch->timescale * ( (ch->adjust_carousel_time ? gf_sys_clock() : ch->time_at_carousel_store) - ch->init_time + ch->ts_delta)/1000; + ts = ch->carousel_ts + ch->timescale * ( (ch->adjust_carousel_time ? (u64)gf_sys_clock() : ch->time_at_carousel_store) - ch->init_time + ch->ts_delta)/1000; gf_rtp_streamer_send_au_with_sn(ch->rtp, ch->carousel_data, ch->carousel_size, ts, ts, 1, 0); ch->last_carousel_time = now - livesess->start_time; @@ -359,7 +365,7 @@ void live_session_shutdown(LiveSession *livesess) } -static RTPChannel *set_broadcast_params(LiveSession *livesess, u16 esid, u32 period, u32 ts_delta, u16 aggregate_on_stream, Bool adjust_carousel_time, Bool force_rap, Bool aggregate_au, Bool discard_pending, Bool signal_rap, Bool signal_critical, Bool version_inc) +static RTPChannel *set_broadcast_params(LiveSession *livesess, u16 esid, u32 period, u32 ts_delta, u16 aggregate_on_stream, Bool adjust_carousel_time, Bool force_rap, Bool aggregate_au, Bool discard_pending, Bool signal_rap, u32 signal_critical, Bool version_inc) { RTPChannel *rtpch = NULL; @@ -369,6 +375,8 @@ static RTPChannel *set_broadcast_params(LiveSession *livesess, u16 esid, u32 per while ( (rtpch = gf_list_enum(livesess->streams, &i))) { if (rtpch->ESID == esid) break; } + } else { + rtpch = gf_list_get(livesess->streams, 0); } /*TODO - set/reset the ESID for the parsers*/ @@ -429,9 +437,9 @@ int live_session(int argc, char **argv) char *update_buffer = NULL; u32 update_buffer_size = 0; u16 aggregate_on_stream; - Bool adjust_carousel_time, force_rap, aggregate_au, discard_pending, signal_rap, signal_critical, version_inc; + Bool adjust_carousel_time, force_rap, aggregate_au, discard_pending, signal_rap, version_inc; Bool update_context; - u32 period, ts_delta; + u32 period, ts_delta, signal_critical; u16 es_id; e = GF_OK; /* souchay : needs to initialize those two vars... */ diff --git a/applications/mp4box/main.c b/applications/mp4box/main.c index 0af8789..b096daf 100644 --- a/applications/mp4box/main.c +++ b/applications/mp4box/main.c @@ -48,7 +48,7 @@ #ifndef GPAC_DISABLE_ISOM_WRITE void convert_file_info(char *inName, u32 trackID); GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double force_fps, u32 frames_per_sample); -GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb, char *inName, Double InterleavingTime, Double chunk_start, const char *tmpdir, char *outfile); +GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb, char *inName, Double InterleavingTime, Double chunk_start, const char *tmpdir); GF_Err cat_isomedia_file(GF_ISOFile *mp4, char *fileName, u32 import_flags, Double force_fps, u32 frames_per_sample, char *tmp_dir, Bool force_cat); #ifndef GPAC_DISABLE_SCENE_ENCODER @@ -113,7 +113,7 @@ int stream_file_rtp(int argc, char **argv); int live_session(int argc, char **argv); void PrintLiveUsage(); - +int mp4boxTerminal(int argc, char **argv); u32 quiet = 0; Bool dvbhdemux =0; @@ -163,6 +163,10 @@ void PrintVersion() void PrintGeneralUsage() { fprintf(stdout, "General Options:\n" +#ifdef GPAC_MEMORY_TRACKING + " -mem-track: enables memory tracker\n" +#endif + " -strict-error exits after the first error is reported\n" " -inter time_in_ms interleaves file data (track chunks of time_in_ms)\n" " * Note 1: Interleaving is 0.5s by default\n" " * Note 2: Performs drift checking accross tracks\n" @@ -204,9 +208,11 @@ void PrintGeneralUsage() " -itags tag1[:tag2] sets iTunes tags to file - more info: MP4Box -tag-list.\n" " -split time_sec splits in files of time_sec max duration\n" " * Note: this removes all MPEG-4 Systems media\n" - " -split-size size splits in files of max filesize kB.\n" + " -split-size size splits in files of max filesize kB. same as -splits.\n" + " * Note: this removes all MPEG-4 Systems media\n" + " -split-rap splits in files begining at each RAP. same as -splitr.\n" " * Note: this removes all MPEG-4 Systems media\n" - " -split-chunk S:E extracts a new file from Start to End (in seconds)\n" + " -split-chunk S:E extracts a new file from Start to End (in seconds). same as -splitx\n" " * Note: this removes all MPEG-4 Systems media\n" " -group-add fmt creates a new grouping information in the file. Format is\n" " a colon-separated list of following options:\n" @@ -234,12 +240,18 @@ void PrintGeneralUsage() " using the interleaver (-inter) switch.\n" " Note: You can specify -rap switch to split segments at RAP boundaries\n" " -frags-per-sidx N sets the number of segments to be written in each SIDX box\n" - " If 0, SIDX box is not used\n" + " If 0, a single SIDX box is used per segment\n" + " If -1, no SIDX box is used\n" + " -rap segments begin with random access points\n" + " Note: segment duration may not be exactly what asked by\n" + " \"-dash\" since raw video data is not modified\n" " -segment-name name sets the segment name for generated segments\n" " If not set (default), segments are concatenated in output file\n" " -segment-ext name sets the segment extension. Default is m4s\n" " -url-template uses UrlTemplate instead of explicit sources in segments.\n" " Ignored if segments are stored in the output file.\n" + " -daisy-chain Uses daisy-chain SIDX instead of hierarchical. Ignored if frags/sidx is 0.\n" + " -dash-ctx FILE Stores/restore DASH timing from FILE.\n" "\n"); } @@ -314,6 +326,9 @@ void PrintImportUsage() " \":psx\": same as -psx option\n" " \":ovsbr\": same as -ovsbr option\n" " \":mpeg4\" same as -mpeg4 option\n" + " \":svc\" import SVC with explicit signaling (no AVC base compatibility)\n" + " \":nosvc\" discard SVC data when importing\n" + " \":subsamples\" adds SubSample information for AVC+SVC\n" " \":font=name\" specifies font name for text import (default \"Serif\")\n" " \":size=s\" specifies font size for text import (default 18)\n" " \":stype=4CC\" forces the sample description type to a different value\n" @@ -537,6 +552,8 @@ void PrintMetaUsage() " -dump-item args dumps item to file - syntax item_ID[:tk=ID][:path=fileName]\n" " -package packages input XML file into an ISO container\n" " * all media referenced except hyperlinks are added to file\n" + " -mgt packages input XML file into an MPEG-U widget with ISO container.\n" + " * all files contained in the current folder are added to the widget package\n" "\n"); } @@ -546,7 +563,7 @@ void PrintSWFUsage() "SWF Importer Options\n" "\n" "MP4Box can import simple Macromedia Flash files (\".SWF\")\n" - "You can specify a SWF input file with \'-bt\', \'xmt\' and \'-mp4\' options\n" + "You can specify a SWF input file with \'-bt\', \'-xmt\' and \'-mp4\' options\n" "\n" " -global all SWF defines are placed in first scene replace\n" " * Note: By default SWF defines are sent when needed\n" @@ -577,7 +594,8 @@ void PrintUsage() " -h swf Flash (SWF) options help\n" " -h crypt ISMA E&A options help\n" " -h format supported formats help\n" - " -h rtp streamer help\n" + " -h rtp file streamer help\n" + " -h live BIFS streamer help\n" "\n" " -nodes lists supported MPEG4 nodes\n" " -node NodeName gets MPEG4 node syntax and QP info\n" @@ -587,8 +605,8 @@ void PrintUsage() " -snode NodeName gets SVG node syntax\n" " -languages lists supported ISO 639 languages\n" "\n" - "-quiet quiet mode\n" - "-noprog disables progress\n" + " -quiet quiet mode\n" + " -noprog disables progress\n" " -v verbose mode\n" " -version gets build version\n" ); @@ -1166,7 +1184,8 @@ enum GF_ISOM_CONV_TYPE_PSP }; -int main(int argc, char **argv) + +int mp4boxMain(int argc, char **argv) { char outfile[5000]; GF_Err e; @@ -1179,15 +1198,20 @@ int main(int argc, char **argv) TrackAction tracks[MAX_CUMUL_OPS]; TSELAction tsel_acts[MAX_CUMUL_OPS]; u64 movie_time; + s32 frags_per_sidx; u32 brand_add[MAX_CUMUL_OPS], brand_rem[MAX_CUMUL_OPS]; - u32 i, MTUSize, stat_level, hint_flags, info_track_id, import_flags, nb_add, nb_cat, ismaCrypt, agg_samples, nb_sdp_ex, max_ptime, raw_sample_num, split_size, nb_meta_act, nb_track_act, rtp_rate, major_brand, nb_alt_brand_add, nb_alt_brand_rem, old_interleave, car_dur, minor_version, conv_type, nb_tsel_acts, frags_per_sidx, program_number; + u32 i, MTUSize, stat_level, hint_flags, info_track_id, import_flags, nb_add, nb_cat, ismaCrypt, agg_samples, nb_sdp_ex, max_ptime, raw_sample_num, split_size, nb_meta_act, nb_track_act, rtp_rate, major_brand, nb_alt_brand_add, nb_alt_brand_rem, old_interleave, car_dur, minor_version, conv_type, nb_tsel_acts, program_number; Bool HintIt, needSave, FullInter, Frag, HintInter, dump_std, dump_rtp, dump_mode, regular_iod, trackID, HintCopy, remove_sys_tracks, remove_hint, force_new, remove_root_od, import_subtitle, dump_chap; Bool print_sdp, print_info, open_edit, track_dump_type, dump_isom, dump_cr, force_ocr, encode, do_log, do_flat, dump_srt, dump_ttxt, x3d_info, chunk_mode, dump_ts, do_saf, do_mpd, dump_m2ts, dump_cart, do_hash, verbose, force_cat, pack_wgt, dash_ts_use_index; - char *inName, *outName, *arg, *mediaSource, *tmpdir, *input_ctx, *output_ctx, *drm_file, *avi2raw, *cprt, *chap_file, *pes_dump, *itunes_tags, *pack_file, *raw_cat, *seg_name; + char *inName, *outName, *arg, *mediaSource, *tmpdir, *input_ctx, *output_ctx, *drm_file, *avi2raw, *cprt, *chap_file, *pes_dump, *itunes_tags, *pack_file, *raw_cat, *seg_name, *dash_ctx; GF_ISOFile *file; Bool stream_rtp=0; Bool live_scene=0; +#ifdef GPAC_MEMORY_TRACKING + Bool enable_mem_tracker = 0; +#endif Bool dump_iod=0; + Bool daisy_chain_sidx=0; Bool use_url_template=0; Bool seg_at_rap =0; char *seg_ext = "m4s"; @@ -1212,12 +1236,12 @@ int main(int argc, char **argv) HintCopy = FullInter = HintInter = encode = do_log = old_interleave = do_saf = do_mpd = do_hash = verbose = 0; chunk_mode = dump_mode = Frag = force_ocr = remove_sys_tracks = agg_samples = remove_hint = keep_sys_tracks = remove_root_od = 0; x3d_info = conv_type = HintIt = needSave = print_sdp = print_info = regular_iod = dump_std = open_edit = dump_isom = dump_rtp = dump_cr = dump_chap = dump_srt = dump_ttxt = force_new = dump_ts = dump_m2ts = dump_cart = import_subtitle = force_cat = pack_wgt = 0; - frags_per_sidx = 1; + frags_per_sidx = 0; track_dump_type = 0; ismaCrypt = 0; file = NULL; itunes_tags = pes_dump = NULL; - seg_name = NULL; + seg_name = dash_ctx = NULL; #ifndef GPAC_DISABLE_SCENE_ENCODER memset(&opts, 0, sizeof(opts)); @@ -1428,7 +1452,15 @@ int main(int argc, char **argv) } else if (!stricmp(arg, "-cprt")) { CHECK_NEXT_ARG cprt = argv[i+1]; i++; open_edit = 1; } else if (!stricmp(arg, "-chap")) { CHECK_NEXT_ARG chap_file = argv[i+1]; i++; open_edit = 1; } - else if (!stricmp(arg, "-inter") || !stricmp(arg, "-old-inter")) { + else if (!strcmp(arg, "-mem-track")) { +#ifdef GPAC_MEMORY_TRACKING + enable_mem_tracker = 1; +#else + fprintf(stdout, "WARNING - GPAC not compiled with Memory Tracker - ignoring \"-mem-track\"\n"); +#endif + } else if (!strcmp(arg, "-strict-error")) { + gf_log_set_strict_error(1); + } else if (!stricmp(arg, "-inter") || !stricmp(arg, "-old-inter")) { CHECK_NEXT_ARG InterleavingTime = atof(argv[i+1]) / 1000; open_edit = 1; @@ -1465,9 +1497,15 @@ int main(int argc, char **argv) CHECK_NEXT_ARG seg_ext = argv[i+1]; i++; + } else if (!stricmp(arg, "-dash-ctx")) { + CHECK_NEXT_ARG + dash_ctx = argv[i+1]; + i++; + } else if (!stricmp(arg, "-daisy-chain")) { + daisy_chain_sidx = 1; } else if (!stricmp(arg, "-url-template")) { use_url_template = 1; - } + } else if (!stricmp(arg, "-itags")) { CHECK_NEXT_ARG itunes_tags = argv[i+1]; i++; open_edit = 1; } #ifndef GPAC_DISABLE_ISOM_HINTING else if (!stricmp(arg, "-hint")) { open_edit = 1; HintIt = 1; } @@ -1726,7 +1764,7 @@ int main(int argc, char **argv) else if (!stricmp(arg, "-ovsbr")) import_flags |= GF_IMPORT_OVSBR; else if (!stricmp(arg, "-fps")) { CHECK_NEXT_ARG - if (!strcmp(argv[i+1], "auto")) import_fps = 10000.0; + if (!strcmp(argv[i+1], "auto")) import_fps = GF_IMPORT_AUTO_FPS; else if (strchr(argv[i+1], '-')) { u32 ticks, dts_inc; sscanf(argv[i+1], "%u-%u", &ticks, &dts_inc); @@ -1847,8 +1885,25 @@ int main(int argc, char **argv) nb_track_act++; i++; } - else if (!stricmp(arg, "-split")) { CHECK_NEXT_ARG split_duration = atof(argv[i+1]); i++; split_size = 0; } - else if (!stricmp(arg, "-split-size") || !stricmp(arg, "-splits")) { CHECK_NEXT_ARG split_size = atoi(argv[i+1]); i++; split_duration = 0; } + else if (!stricmp(arg, "-split")) { + CHECK_NEXT_ARG + split_duration = atof(argv[i+1]); + if (split_duration<0) split_duration=0;; + i++; + split_size = 0; + } + else if (!stricmp(arg, "-split-rap") || !stricmp(arg, "-splitr")) { + CHECK_NEXT_ARG + split_duration = -1; + split_size = -1; + } + else if (!stricmp(arg, "-split-size") || !stricmp(arg, "-splits")) { + CHECK_NEXT_ARG + split_size = atoi(argv[i+1]); + if (split_size<0) split_size = 0; + i++; + split_duration = 0; + } else if (!stricmp(arg, "-split-chunk") || !stricmp(arg, "-splitx")) { CHECK_NEXT_ARG if (!strstr(argv[i+1], ":")) { @@ -2070,16 +2125,29 @@ int main(int argc, char **argv) return 0; } -// gf_log_set_level((verbose>1) ? GF_LOG_DEBUG : (verbose ? GF_LOG_INFO : GF_LOG_WARNING) ); - gf_log_set_level(verbose ? GF_LOG_DEBUG : GF_LOG_INFO); - gf_log_set_tools(GF_LOG_CONTAINER|GF_LOG_SCENE|GF_LOG_PARSER|GF_LOG_AUTHOR|GF_LOG_CODING); - if (quiet) { - if (quiet==2) gf_log_set_level(0); - gf_set_progress_callback(NULL, progress_quiet); + { + u32 logtools = GF_LOG_CONTAINER|GF_LOG_SCENE|GF_LOG_PARSER|GF_LOG_AUTHOR|GF_LOG_CODING; +#ifdef GPAC_MEMORY_TRACKING + if (enable_mem_tracker) logtools |= GF_LOG_MEMORY; +#endif + + //gf_log_set_level((verbose>1) ? GF_LOG_DEBUG : (verbose ? GF_LOG_INFO : GF_LOG_WARNING) ); + gf_log_set_level(verbose ? GF_LOG_DEBUG : GF_LOG_INFO); + gf_log_set_tools(logtools); + if (quiet) { + if (quiet==2) gf_log_set_level(0); + gf_set_progress_callback(NULL, progress_quiet); + + } } + /*init libgpac*/ - gf_sys_init(1); +#ifdef GPAC_MEMORY_TRACKING + gf_sys_init(enable_mem_tracker); +#else + gf_sys_init(0); +#endif if (do_mpd) { Bool remote = 0; @@ -2167,8 +2235,13 @@ int main(int argc, char **argv) if (!test) { open_mode = (do_flat) ? GF_ISOM_OPEN_WRITE : GF_ISOM_WRITE_EDIT; if (!outName) outName = inName; + } else { + fclose(test); + if (! gf_isom_probe_file(inName) ) { + open_mode = (do_flat) ? GF_ISOM_OPEN_WRITE : GF_ISOM_WRITE_EDIT; + if (!outName) outName = inName; + } } - else fclose(test); } open_edit = 1; @@ -2192,7 +2265,8 @@ int main(int argc, char **argv) /*unless explicitly asked, remove all systems tracks*/ if (!keep_sys_tracks) remove_systems_tracks(file); needSave = 1; - if (!conv_type && can_convert_to_isma(file)) conv_type = GF_ISOM_CONV_TYPE_ISMA; + /*JLF commented: if you want ISMA, just ask for it, no more auto-detect*/ +// if (!conv_type && can_convert_to_isma(file)) conv_type = GF_ISOM_CONV_TYPE_ISMA; } if (nb_cat) { @@ -2366,6 +2440,7 @@ int main(int argc, char **argv) } if (dash_duration) { + if (frags_per_sidx<0) frags_per_sidx = 0; #ifndef GPAC_DISABLE_MPEG2TS dump_mpeg2_ts(inName, NULL, program_number, dash_duration, seg_at_rap, frags_per_sidx, seg_name, seg_ext, use_url_template, dash_ts_use_index); @@ -2516,9 +2591,10 @@ int main(int argc, char **argv) #ifndef GPAC_DISABLE_ISOM_WRITE if (split_duration || split_size) { - split_isomedia_file(file, split_duration, split_size, inName, InterleavingTime, split_start, tmpdir, outName); + split_isomedia_file(file, split_duration, split_size, inName, InterleavingTime, split_start, tmpdir); /*never save file when splitting is desired*/ open_edit = 0; + needSave = 0; } #endif @@ -2601,7 +2677,7 @@ int main(int argc, char **argv) break; #endif case 7: - if (gf_isom_get_meta_item_count(file, meta->root_meta, tk)) { + if (gf_isom_has_meta_xml(file, meta->root_meta, tk)) { e = gf_isom_extract_meta_xml(file, meta->root_meta, tk, meta->szPath, NULL); } else { fprintf(stdout, "No meta box in input file\n"); @@ -3001,7 +3077,11 @@ int main(int argc, char **argv) /*split file*/ if (dash_duration) { - fprintf(stdout, "DASH-ing file with %.3f secs segments with %d fragments of %.3f secs", dash_duration, frags_per_sidx, InterleavingTime); + + fprintf(stdout, "DASH-ing file with %.3f secs segments - fragments: %.3f secs - ", dash_duration, InterleavingTime); + if (frags_per_sidx<0) fprintf(stdout, "no sidx"); + else if (frags_per_sidx) fprintf(stdout, "%d per sidx", frags_per_sidx); + else fprintf(stdout, "single sidx"); if (seg_at_rap) fprintf(stdout, " at GOP boundaries"); fprintf(stdout, "\n"); @@ -3009,7 +3089,7 @@ int main(int argc, char **argv) while (outfile[strlen(outfile)-1] != '.') outfile[strlen(outfile)-1] = 0; outfile[strlen(outfile)-1] = 0; if (!outName) strcat(outfile, "_dash"); - e = gf_media_fragment_file(file, outfile, InterleavingTime, seg_at_rap ? 2 : 1, dash_duration, seg_name, seg_ext, frags_per_sidx, 0, use_url_template); + e = gf_media_fragment_file(file, outfile, InterleavingTime, seg_at_rap ? 2 : 1, dash_duration, seg_name, seg_ext, frags_per_sidx, daisy_chain_sidx, use_url_template, dash_ctx); if (e) fprintf(stdout, "Error while DASH-ing file: %s\n", gf_error_to_string(e)); gf_isom_delete(file); gf_sys_close(); @@ -3018,7 +3098,7 @@ int main(int argc, char **argv) if (!InterleavingTime) InterleavingTime = 0.5; if (HintIt) fprintf(stdout, "Warning: cannot hint and fragment - ignoring hint\n"); fprintf(stdout, "Fragmenting file (%.3f seconds fragments)\n", InterleavingTime); - e = gf_media_fragment_file(file, outfile, InterleavingTime, 0, 0, NULL, NULL, 0, 0, 0); + e = gf_media_fragment_file(file, outfile, InterleavingTime, 0, 0, NULL, NULL, 0, 0, 0, NULL); if (e) fprintf(stdout, "Error while fragmenting file: %s\n", gf_error_to_string(e)); gf_isom_delete(file); if (!e && !outName && !force_new) { @@ -3150,9 +3230,14 @@ int main(int argc, char **argv) err_exit: /*close libgpac*/ gf_sys_close(); - if (file) gf_isom_delete(file); + if (file) gf_isom_delete(file); fprintf(stdout, "\n\tError: %s\n", gf_error_to_string(e)); return 1; } +int main( int argc, char** argv ) +{ + return mp4boxMain( argc, argv ); +} + #endif /*GPAC_DISABLE_ISOM*/ diff --git a/applications/mp4box/wrapper.c b/applications/mp4box/wrapper.c new file mode 100644 index 0000000..8a8bc58 --- /dev/null +++ b/applications/mp4box/wrapper.c @@ -0,0 +1,104 @@ +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "stdlib.h" +#include "stdio.h" +#include "string.h" + + +#define jniTAG "WRAPPER_JNI" + +#define jniLOGV(X) __android_log_print(ANDROID_LOG_VERBOSE, jniTAG, X) +#define jniLOGI(X) __android_log_print(ANDROID_LOG_INFO, jniTAG, X) +#define jniLOGE(X) __android_log_print(ANDROID_LOG_ERROR, jniTAG, X) + +/*#define CAST_HANDLE(wr) jclass c = env->GetObjectClass(obj);\ + if (!c) return;\ + jfieldID fid = env->GetFieldID(c, "handle", "J");\ + if (!fid){\ + __android_log_print(ANDROID_LOG_ERROR, jniTAG, "No Field ID, ERROR");\ + return;\ + }\ + jlong h = env->GetLongField(obj, fid); + //CNativeWrapper* wr = (CNativeWrapper*) h;*/ + +char ** ConvertCommandLine( const char* sCommand, int* iNbArg ); + +JNIEXPORT void JNICALL Java_com_enst_mp4box_mp4terminal_run(JNIEnv * env, jobject obj, jstring sCommand) +{ + //CAST_HANDLE(wr); + jniLOGV("mp4terminal::start"); + /*if (!wr) + { + jniLOGV("mp4terminal::end : aborted"); + return; + }*/ + jboolean isCopy; + const char * sOriginalCommand = (*env)->GetStringUTFChars(env, sCommand, &isCopy); + + jniLOGV("mp4terminal::command get back ok"); + jniLOGV(sOriginalCommand); + + int iNbArg = 0; + + int i = 0; + char** sConvertedCommandLine; + sConvertedCommandLine = ConvertCommandLine( sOriginalCommand, &i ); + + jniLOGV("Convert command line done"); + FILE* ferr = freopen( "/mnt/sdcard/stderrout.txt", "w", stderr ); + + FILE* fout = freopen( "/mnt/sdcard/stdout.txt", "w", stdout ); + + mp4boxMain(i, sConvertedCommandLine); + + (*env)->ReleaseStringUTFChars(env, sCommand, sOriginalCommand); + jniLOGV("mp4terminal::end"); + fclose(ferr); + fclose(fout); +} + +char ** ConvertCommandLine( const char* sCommand, int* iNbArg ) +{ + int iLength = strlen( sCommand ); + int iArgNumber = 1; + int i = 0; + char** pReturn; + int iPreviousPos = 0; + int k = 1;//begin at character position 1 as the 0 position will be held by the process name , i.e. mp4box + int l = 0; + + for ( i = 0; i < iLength ; i++ ) + { + if( sCommand[i] == ' ' ) + { + iArgNumber++; + } + } + iArgNumber++;; // last argument will not be detected as it is not followed by a space character + pReturn = (char**)malloc(sizeof(char*)*iArgNumber); + pReturn[0] = (char*)malloc(sizeof( char) * ( 7 )); + strcpy( pReturn[0], "MP4Box" );//just a place holder , will never be read. + pReturn[0][6] = '\0'; + + for ( l = 0; l <= iLength ; l++ ) + { + if( sCommand[l] == ' ' || l == ( iLength ) ) + { + pReturn[k] = (char*)malloc(sizeof( char) * ( l - iPreviousPos + 1)); + strncpy( pReturn[k], sCommand + iPreviousPos, l - iPreviousPos ); + pReturn[k][l-iPreviousPos] = '\0'; + iPreviousPos = l + 1; + k++; + } + } + *iNbArg = iArgNumber; + return pReturn; +} +#ifdef __cplusplus +} +#endif + diff --git a/applications/mp4box_android/.classpath b/applications/mp4box_android/.classpath new file mode 100644 index 0000000..609aa00 --- /dev/null +++ b/applications/mp4box_android/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/applications/mp4box_android/.project b/applications/mp4box_android/.project new file mode 100644 index 0000000..d7f5daa --- /dev/null +++ b/applications/mp4box_android/.project @@ -0,0 +1,33 @@ + + + mp4box + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/applications/mp4box_android/AndroidManifest.xml b/applications/mp4box_android/AndroidManifest.xml new file mode 100644 index 0000000..ba98ed9 --- /dev/null +++ b/applications/mp4box_android/AndroidManifest.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + diff --git a/applications/mp4box_android/default.properties b/applications/mp4box_android/default.properties new file mode 100644 index 0000000..e2e8061 --- /dev/null +++ b/applications/mp4box_android/default.properties @@ -0,0 +1,11 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=android-8 diff --git a/applications/mp4box_android/gen/org/enst/mp4box/R.java b/applications/mp4box_android/gen/org/enst/mp4box/R.java new file mode 100644 index 0000000..399c89c --- /dev/null +++ b/applications/mp4box_android/gen/org/enst/mp4box/R.java @@ -0,0 +1,30 @@ +/* AUTO-GENERATED FILE. DO NOT MODIFY. + * + * This class was automatically generated by the + * aapt tool from the resource data it found. It + * should not be modified by hand. + */ + +package com.enst.mp4box; + +public final class R { + public static final class attr { + } + public static final class drawable { + public static final int icon=0x7f020000; + } + public static final class id { + public static final int CommandLineEdit=0x7f050001; + public static final int OkButton=0x7f050002; + public static final int textView1=0x7f050000; + } + public static final class layout { + public static final int main=0x7f030000; + } + public static final class string { + public static final int CommandLineTitle=0x7f040002; + public static final int OkButton=0x7f040003; + public static final int app_name=0x7f040001; + public static final int hello=0x7f040000; + } +} diff --git a/applications/mp4box_android/proguard.cfg b/applications/mp4box_android/proguard.cfg new file mode 100644 index 0000000..12dd039 --- /dev/null +++ b/applications/mp4box_android/proguard.cfg @@ -0,0 +1,36 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class * extends android.app.backup.BackupAgentHelper +-keep public class * extends android.preference.Preference +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/applications/mp4box_android/res/drawable-hdpi/icon.png b/applications/mp4box_android/res/drawable-hdpi/icon.png new file mode 100644 index 0000000..8074c4c Binary files /dev/null and b/applications/mp4box_android/res/drawable-hdpi/icon.png differ diff --git a/applications/mp4box_android/res/drawable-ldpi/icon.png b/applications/mp4box_android/res/drawable-ldpi/icon.png new file mode 100644 index 0000000..1095584 Binary files /dev/null and b/applications/mp4box_android/res/drawable-ldpi/icon.png differ diff --git a/applications/mp4box_android/res/drawable-mdpi/icon.png b/applications/mp4box_android/res/drawable-mdpi/icon.png new file mode 100644 index 0000000..a07c69f Binary files /dev/null and b/applications/mp4box_android/res/drawable-mdpi/icon.png differ diff --git a/applications/mp4box_android/res/layout/main.xml b/applications/mp4box_android/res/layout/main.xml new file mode 100644 index 0000000..097c3b9 --- /dev/null +++ b/applications/mp4box_android/res/layout/main.xml @@ -0,0 +1,10 @@ + + + + + + diff --git a/applications/mp4box_android/res/values/strings.xml b/applications/mp4box_android/res/values/strings.xml new file mode 100644 index 0000000..dece8e7 --- /dev/null +++ b/applications/mp4box_android/res/values/strings.xml @@ -0,0 +1,7 @@ + + + Hello World, mp4box! + mp4box + Command Line : + Ok + diff --git a/applications/mp4box_android/src/com/enst/mp4box/mp4box.java b/applications/mp4box_android/src/com/enst/mp4box/mp4box.java new file mode 100644 index 0000000..4a3f1e7 --- /dev/null +++ b/applications/mp4box_android/src/com/enst/mp4box/mp4box.java @@ -0,0 +1,129 @@ +package com.enst.mp4box; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import com.enst.mp4box.R; + +import android.app.Activity; +import android.os.Bundle; +import android.widget.Button; +import android.widget.EditText; +import android.util.Log; +import android.view.View; + + + +public class mp4box extends Activity { + private mp4terminal myTerminal; + + /** Called when the activity is first created. */ + @Override + + + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + myTerminal = new mp4terminal(); + errors = loadAllLibraries(); + System.out.println( "hello world java" ); + final Button button = (Button) findViewById(R.id.OkButton); + + button.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + EditText oCommandLine = (EditText) findViewById(R.id.CommandLineEdit ); + CharSequence sCommandLine = oCommandLine.getText(); + myTerminal.run( sCommandLine.toString() ); + //showKeyboard( true ); + } + }); + + } + + + + + private static Map errors = null; + + synchronized static Map loadAllLibraries() + { + if( errors != null) + return errors; + StringBuilder sb = new StringBuilder(); + final String[] toLoad = { "GLESv1_CM", "dl", "log",//$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ + "jpeg", "javaenv", //$NON-NLS-1$ //$NON-NLS-2$ + "mad", "editline", "ft2", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "js_osmo", "openjpeg", "png", "z", //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$ + "ffmpeg", "faad", "gpac", //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ + "stdc++", "mp4box" }; // //$NON-NLS-1$ //$NON-NLS-2$ + HashMap exceptions = new HashMap(); + for (String s : toLoad) { + try { + String msg = "Loading library " + s + "...";//$NON-NLS-1$//$NON-NLS-2$ + sb.append(msg); + //Log.i(LOG_LIB, msg); + System.loadLibrary(s); + } catch (UnsatisfiedLinkError e) { + sb.append("Failed to load " + s + ", error=" + e.getLocalizedMessage() + " :: " //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + + e.getClass().getSimpleName() + "\n"); //$NON-NLS-1$ + exceptions.put(s, e); + //Log.e(LOG_LIB, "Failed to load library : " + s + " due to link error " + e.getLocalizedMessage(), e); //$NON-NLS-1$ //$NON-NLS-2$ + } catch (SecurityException e) { + exceptions.put(s, e); + //Log.e(LOG_LIB, "Failed to load library : " + s + " due to security error " + e.getLocalizedMessage(), e); //$NON-NLS-1$ //$NON-NLS-2$ + } catch (Throwable e) { + exceptions.put(s, e); + //Log.e(LOG_LIB, "Failed to load library : " + s + " due to Runtime error " + e.getLocalizedMessage(), e); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + /*if (!exceptions.isEmpty()) { + try { + PrintStream out = new PrintStream(config.getGpacConfigDirectory() + "debug_libs.txt", "UTF-8"); //$NON-NLS-1$//$NON-NLS-2$ + out.println("$Revision: 2972 $"); //$NON-NLS-1$ + out.println(new Date()); + out.println("\n*** Configuration\n"); //$NON-NLS-1$ + out.println(config.getConfigAsText()); + sb.append("*** Libs listing: "); //$NON-NLS-1$ + sb.append(config.getGpacLibsDirectory()); + sb.append('\n'); + listing(sb, new File(config.getGpacLibsDirectory()), 2); + sb.append("*** Modules listing: "); //$NON-NLS-1$ + sb.append(config.getGpacModulesDirectory()); + sb.append('\n'); + listing(sb, new File(config.getGpacModulesDirectory()), 2); + sb.append("*** Fonts listing: \n"); //$NON-NLS-1$ + sb.append(config.getGpacFontDirectory()); + sb.append('\n'); + listing(sb, new File(config.getGpacFontDirectory()), 2); + sb.append("*** Exceptions:\n"); //$NON-NLS-1$ + for (Map.Entry ex : exceptions.entrySet()) { + sb.append(ex.getKey()).append(": ") //$NON-NLS-1$ + .append(ex.getValue().getLocalizedMessage()) + .append('(') + .append(ex.getValue().getClass()) + .append(")\n"); //$NON-NLS-1$ + } + out.println(sb.toString()); + out.flush(); + out.close(); + } catch (Exception e) { + Log.e(LOG_LIB, "Failed to output debug info to debug file", e); //$NON-NLS-1$ + } + }*/ + errors = Collections.unmodifiableMap(exceptions); + return errors; +} + /*public void showKeyboard(boolean showKeyboard) { + if (keyboardIsVisible == showKeyboard == true) + return; + InputMethodManager mgr = ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE)); + this.keyboardIsVisible = showKeyboard; + if (showKeyboard) + mgr.showSoftInput(findViewById(R.id.CommandLineEdit ), 0); + else + mgr.hideSoftInputFromInputMethod(findViewById(R.id.CommandLineEdit ).getWindowToken(), 0); + + }*/ +} \ No newline at end of file diff --git a/applications/mp4box_android/src/com/enst/mp4box/mp4terminal.java b/applications/mp4box_android/src/com/enst/mp4box/mp4terminal.java new file mode 100644 index 0000000..7b77bb6 --- /dev/null +++ b/applications/mp4box_android/src/com/enst/mp4box/mp4terminal.java @@ -0,0 +1,7 @@ +package com.enst.mp4box; + + +public class mp4terminal { + + public native void run( String sCommandLine); +} diff --git a/applications/mp4client/Makefile b/applications/mp4client/Makefile index 68bac02..0cdc8d9 100644 --- a/applications/mp4client/Makefile +++ b/applications/mp4client/Makefile @@ -4,7 +4,7 @@ vpath %.c $(SRC_PATH)/applications/mp4client CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include" -I../../ -LINKLIBS=$(OGL_LIBS) +LINKLIBS=$(GPAC_SH_FLAGS) ifeq ($(DEBUGBUILD), yes) CFLAGS+=-g @@ -23,15 +23,6 @@ endif #common obj OBJS= main.o extract.o -#not the same path as local in target -ifneq ($(CROSS_COMPILING), yes) -ifeq ($(BUILD_INSTALL), yes) -INSTALL_FLAGS=-DGPAC_MODULES_PATH=\"$(moddir)\" -else -INSTALL_FLAGS= -endif -endif - ifeq ($(CONFIG_WIN32),yes) EXE=.exe PROG=MP4Client$(EXE) @@ -40,30 +31,6 @@ EXT= PROG=MP4Client endif -ifneq ($(CONFIG_JPEG), no) -#LINKLIBS+= -L$(prefix)/lib -else -ifneq ($(CONFIG_PNG), no) -#LINKLIBS+= -L$(prefix)/lib -else -ifeq ($(CONFIG_JS),prefix) -#LINKLIBS+= -L$(prefix)/lib -endif -endif -endif - -ifeq ($(CONFIG_JPEG), no) -else -#LINKLIBS+= -ljpeg -endif - - -ifeq ($(CONFIG_PNG), no) -else -#LINKLIBS+= -lpng -endif - - SRCS := $(OBJS:.o=.c) all: $(PROG) @@ -72,17 +39,16 @@ MP4Client$(EXE): $(OBJS) $(CC) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(LINKLIBS) %.o: %.c - $(CC) $(CFLAGS) $(INSTALL_FLAGS) -c -o $@ $< + $(CC) $(CFLAGS) -c -o $@ $< clean: rm -f $(OBJS) ../../bin/gcc/$(PROG) install: clean - $(MAKE) -override BUILD_INSTALL=yes all install -m 755 $(INSTFLAGS) ../../bin/gcc/MP4Client "$(DESTDIR)$(prefix)/bin" uninstall: - rm -rf $(prefix)/bin/MP4Client + rm -rf $(DESTDIR)$(prefix)/bin/MP4Client dep: depend diff --git a/applications/mp4client/extract.c b/applications/mp4client/extract.c index 6aac57e..2458dcf 100644 --- a/applications/mp4client/extract.c +++ b/applications/mp4client/extract.c @@ -26,6 +26,7 @@ #include #include +#include #ifdef WIN32 #include @@ -678,7 +679,7 @@ Bool dump_file(char *url, u32 dump_mode, Double fps, u32 width, u32 height, Floa } } - if (!fps) fps = 25.0; + if (!fps) fps = GF_IMPORT_DEFAULT_FPS; time = prev_time = 0; nb_frames = 0; @@ -705,7 +706,7 @@ Bool dump_file(char *url, u32 dump_mode, Double fps, u32 width, u32 height, Floa while ((gf_term_get_option(term, GF_OPT_PLAY_STATE) == GF_STATE_STEP_PAUSE)) { gf_term_process_flush(term); } - fprintf(stdout, "Dumping %02d/100\r", (u32) ((100.0*prev_time)/dump_dur) ); + fprintf(stdout, "Dumping %02d/100 %% - time %.02f sec\r", (u32) ((100.0*prev_time)/dump_dur), prev_time/1000.0 ); if (dump_mode==8) { /*we'll dump both buffers at once*/ @@ -721,6 +722,11 @@ Bool dump_file(char *url, u32 dump_mode, Double fps, u32 width, u32 height, Floa time = (u32) (nb_frames*1000/fps); gf_term_step_clocks(term, time - prev_time); prev_time = time; + + if (gf_prompt_has_input() && (gf_prompt_get_char()=='q')) { + fprintf(stdout, "Aborting dump\n"); + break; + } } AVI_close(avi_out); if (dump_mode==8) AVI_close(depth_avi_out); diff --git a/applications/mp4client/main.c b/applications/mp4client/main.c index 08cecb7..5861508 100644 --- a/applications/mp4client/main.c +++ b/applications/mp4client/main.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -44,12 +45,6 @@ #else #include /*for GetModuleFileName*/ -#include /*for _mkdir*/ -#include /*for getting user-dir*/ -#ifndef SHGFP_TYPE_CURRENT -#define SHGFP_TYPE_CURRENT 0 /*needed for MinGW*/ -#endif - #endif //WIN32 /*local prototypes*/ @@ -83,6 +78,8 @@ GF_Err last_error = GF_OK; static Fixed bench_speed = FLT2FIX(20); static Bool request_next_playlist_item = 0; +FILE *playlist = NULL; +static Bool readonly_playlist = 0; static GF_Config *cfg_file; static Bool display_rti = 0; @@ -126,19 +123,23 @@ void hide_shell(u32 cmd_type) void PrintUsage() { fprintf(stdout, "Usage MP4Client [options] [filename]\n" - "\t-c fileName: user-defined configuration file\n" + "\t-c fileName: user-defined configuration file. Also works with -cfg\n" +#ifdef GPAC_MEMORY_TRACKING + "\t-mem-track: enables memory tracker\n" +#endif "\t-rti fileName: logs run-time info (FPS, CPU, Mem usage) to file\n" "\t-rtix fileName: same as -rti but driven by GPAC logs\n" "\t-quiet: removes script message, buffering and downloading status\n" + "\t-strict-error: exit when the player reports its first error\n" "\t-opt option: Overrides an option in the configuration file. String format is section:key=value\n" - "\t-log-file file: sets output log file.\n" - "\t-log-level lev: sets log level. Possible values are:\n" + "\t-log-file file: sets output log file. Also works with -lf\n" + "\t-log-level lev: sets log level. Also works with -ll. Possible values are:\n" "\t \"error\" : logs only error messages\n" "\t \"warning\" : logs error+warning messages\n" "\t \"info\" : logs error+warning+info messages\n" "\t \"debug\" : logs all messages\n" "\n" - "\t-log-tools lt: sets tool(s) to log. List of \':\'-separated values:\n" + "\t-log-tools lt: sets tool(s) to log. Also works with -lt. List of \':\'-separated values:\n" "\t \"core\" : libgpac core\n" "\t \"coding\" : bitstream formats (audio, video, scene)\n" "\t \"container\" : container formats (ISO File, MPEG-2 TS, AVI, ...)\n" @@ -159,7 +160,6 @@ void PrintUsage() "\t \"all\" : all tools logged\n" "\n" "\t-size WxH: specifies visual size (default: scene size)\n" - "\t-scale s: scales the visual size (default: 1)\n" #if defined(__DARWIN__) || defined(__APPLE__) "\t-thread: enables thread usage for terminal and compositor \n" #else @@ -167,6 +167,7 @@ void PrintUsage() #endif "\t-no-audio: disables audio \n" "\t-no-wnd: uses windowless mode (Win32 only)\n" + "\t-no-back: uses transparent background for output window when no background is specified (Win32 only)\n" "\t-align vh: specifies v and h alignment for windowless mode\n" " possible v values: t(op), m(iddle), b(ottom)\n" " possible h values: l(eft), m(iddle), r(ight)\n" @@ -174,6 +175,15 @@ void PrintUsage() " default alignment is top-left\n" "\t-pause: pauses at first frame\n" "\t-loop: loops presentation\n" + "\t-no-regulation: disables framerate regulation\n" + "\t-fs: starts in fullscreen mode\n" + "\t-views v1:.:vN: creates an auto-stereo scene of N views. vN can be any type of URL supported by GPAC. \n" + " in this mode, URL argument of GPAC is ignored, GUI as well.\n" + " this is equivalent as using views://v1:.:N as an URL.\n" + "\n" + "\t-exit: automatically exits when presentation is over\n" + "\t-run-for TIME: runs for TIME seconds and exits\n" + "\t-gui: starts in GUI mode. The GUI is indicated in GPAC config, section General, by the key [StartupFile]\n" "\n" "Dumper Options:\n" "\t-bmp [times]: dumps given frames to bmp\n" @@ -187,14 +197,16 @@ void PrintUsage() "\t-depth: dumps depthmap (z-buffer) frames\n" " with -avi [times]: dumps depthmap in grayscale .avi\n" " with -bmp: dumps depthmap in grayscale .bmp\n" - "\t-fps FPS: specifies frame rate for AVI dumping (default: 25.0)\n" - "\t-2d: uses 2D compositor\n" - "\t-3d: uses 3D compositor\n" + "\t-fps FPS: specifies frame rate for AVI dumping (default: %f)\n" + "\t-scale s: scales the visual size (default: 1)\n" "\t-fill: uses fill aspect ratio for dumping (default: none)\n" "\t-show: show window while dumping (default: no)\n" + "\n" + "\t-help: show this screen\n" + "\n" "MP4Client - GPAC command line player and dumper - version %s\n" "GPAC Written by Jean Le Feuvre (c) 2001-2005 - ENST (c) 2005-200X\n", - + GF_IMPORT_DEFAULT_FPS, GPAC_FULL_VERSION ); } @@ -202,15 +214,23 @@ void PrintUsage() void PrintHelp() { fprintf(stdout, "MP4Client command keys:\n" + "\tq: quit\n" + "\tX: kill\n" "\to: connect to the specified URL\n" - "\tO: connect to the specified URL in playlist mode\n" - "\tN: switch to the next URL in the playlist (works with return key as well)\n" - "\tr: restart current presentation\n" + "\tO: connect to the specified playlist\n" + "\tN: switch to the next URL in the playlist. Also works with \\n\n" + "\tP: jumps to a given number ahead in the playlist\n" + "\tr: reload current presentation\n" + "\tD: disconnects the current presentation\n" + "\n" "\tp: play/pause the presentation\n" "\ts: step one frame ahead\n" "\tz: seek into presentation\n" "\tt: print current timing\n" "\n" + "\tu: sends a command (BIFS or LASeR) to the main scene\n" + "\tZ: dumps output video to PNG\n" + "\n" "\tw: view world info\n" "\tv: view Object Descriptor list\n" "\ti: view Object Descriptor info (by ID)\n" @@ -219,16 +239,11 @@ void PrintHelp() "\tm: view media objects buffering and memory info\n" "\td: dumps scene graph\n" "\n" - "\tC: Enable Streaming Cache\n" - "\tS: Stops Streaming Cache and save to file\n" - "\tA: Aborts Streaming Cache\n" - "\n" "\tk: turns stress mode on/off\n" "\tn: changes navigation mode\n" "\tx: reset to last active viewpoint\n" "\n" - "\t2: restart using 2D compositor\n" - "\t3: restart using 3D compositor\n" + "\t3: switch OpenGL on or off for 2D scenes\n" "\n" "\t4: forces 4/3 Aspect Ratio\n" "\t5: forces 16/9 Aspect Ratio\n" @@ -240,10 +255,19 @@ void PrintHelp() "\n" "\tl: list available modules\n" "\tc: prints some GPAC configuration info\n" - "\tR: toggles run-time info display on/off\n" - "\tq: exit the application\n" + "\tE: forces reload of GPAC configuration\n" + "\n" + "\tR: toggles run-time info display in window title bar on/off\n" + "\tF: toggle displaying of FPS in stdout on/off\n" + "\tg: print GPAC allocated memory\n" "\th: print this message\n" "\n" + "\tEXPERIMENTAL/UNSTABLE OPTIONS\n" + "\tC: Enable Streaming Cache\n" + "\tS: Stops Streaming Cache and save to file\n" + "\tA: Aborts Streaming Cache\n" + "\tM: specifies video cache memory for 2D objects\n" + "\n" "MP4Client - GPAC command line player - version %s\n" "GPAC Written by Jean Le Feuvre (c) 2001-2005 - ENST (c) 2005-200X\n", @@ -251,195 +275,7 @@ void PrintHelp() ); } -GF_Config *create_default_config(char *file_path, char *file_name) -{ - GF_Config *cfg; - char szPath[GF_MAX_PATH]; - char gui_path[GF_MAX_PATH]; -#ifdef WIN32 - FILE *f; - Bool write_access = 0; - - strcpy(gui_path, file_path); - - /*following code is highly inspired by Osmo4*/ - /*do we have the write privileges on this dir ? if not, use user local data directory*/ - strcpy(szPath, file_path); - strcat(szPath, "GPAC.cfg"); - f = gf_f64_open(szPath, "wb"); - if (f != NULL) { - fclose(f); - write_access = 1; - } else { - write_access = 0; - } - strcpy(szPath, file_path); - - /*get GPAC.cfg path*/ - if (!write_access) { - char szPath2[GF_MAX_PATH]; - SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, file_path); - if (file_path[strlen((char *) file_path)-1] != '\\') strcat(file_path, "\\"); - strcat(file_path, "GPAC\\"); - /*create GPAC dir*/ - _mkdir(file_path); - strcpy(szPath2, file_path); - strcat(szPath2, "GPAC.cfg"); - f = gf_f64_open(szPath2, "wb"); - assert(f); - if (!f) return NULL; - fclose(f); - } -#else - FILE *f; - strcpy(gui_path, ""); - - sprintf(szPath, "%s%c%s", file_path, GF_PATH_SEPARATOR, file_name); - f = gf_f64_open(szPath, "wt"); - fprintf(stdout, "create %s: %s\n", szPath, (f==NULL) ? "Error" : "OK"); - if (!f) return NULL; - fclose(f); -#endif - - cfg = gf_cfg_new(file_path, file_name); - if (!cfg) return NULL; - -#if defined(WIN32) - //szPath still contains the executable directory -#elif defined(GPAC_MODULES_PATH) /* Mac OS and UNIX */ - fprintf(stdout, "Using module directory %s \n", GPAC_MODULES_PATH); - strcpy(szPath, GPAC_MODULES_PATH); -#else - fprintf(stdout, "Please enter full path to GPAC modules directory:\n"); - while ( 1 > scanf("%s", szPath)); -#endif - gf_cfg_set_key(cfg, "General", "ModulesDirectory", szPath); - gf_cfg_set_key(cfg, "Compositor", "Raster2D", "GPAC 2D Raster"); - gf_cfg_set_key(cfg, "Audio", "ForceConfig", "yes"); - gf_cfg_set_key(cfg, "Audio", "NumBuffers", "2"); - gf_cfg_set_key(cfg, "Audio", "TotalDuration", "120"); - gf_cfg_set_key(cfg, "Audio", "DisableNotification", "no"); - gf_cfg_set_key(cfg, "FontEngine", "FontReader", "ft_font"); - -#ifdef WIN32 - GetWindowsDirectory((char*)szPath, MAX_PATH); - if (szPath[strlen((char*)szPath)-1] != '\\') strcat((char*)szPath, "\\"); - strcat((char *)szPath, "Fonts"); -#elif defined(__DARWIN__) || defined(__APPLE__) - strcpy(szPath, "/Library/Fonts"); -#else - strcpy(szPath, "/usr/share/fonts/truetype/"); -#endif - fprintf(stdout, "Using default font directory %s\n", szPath); - gf_cfg_set_key(cfg, "FontEngine", "FontDirectory", szPath); - - { - char * tmp = gf_get_default_cache_directory(); - gf_cfg_set_key(cfg, "General", "CacheDirectory", tmp); - fprintf(stdout, "Using default cache directory %s\n", tmp); - gf_free(tmp); - } - - gf_cfg_set_key(cfg, "Downloader", "CleanCache", "yes"); - gf_cfg_set_key(cfg, "Compositor", "AntiAlias", "All"); - gf_cfg_set_key(cfg, "Compositor", "FrameRate", "30"); - /*use power-of-2 emulation*/ - gf_cfg_set_key(cfg, "Compositor", "EmulatePOW2", "yes"); -#ifdef WIN32 - gf_cfg_set_key(cfg, "Compositor", "ScalableZoom", "yes"); - gf_cfg_set_key(cfg, "Video", "DriverName", "DirectX Video Output"); -#elif defined(__DARWIN__) - gf_cfg_set_key(cfg, "Video", "DriverName", "SDL Video Output"); - /*SDL not so fast with scalable zoom*/ - gf_cfg_set_key(cfg, "Compositor", "ScalableZoom", "no"); -#else - gf_cfg_set_key(cfg, "Video", "DriverName", "X11 Video Output"); - /*x11 only supports scalable zoom*/ - gf_cfg_set_key(cfg, "Compositor", "ScalableZoom", "yes"); - gf_cfg_set_key(cfg, "Audio", "DriverName", "SDL Audio Output"); -#endif - - gf_cfg_set_key(cfg, "Video", "SwitchResolution", "no"); - gf_cfg_set_key(cfg, "Network", "AutoReconfigUDP", "yes"); - gf_cfg_set_key(cfg, "Network", "UDPTimeout", "10000"); - gf_cfg_set_key(cfg, "Network", "BufferLength", "3000"); - -#if defined(__DARWIN__) || defined(__APPLE__) - gf_cfg_set_key(cfg, "Video", "DriverName", "SDL Video Output"); -#endif - - if (gui_path[0]) { - FILE *f; - strcat(gui_path, "gui/gui.bt"); - f = fopen(gui_path, "rt"); - if (f) { - fclose(f); - gf_cfg_set_key(cfg, "General", "StartupFile", gui_path); - } - } - - - /*store and reload*/ - gf_cfg_del(cfg); - return gf_cfg_new(file_path, file_name); -} - -#if (defined(__DARWIN__) || defined(__APPLE__) ) -#include -#endif /* Apple, needs this for _NSGetExecutablePath on Mac OS X */ - -static void check_config_directories(GF_Config *cfg) -{ -#if (defined(__DARWIN__) || defined(__APPLE__) ) - char mod_path[GF_MAX_PATH]; - char gui_path[GF_MAX_PATH]; - char root_path[GF_MAX_PATH]; - char *sep; - const char *opt; - u32 size = GF_MAX_PATH; - if (_NSGetExecutablePath(root_path, &size)!=0) return; - /*installed or symlink on system, do not attempt to modify the path*/ - if (!strnicmp(root_path, "/usr/", 5)) return; - sep = strstr(root_path, ".app/"); - if (sep) { - sep[4] = 0; - } - gui_path[0] = '\0'; - strcpy(mod_path, root_path); - strcat(mod_path, "/Contents/MacOS/modules/"); - { - struct stat buf; - int status_dir; - memset(&buf, 0, sizeof(struct stat)); - status_dir = stat(mod_path, &buf); - if (!status_dir){ - if (!(buf.st_mode & S_IFDIR)){ -#ifdef GPAC_MODULES_PATH - strcpy(mod_path, GPAC_MODULES_PATH); - gui_path[0] = '\0'; -#endif - } else { - /* OK, it means we are in an .app directory ! */ - strcpy(gui_path, root_path); - strcat(gui_path, "/Contents/MacOS/gui/gui.bt"); - } - } else { -#ifdef GPAC_MODULES_PATH - strcpy(mod_path, GPAC_MODULES_PATH); - gui_path[0] = '\0'; -#endif - } - } - opt = gf_cfg_get_key(cfg, "General", "ModulesDirectory"); - /*modules directory has changed, forced to new location*/ - if (!opt || strcmp(opt, mod_path)) { - gf_cfg_set_key(cfg, "General", "ModulesDirectory", mod_path); - if (gui_path[0]) - gf_cfg_set_key(cfg, "General", "StartupFile", gui_path); - } -#endif -} static void PrintTime(u64 time) @@ -455,7 +291,6 @@ static void PrintTime(u64 time) static u32 rti_update_time_ms = 200; static FILE *rti_logs = NULL; -static u64 memory_at_gpac_startup = 0; static void UpdateRTInfo(const char *legend) { @@ -468,9 +303,6 @@ static void UpdateRTInfo(const char *legend) if (display_rti) { char szMsg[1024]; - if (!rti.process_memory) rti.process_memory = (u32) (memory_at_gpac_startup-rti.physical_memory_avail); - if (!rti.gpac_memory) rti.gpac_memory = (u32) (memory_at_gpac_startup-rti.physical_memory_avail); - if (rti.total_cpu_usage) { sprintf(szMsg, "FPS %02.2f - CPU %02d (%02d) - Mem %d kB", @@ -634,23 +466,23 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) { const char *servName; if (!evt->message.service || !strcmp(evt->message.service, the_url)) { - servName = "main service"; - } else if (!strnicmp(evt->message.service, "data:", 5)) { servName = ""; + } else if (!strnicmp(evt->message.service, "data:", 5)) { + servName = "(embedded data)"; } else { servName = evt->message.service; } - servName = ""; if (!evt->message.message) return 0; + if (evt->message.error==GF_SCRIPT_INFO) { GF_LOG(GF_LOG_INFO, GF_LOG_SCRIPT, ("[Script] %s\n", evt->message.message)); - fprintf(stdout, "%s\n", evt->message.message); } else if (evt->message.error) { if (!is_connected) last_error = evt->message.error; - fprintf(stdout, "%s (%s): %s\n", evt->message.message, servName, gf_error_to_string(evt->message.error)); + GF_LOG(GF_LOG_ERROR, GF_LOG_ALL, ("%s %s: %s\n", evt->message.message, servName, gf_error_to_string(evt->message.error))); } else if (!be_quiet) - fprintf(stdout, "(%s) %s\r", servName, evt->message.message); + /*TODO: put a GF_LOG here*/ + fprintf(stdout, "%s %s\r", evt->message.message, servName); } break; case GF_EVENT_PROGRESS: @@ -818,6 +650,32 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) ResetCaption(); break; + case GF_EVENT_OPENFILE: + { + u32 i, pos; + /*todo - force playlist mode*/ + if (readonly_playlist) { + fclose(playlist); + playlist = NULL; + } + readonly_playlist = 0; + if (!playlist) { + readonly_playlist = 0; + playlist = gf_temp_file_new(); + } + pos = ftell(playlist); + i=0; + while (iopen_file.nb_files) { + if (evt->open_file.files[i] != NULL) { + fprintf(playlist, "%s\n", evt->open_file.files[i]); + } + i++; + } + fseek(playlist, pos, SEEK_SET); + request_next_playlist_item = 1; + } + return 1; + case GF_EVENT_QUIT: Run = 0; break; @@ -870,69 +728,6 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) return 0; } -GF_Config *loadconfigfile(char *filepath) -{ - GF_Config *cfg = NULL; - char *cfg_dir; - char szPath[GF_MAX_PATH]; - - if (filepath) { - strcpy(szPath, filepath); - cfg_dir = strrchr(szPath, '\\'); - if (!cfg_dir) cfg_dir = strrchr(szPath, '/'); - if (cfg_dir) { - char c = cfg_dir[0]; - cfg_dir[0] = 0; - cfg = gf_cfg_new(cfg_dir, cfg_dir+1); - cfg_dir[0] = c; - if (cfg) goto success; - } else { - cfg = gf_cfg_new(".", filepath); - if (cfg) goto success; - } - } - -#ifdef WIN32 - GetModuleFileNameA(NULL, szPath, GF_MAX_PATH); - cfg_dir = strrchr(szPath, '\\'); - if (cfg_dir) cfg_dir[1] = 0; - - cfg = gf_cfg_new(szPath, "GPAC.cfg"); - if (cfg) goto success; - strcpy(szPath, "."); - cfg = gf_cfg_new(szPath, "GPAC.cfg"); - if (cfg) goto success; - strcpy(szPath, "."); - cfg = gf_cfg_new(szPath, "GPAC.cfg"); - if (cfg) goto success; - - GetModuleFileNameA(NULL, szPath, GF_MAX_PATH); - cfg_dir = strrchr(szPath, '\\'); - if (cfg_dir) cfg_dir[1] = 0; - cfg = create_default_config(szPath, "GPAC.cfg"); -#else - /*linux*/ - cfg_dir = getenv("HOME"); - if (cfg_dir) { - strcpy(szPath, cfg_dir); - } else { - fprintf(stdout, "WARNING: HOME env var not set - using current directory for config file\n"); - strcpy(szPath, "."); - } - cfg = gf_cfg_new(szPath, ".gpacrc"); - if (cfg) goto success; - fprintf(stdout, "GPAC config file not found in %s - creating new file\n", szPath); - cfg = create_default_config(szPath, ".gpacrc"); -#endif - if (!cfg) { - fprintf(stdout, "cannot create config file in %s directory\n", szPath); - return NULL; - } - success: - fprintf(stdout, "Using config file in %s directory\n", szPath); - check_config_directories(cfg); - return cfg; -} void list_modules(GF_ModuleManager *modules) { @@ -1068,7 +863,7 @@ int main (int argc, char **argv) char c; const char *str; u32 i, times[100], nb_times, dump_mode; - u32 simulation_time = 0; + u32 simulation_time_in_ms = 0; Bool auto_exit = 0; Bool logs_set = 0; Bool start_fs = 0; @@ -1077,12 +872,12 @@ int main (int argc, char **argv) Bool rgbd_dump = 0; Bool depth_dump = 0; Bool pause_at_first = 0; +#ifdef GPAC_MEMORY_TRACKING Bool enable_mem_tracker = 0; - Double fps = 25.0; +#endif + Double fps = GF_IMPORT_DEFAULT_FPS; Bool ret, fill_ar, visible; - char *url_arg, *the_cfg, *rti_file; - GF_SystemRTInfo rti; - FILE *playlist = NULL; + char *url_arg, *the_cfg, *rti_file, *views; FILE *logfile = NULL; Float scale = 1; #ifndef WIN32 @@ -1096,7 +891,7 @@ int main (int argc, char **argv) dump_mode = 0; fill_ar = visible = 0; - url_arg = the_cfg = rti_file = NULL; + url_arg = the_cfg = rti_file = views = NULL; nb_times = 0; times[0] = 0; @@ -1107,24 +902,32 @@ int main (int argc, char **argv) the_cfg = argv[i+1]; i++; } - else if (!strcmp(arg, "-mem-track")) enable_mem_tracker = 1; + else if (!strcmp(arg, "-mem-track")) { +#ifdef GPAC_MEMORY_TRACKING + enable_mem_tracker = 1; +#else + fprintf(stdout, "WARNING - GPAC not compiled with Memory Tracker - ignoring \"-mem-track\"\n"); +#endif + } else if (!strcmp(arg, "-h") || !strcmp(arg, "-help")) { PrintUsage(); return 1; } } +#ifdef GPAC_MEMORY_TRACKING gf_sys_init(enable_mem_tracker); +#else + gf_sys_init(0); +#endif - cfg_file = loadconfigfile(the_cfg); + cfg_file = gf_cfg_init(the_cfg, NULL); if (!cfg_file) { - fprintf(stdout, "Error: Configuration File \"GPAC.cfg\" not found\n"); + fprintf(stdout, "Error: Configuration File not found\n"); if (logfile) fclose(logfile); return 1; } - - for (i=1; i<(u32) argc; i++) { char *arg = argv[i]; // if (isalnum(arg[0]) || (arg[0]=='/') || (arg[0]=='.') || (arg[0]=='\\') ) { @@ -1192,16 +995,22 @@ int main (int argc, char **argv) i++; } else if (!strcmp(arg, "-quiet")) { be_quiet = 1; + } else if (!strcmp(arg, "-strict-error")) { + gf_log_set_strict_error(1); } else if (!strcmp(arg, "-log-file") || !strcmp(arg, "-lf")) { logfile = gf_f64_open(argv[i+1], "wt"); gf_log_set_callback(logfile, on_gpac_log); i++; } else if (!strcmp(arg, "-log-level") || !strcmp(arg, "-ll")) { - gf_log_set_level(gf_log_parse_level(argv[i+1])); + u32 flags = gf_log_parse_level(argv[i+1]); + if (!flags) return 1; + gf_log_set_level(flags); logs_set = 1; i++; } else if (!strcmp(arg, "-log-tools") || !strcmp(arg, "-lt")) { - gf_log_set_tools(gf_log_parse_tools(argv[i+1])); + u32 flags = gf_log_parse_tools(argv[i+1]); + if (!flags) return 1; + gf_log_set_tools(flags); logs_set = 1; i++; } else if (!strcmp(arg, "-log-clock") || !strcmp(arg, "-lc")) { @@ -1226,7 +1035,13 @@ int main (int argc, char **argv) else if (!strcmp(arg, "-fs")) start_fs = 1; else if (!strcmp(arg, "-pause")) pause_at_first = 1; else if (!strcmp(arg, "-exit")) auto_exit = 1; - else if (!strcmp(arg, "-mem-track")) enable_mem_tracker = 1; + else if (!strcmp(arg, "-mem-track")) { +#ifdef GPAC_MEMORY_TRACKING + enable_mem_tracker = 1; +#else + fprintf(stdout, "WARNING - GPAC not compiled with Memory Tracker - ignoring \"-mem-track\"\n"); +#endif + } else if (!strcmp(arg, "-loop")) loop_at_end = 1; else if (!strcmp(arg, "-opt")) { char *sep, *sep2, szSec[1024], szKey[1024], szVal[1024]; @@ -1247,7 +1062,16 @@ int main (int argc, char **argv) } i++; } - else if (!strncmp(arg, "-run-for=", 9)) simulation_time = atoi(arg+9); + else if (!stricmp(arg, "-views")) { + views = argv[i+1]; + i++; + } + else if (!stricmp(arg, "-run-for")) { + simulation_time_in_ms = atoi(argv[i+1]) * 1000; + if (!simulation_time_in_ms) + simulation_time_in_ms = 1; /*1ms*/ + i++; + } else if (!stricmp(arg, "-help")) { PrintUsage(); return 1; @@ -1255,13 +1079,15 @@ int main (int argc, char **argv) fprintf(stdout, "Unrecognized option %s - skipping\n", arg); } } - if (dump_mode && !url_arg) { + if (dump_mode && !url_arg ) { fprintf(stdout, "Missing argument for dump\n"); PrintUsage(); if (logfile) fclose(logfile); return 1; } + if (!url_arg && simulation_time_in_ms) + simulation_time_in_ms += gf_sys_clock(); if (!gui_mode) { str = gf_cfg_get_key(cfg_file, "General", "ForceGUI"); @@ -1284,8 +1110,6 @@ int main (int argc, char **argv) gf_log_set_tools(0xFFFFFFFF); } - gf_sys_get_rti(500, &rti, GF_RTI_SYSTEM_MEMORY_ONLY); - memory_at_gpac_startup = rti.physical_memory_avail; if (rti_file) init_rti_logs(rti_file, url_arg, use_rtix); /*setup dumping options*/ @@ -1380,7 +1204,8 @@ int main (int argc, char **argv) } else /*connect if requested*/ - if (!gui_mode && url_arg) { + if (views) { + } else if (!gui_mode && url_arg) { char *ext; strcpy(the_url, url_arg); @@ -1388,6 +1213,7 @@ int main (int argc, char **argv) if (ext && strncmp("http:", the_url, 5) && (!stricmp(ext, ".m3u") || !stricmp(ext, ".pls"))) { fprintf(stdout, "Opening Playlist %s\n", the_url); playlist = gf_f64_open(the_url, "rt"); + readonly_playlist = 1; if (playlist) { strcpy(pl_path, the_url); if (1 > fscanf(playlist, "%s", the_url)) @@ -1420,6 +1246,12 @@ int main (int argc, char **argv) if (start_fs) gf_term_set_option(term, GF_OPT_FULLSCREEN, 1); + if (views) { + char szTemp[4046]; + sprintf(szTemp, "views://%s", views); + gf_term_connect(term, szTemp); + } + while (Run) { /*we don't want getchar to block*/ if (gui_mode || !gf_prompt_has_input()) { @@ -1442,7 +1274,9 @@ int main (int argc, char **argv) gf_sleep(rti_update_time_ms); } /*sim time*/ - if (simulation_time && (gf_term_get_time_in_ms(term)>simulation_time)) { + if (simulation_time_in_ms + && ( (gf_term_get_time_in_ms(term)>simulation_time_in_ms) || (!url_arg && gf_sys_clock()>simulation_time_in_ms)) + ) { Run = 0; } continue; @@ -1737,24 +1571,34 @@ force_input: case 'L': { + u32 flags; char szLog[1024]; fprintf(stdout, "Enter new log level:\n"); if (1 > scanf("%s", szLog)){ fprintf(stderr, "Cannot read new log level, aborting.\n"); break; } - gf_log_set_level(gf_log_parse_level(szLog)); + flags = gf_log_parse_level(szLog); + if (!flags) + fprintf(stderr, "Wrong log level specified, aborting.\n"); + else + gf_log_set_level(flags); } break; case 'T': { + u32 flags; char szLog[1024]; fprintf(stdout, "Enter new log tools:\n"); - if (1 > scanf("%s", szLog)){ + if (1 > scanf("%s", szLog)) { fprintf(stderr, "Cannot read new log tools, aborting.\n"); break; } - gf_log_set_tools(gf_log_parse_tools(szLog)); + flags = gf_log_parse_tools(szLog); + if (!flags) + fprintf(stderr, "Wrong log tools specified, aborting.\n"); + else + gf_log_set_tools(flags); } break; case 'g': @@ -1785,31 +1629,63 @@ force_input: /*extract to PNG*/ case 'Z': { + char szFileName[100]; + u32 nb_pass, nb_views, offscreen_view = 0; GF_VideoSurface fb; GF_Err e; - e = gf_term_get_screen_buffer(term, &fb); - if (e) { - fprintf(stdout, "Error dumping screen buffer %s\n", gf_error_to_string(e) ); - } else { - u32 dst_size = fb.width*fb.height*3; - char *dst = (char*)gf_malloc(sizeof(char)*dst_size); - - e = gf_img_png_enc(fb.video_buffer, fb.width, fb.height, fb.pitch_y, fb.pixel_format, dst, &dst_size); + nb_pass = 1; + nb_views = gf_term_get_option(term, GF_OPT_NUM_STEREO_VIEWS); + if (nb_views>1) { + fprintf(stdout, "Auto-stereo mode detected - type number of view to dump (0 is main output, 1 to %d offscreen view, %d for all offscreen, %d for all offscreen and main)\n", nb_views, nb_views+1, nb_views+2); + if (scanf("%d", &offscreen_view) != 1) { + offscreen_view = 0; + } + if (offscreen_view==nb_views+1) { + offscreen_view = 1; + nb_pass = nb_views; + } + else if (offscreen_view==nb_views+2) { + offscreen_view = 0; + nb_pass = nb_views+1; + } + } + while (nb_pass) { + nb_pass--; + if (offscreen_view) { + sprintf(szFileName, "view%d_dump.png", offscreen_view); + e = gf_term_get_offscreen_buffer(term, &fb, offscreen_view-1, 0); + } else { + sprintf(szFileName, "video_dump.png"); + e = gf_term_get_screen_buffer(term, &fb); + } + offscreen_view++; if (e) { - fprintf(stdout, "Error encoding PNG %s\n", gf_error_to_string(e) ); + fprintf(stdout, "Error dumping screen buffer %s\n", gf_error_to_string(e) ); + nb_pass = 0; } else { - FILE *png = gf_f64_open("dump.png", "wb"); - if (!png) { - fprintf(stdout, "Error writing file dump.png\n"); + u32 dst_size = fb.width*fb.height*4; + char *dst = (char*)gf_malloc(sizeof(char)*dst_size); + + e = gf_img_png_enc(fb.video_buffer, fb.width, fb.height, fb.pitch_y, fb.pixel_format, dst, &dst_size); + if (e) { + fprintf(stdout, "Error encoding PNG %s\n", gf_error_to_string(e) ); + nb_pass = 0; } else { - fwrite(dst, dst_size, 1, png); - fclose(png); - fprintf(stdout, "Writing file dump.png\n"); + FILE *png = gf_f64_open(szFileName, "wb"); + if (!png) { + fprintf(stdout, "Error writing file %s\n", szFileName); + nb_pass = 0; + } else { + fwrite(dst, dst_size, 1, png); + fclose(png); + fprintf(stdout, "Dump to %s\n", szFileName); + } } + if (dst) gf_free(dst); + gf_term_release_screen_buffer(term, &fb); } - if (dst) gf_free(dst); - gf_term_release_screen_buffer(term, &fb); } + fprintf(stdout, "Done: %s\n", szFileName); } break; @@ -1833,16 +1709,6 @@ force_input: gf_modules_del(user.modules); gf_cfg_del(cfg_file); -#ifdef GPAC_MEMORY_TRACKING - if (enable_mem_tracker) { - gf_memory_print(); - fprintf(stdout, "print any key\n"); - while (!gf_prompt_has_input()) { - gf_sleep(100); - } - } -#endif - gf_sys_close(); if (rti_logs) fclose(rti_logs); if (logfile) fclose(logfile); @@ -1854,8 +1720,6 @@ force_input: } - - void PrintWorldInfo(GF_Terminal *term) { u32 i; @@ -1887,6 +1751,11 @@ void PrintODList(GF_Terminal *term, GF_ObjectManager *root_odm, u32 num, u32 ind root_odm = gf_term_get_root_object(term); } if (!root_odm) return; + + count = gf_term_get_current_service_id(term); + if (count) + fprintf(stdout, "Current service ID %d\n", count); + if (gf_term_get_object_info(term, root_odm, &odi) != GF_OK) return; if (!odi.od) { fprintf(stdout, "Service not attached\n"); @@ -1898,6 +1767,7 @@ void PrintODList(GF_Terminal *term, GF_ObjectManager *root_odm, u32 num, u32 ind fprintf(stdout, "%s", szIndent); fprintf(stdout, "#%d %s - ", num, root_name); + if (odi.od->ServiceID) fprintf(stdout, "Service ID %d ", odi.od->ServiceID); if (odi.media_url) { fprintf(stdout, "%s\n", odi.media_url); } else { @@ -1932,7 +1802,9 @@ void PrintODList(GF_Terminal *term, GF_ObjectManager *root_odm, u32 num, u32 ind } else { fprintf(stdout, "ID %d", odi.od->objectDescriptorID); } - fprintf(stdout, " - %s\n", (odi.od_type==GF_STREAM_VISUAL) ? "Video" : (odi.od_type==GF_STREAM_AUDIO) ? "Audio" : "Systems"); + fprintf(stdout, " - %s", (odi.od_type==GF_STREAM_VISUAL) ? "Video" : (odi.od_type==GF_STREAM_AUDIO) ? "Audio" : "Systems"); + if (odi.od && odi.od->ServiceID) fprintf(stdout, " - Service ID %d", odi.od->ServiceID); + fprintf(stdout, "\n"); break; } } diff --git a/applications/mp4client/resource.h b/applications/mp4client/resource.h index 2b88c52..deb8163 100644 --- a/applications/mp4client/resource.h +++ b/applications/mp4client/resource.h @@ -1,18 +1,18 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by mp4client.rc -// -#define IDI_ICON1 102 -#define IDI_ICON2 103 -#define IDI_ICON3 105 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 106 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by mp4client.rc +// +#define IDI_ICON1 102 +#define IDI_ICON2 103 +#define IDI_ICON3 105 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 106 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/applications/osmo4_android/AndroidManifest.xml b/applications/osmo4_android/AndroidManifest.xml index b0d3ccf..44cb2a8 100644 --- a/applications/osmo4_android/AndroidManifest.xml +++ b/applications/osmo4_android/AndroidManifest.xml @@ -1,5 +1,5 @@ - diff --git a/applications/osmo4_android/Osmo4_keystore b/applications/osmo4_android/Osmo4_keystore new file mode 100644 index 0000000..d504ce3 Binary files /dev/null and b/applications/osmo4_android/Osmo4_keystore differ diff --git a/applications/osmo4_android/build.properties b/applications/osmo4_android/build.properties new file mode 100644 index 0000000..b392a8a --- /dev/null +++ b/applications/osmo4_android/build.properties @@ -0,0 +1,4 @@ +key.store=Osmo4_keystore +key.alias=Osmo4_androidkey +key.store.password=SkSlJ404 +key.alias.password=android \ No newline at end of file diff --git a/applications/osmo4_android/jni/wrapper-bitmap-20-09-2010.cpp b/applications/osmo4_android/jni/wrapper-bitmap-20-09-2010.cpp deleted file mode 100644 index b6fda33..0000000 --- a/applications/osmo4_android/jni/wrapper-bitmap-20-09-2010.cpp +++ /dev/null @@ -1,960 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) ENST 2009- - * Authors: Jean Le Feuvre - * All rights reserved - * - * Created by NGO Van Luyen, Ivica ARSOV / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010 - * - * This file is part of GPAC / Wrapper - * - * 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 - -#include -#include -#include -#include -#include -#include - -#include "wrapper.h" - -#include - -#undef PI -#define PI 3.1415926535897932f - -#include -#ifndef ANDROID_NDK -//#include -#endif /* !ANDROID_NDK */ -//--------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------- -//CPeriodic -//------------------------------- -CPeriodic::CPeriodic(){} -//------------------------------- -CPeriodic::~CPeriodic(){} -//------------------------------- -void CPeriodic::Start(){ -} -//------------------------------- -void CPeriodic::Cancel(){} -//--------------------------------------------------------------------------------------------------- - -void initGL() -{ - /* Enable smooth shading */ - glShadeModel(GL_SMOOTH); - - /* Set the background black */ - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - - /* Depth buffer setup */ - glClearDepthf(1.0f); - - /* Enables Depth Testing */ - glEnable(GL_DEPTH_TEST); - - /* The Type Of Depth Test To Do */ - glDepthFunc(GL_LEQUAL); - - /* Really Nice Perspective Calculations */ - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); -} - -void gluPerspective(GLfloat fovy, GLfloat aspect, - GLfloat zNear, GLfloat zFar) -{ - GLfloat xmin, xmax, ymin, ymax; - - ymax = zNear * (GLfloat)tan(fovy * PI / 360); - ymin = -ymax; - xmin = ymin * aspect; - xmax = ymax * aspect; - - glFrustumx((GLfixed)(xmin * 65536), (GLfixed)(xmax * 65536), - (GLfixed)(ymin * 65536), (GLfixed)(ymax * 65536), - (GLfixed)(zNear * 65536), (GLfixed)(zFar * 65536)); -} - -void resizeWindow(int width, int height) -{ - /* Height / width ration */ - GLfloat ratio; - - /* Protect against a divide by zero */ - if (height==0) - { - height=1; - } - - ratio=(GLfloat)width/(GLfloat)height; - - /* Setup our viewport. */ - glViewport(0, 0, (GLsizei)width, (GLsizei)height); - - /* change to the projection matrix and set our viewing volume. */ - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - /* Set our perspective */ - gluPerspective(45.0f, ratio, 0.1f, 100.0f); - - /* Make sure we're chaning the model view and not the projection */ - glMatrixMode(GL_MODELVIEW); - - /* Reset The View */ - glLoadIdentity(); -} - -void drawGLScene() -{ - GLfloat vertices[4][3]; - - /* Clear The Screen And The Depth Buffer */ - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - /* Enable VERTEX array */ - glEnableClientState(GL_VERTEX_ARRAY); - - /* Setup pointer to VERTEX array */ - glVertexPointer(3, GL_FLOAT, 0, vertices); - - /* Move Left 1.5 Units And Into The Screen 6.0 */ - glLoadIdentity(); - glTranslatef(-1.5f, 0.0f, -6.0f); - - /* Top Of Triangle */ - vertices[0][0]=0.0f; vertices[0][1]=1.0f; vertices[0][2]=0.0f; - /* Left Of Triangle */ - vertices[1][0]=-1.0f; vertices[1][1]=-1.0f; vertices[1][2]=0.0f; - /* Right Of Triangle */ - vertices[2][0]=1.0f; vertices[2][1]=-1.0f; vertices[2][2]=0.0f; - - /* Drawing Using Triangles, draw triangles using 3 vertices */ - glDrawArrays(GL_TRIANGLES, 0, 3); - - /* Move Right 3 Units */ - glLoadIdentity(); - glTranslatef(1.5f, 0.0f, -6.0f); - - /* Top Right Of The Quad */ - vertices[0][0]=1.0f; vertices[0][1]=1.0f; vertices[0][2]=0.0f; - /* Top Left Of The Quad */ - vertices[1][0]=-1.0f; vertices[1][1]=1.0f; vertices[1][2]=0.0f; - /* Bottom Left Of The Quad */ - vertices[2][0]=1.0f; vertices[2][1]=-1.0f; vertices[2][2]=0.0f; - /* Bottom Right Of The Quad */ - vertices[3][0]=-1.0f; vertices[3][1]=-1.0f; vertices[3][2]=0.0f; - - /* Drawing using triangle strips, draw triangles using 4 vertices */ - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - /* Disable vertex array */ - glDisableClientState(GL_VERTEX_ARRAY); - - /* Flush all drawings */ - glFinish(); -} - -//--------------------------------------------------------------------------------------------------- -//CNativeWrapper -//------------------------------- -CNativeWrapper::CNativeWrapper(){ - do_log = 1; - logfile = NULL; - - m_pTimer = NULL; -#ifndef GPAC_GUI_ONLY - memset(&m_user, 0, sizeof(GF_User)); - m_term = NULL; - m_mx = NULL; - memset(&m_rti, 0, sizeof(GF_SystemRTInfo)); -#endif - -#ifdef DEBUG_MODE - debug_f = fopen(DEBUG_FILE, "w"); -#endif -} -//------------------------------- -CNativeWrapper::~CNativeWrapper(){ - Shutdown(); - - if (logfile) fclose(logfile); - -#ifdef DEBUG_MODE - if (debug_f){ - debug_log("~CNativeWrapper()\n"); - fclose(debug_f); - } - -#endif -} -//------------------------------- -void CNativeWrapper::debug_log(const char* msg){ -#ifdef DEBUG_MODE - fprintf(debug_f, "%s\n", msg); - fflush(debug_f); -#endif -} -//------------------------------- -void CNativeWrapper::Shutdown() -{ - - if (m_mx) gf_mx_del(m_mx); - - MessageBox("Osmo4 shutdown request", ""); - if (m_pTimer) { - m_pTimer->Cancel(); - delete m_pTimer; - m_pTimer = NULL; - } -#ifndef GPAC_GUI_ONLY - if (m_term) { - GF_Terminal *t = m_term; - m_term = NULL; - gf_term_del(t); - } - if (m_user.config) { - gf_cfg_del(m_user.config); - m_user.config = NULL; - } - if (m_user.modules) { - gf_modules_del(m_user.modules); - m_user.modules = NULL; - } -#endif - MessageBox("Osmo4 shutdown OK", ""); -} -//------------------------------- -int CNativeWrapper::MessageBox(const char* msg, const char* title){ - //call java function to display a message box - - debug_log(msg); - - return 1; -} -//------------------------------- -int CNativeWrapper::OnTick(){ -#ifndef GPAC_GUI_ONLY - if (m_term) gf_term_process_step(m_term); - - /*check RTI display*/ - //if (show_rti && gf_sys_get_rti(500, &m_rti, 0)) DisplayRTI(); -#endif - /*never stop...*/ - return 1; -} -//------------------------------- -void CNativeWrapper::DisplayRTI(){ -#ifndef GPAC_GUI_ONLY - // display some system informations ? -#endif -} -//------------------------------- -int CNativeWrapper::Quit(int code){ - - Shutdown(); - // send shutdown request to java - return code; -} -//------------------------------- -void CNativeWrapper::on_gpac_log(void *cbk, u32 ll, u32 lm, const char *fmt, va_list list){ - // do log here - FILE *logs = (FILE*)cbk; - - /*if (rti_logs && (lm & GF_LOG_RTI)) { - char szMsg[2048]; - vsprintf(szMsg, fmt, list); - UpdateRTInfo(szMsg + 6 ); - } else { - if (log_time_start) fprintf(logs, "[At %d]", gf_sys_clock() - log_time_start); - vfprintf(logs, fmt, list); - fflush(logs); - }*/ - - vfprintf(logs, fmt, list); - fflush(logs); - -} -//------------------------------- -Bool CNativeWrapper::GPAC_EventProc(void *ptr, GF_Event *evt){ - //event - return true; -} -//------------------------------- -void CNativeWrapper::Osmo4_progress_cbk(void *usr, char *title, u32 done, u32 total){ - -} -//------------------------------- -void CNativeWrapper::SetupLogs(){ - const char *opt; - debug_log("SetupLogs()"); - -//#ifndef GPAC_GUI_ONLY - gf_mx_p(m_mx); - if (do_log) { - gf_log_set_level(0); - do_log = 0; - } - /*setup GPAC logs: log all errors*/ - gf_log_set_level(GF_LOG_DEBUG); - gf_log_set_tools(0xFFFFFFFF); - opt = gf_cfg_get_key(m_user.config, "General", "LogLevel"); - if ((opt && !stricmp(opt, "debug")) /*|| 1*/) { - FILE *logs = fopen(GPAC_LOG_FILE, "wt"); - if (!logs) { - MessageBox("Cannot open log file - disabling logs", "Warning !"); - } else { - MessageBox("Debug log enabled in \\data\\gpac_logs.txt", "Info"); - fclose(logs); - do_log = 1; - gf_log_set_level(GF_LOG_DEBUG); - gf_log_set_tools(0xFFFFFFFF); - } - } - if (!do_log) { - gf_log_set_level(GF_LOG_ERROR); - gf_log_set_tools(0xFFFFFFFF); - } - - - gf_log_set_level(GF_LOG_DEBUG); - gf_log_set_tools(0xFFFFFFFF); - - logfile = fopen(GPAC_LOG_FILE, "wt"); - - gf_log_set_callback(logfile, on_gpac_log); - gf_mx_v(m_mx); - - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Osmo4 logs initialized\n")); -//#endif -} -//------------------------------- -int CNativeWrapper::init(JNIEnv * env, jobject * bitmap){ - - debug_log("int CNativeWrapper::init()"); - - int m_Width = 100, m_Height = 100; - - int first_launch = 0; - const char *opt; - - m_window = env; - m_session = bitmap; - - m_mx = gf_mx_new("Osmo4"); - - //load config file - m_user.config = gf_cfg_new(GPAC_CFG_DIR, "GPAC.cfg"); - if (!m_user.config) { - first_launch = 1; - FILE *ft = fopen(GPAC_CFG_DIR"GPAC.cfg", "wt"); - if (!ft) { - MessageBox("Cannot create GPAC Config file", "Fatal Error"); - return Quit(KErrGeneral); - } else { - fclose(ft); - } - m_user.config = gf_cfg_new(GPAC_CFG_DIR, "GPAC.cfg"); - if (!m_user.config) { - MessageBox("GPAC Configuration file not found", "Fatal Error"); - return Quit(KErrGeneral); - } - } - - SetupLogs(); - gf_set_progress_callback(this, Osmo4_progress_cbk); - - opt = gf_cfg_get_key(m_user.config, "General", "ModulesDirectory"); - if (!opt) first_launch = 2; - - if (first_launch) { - /*hardcode module directory*/ - gf_cfg_set_key(m_user.config, "General", "ModulesDirectory", GPAC_MODULES_DIR); - /*hardcode cache directory*/ - gf_cfg_set_key(m_user.config, "General", "CacheDirectory", GPAC_CACHE_DIR); - gf_cfg_set_key(m_user.config, "Downloader", "CleanCache", "yes"); - /*startup file*/ - //gf_cfg_set_key(m_user.config, "General", "StartupFile", GPAC_CFG_DIR"gpac.mp4"); - /*setup UDP traffic autodetect*/ - gf_cfg_set_key(m_user.config, "Network", "AutoReconfigUDP", "yes"); - gf_cfg_set_key(m_user.config, "Network", "UDPTimeout", "10000"); - gf_cfg_set_key(m_user.config, "Network", "BufferLength", "3000"); - - gf_cfg_set_key(m_user.config, "Compositor", "TextureTextMode", "Default"); - //gf_cfg_set_key(m_user.config, "Compositor", "FrameRate", "30"); - - gf_cfg_set_key(m_user.config, "Video", "DriverName", "Android Video Output"); - - gf_cfg_set_key(m_user.config, "FontEngine", "FontReader", "ft_font"); - - gf_cfg_set_key(m_user.config, "FontEngine", "FontDirectory", GPAC_FONT_DIR); - - - /*save cfg and reload*/ - gf_cfg_del(m_user.config); - m_user.config = gf_cfg_new(GPAC_CFG_DIR, "GPAC.cfg"); - if (!m_user.config) { - MessageBox("Cannot save initial GPAC Config file", "Fatal Error"); - return Quit(KErrGeneral); - } - - - MessageBox("Osmo4", "Thank you for Installing"); - } - - /*load modules*/ - opt = gf_cfg_get_key(m_user.config, "General", "ModulesDirectory"); - m_user.modules = gf_modules_new(opt, m_user.config); - if (!m_user.modules || !gf_modules_get_count(m_user.modules)) { - MessageBox(m_user.modules ? "No modules available" : "Cannot create module manager", "Fatal Error"); - if (m_user.modules) gf_modules_del(m_user.modules); - gf_cfg_del(m_user.config); - return Quit(KErrGeneral); - } - - if (first_launch) { - /*first launch, register all files ext*/ - for (u32 i=0; iCanHandleURL(ifce, "test.test"); - gf_modules_close_interface((GF_BaseInterface *)ifce); - } - } - } - - /*we don't thread the terminal, ie appart from the audio renderer, media decoding and visual rendering is - handled by the app process*/ - m_user.init_flags = GF_TERM_NO_THREAD | GF_TERM_NO_REGULATION; - m_user.init_flags |= GF_TERM_NO_AUDIO; - m_user.EventProc = GPAC_EventProc; - m_user.opaque = this; - m_user.os_window_handler = m_window; - m_user.os_display = m_session; - - m_term = gf_term_new(&m_user); - if (!m_term) { - MessageBox("Cannot load GPAC terminal", "Fatal Error"); - gf_modules_del(m_user.modules); - gf_cfg_del(m_user.config); - return Quit(KErrGeneral); - } - MessageBox("GPAC terminal loaded", "Success !"); - - gf_term_set_size(m_term, m_Width, m_Height); - - m_pTimer = new CPeriodic(); - m_pTimer->Start(); - - opt = gf_cfg_get_key(m_user.config, "General", "StartupFile"); - //if (opt) gf_term_connect(m_term, opt); - - //initGL(); -} -//------------------------------- -int CNativeWrapper::connect(const char *url){ - /*debug_log("Starting to connect ..."); - - gf_term_connect_from_time(m_term, url, 0, false); - //gf_term_connect(m_term, url); - - debug_log("connected ...");*/ - - char pl_path[GF_MAX_PATH]; - - strcpy(pl_path, url); - - debug_log("Connecting to ..."); - debug_log(pl_path); - - //gf_term_connect_with_path(m_term, url, pl_path); - gf_term_connect(m_term, url); - debug_log("connected ..."); -} -//----------------------------------------------------- -void CNativeWrapper::disconnect(){ - - gf_term_disconnect(m_term); - debug_log("disconnected ..."); -} -//----------------------------------------------------- -void CNativeWrapper::step(JNIEnv * env, jobject * bitmap){ - m_window = env; - m_session = bitmap; - debug_log("Step ..."); - if (!m_term) - debug_log("m_term ..."); - else - if (!m_term->compositor) - debug_log("compositor ..."); - else - if (!m_term->compositor->video_out) - debug_log("video_out ..."); - else - if (!m_term->compositor->video_out->Setup) - debug_log("Setup ..."); - else - { - debug_log("Video Setup ..."); - m_term->compositor->video_out->Setup(m_term->compositor->video_out, m_window, m_session, -1); - } - gf_term_process_step(m_term); - //drawGLScene(); -} -//----------------------------------------------------- -void CNativeWrapper::resize(int w, int h){ - gf_term_set_size(m_term, w, h); - //resizeWindow(w,h); -} -//----------------------------------------------------- -void CNativeWrapper::onMouseDown(float x, float y){ - char msg[100]; - sprintf(msg, "onMousedown x=%f, y=%f", x, y ); - debug_log(msg); - - GF_Event evt; - evt.type = GF_EVENT_MOUSEDOWN; - evt.mouse.button = GF_MOUSE_LEFT; - evt.mouse.x = x; - evt.mouse.y = y; - - int ret = gf_term_user_event(m_term, &evt); -} -//----------------------------------------------------- -void CNativeWrapper::onMouseUp(float x, float y){ - char msg[100]; - sprintf(msg, "onMouseUp x=%f, y=%f", x, y ); - debug_log(msg); - - GF_Event evt; - evt.type = GF_EVENT_MOUSEUP; - evt.mouse.button = GF_MOUSE_LEFT; - evt.mouse.x = x; - evt.mouse.y = y; - - int ret = gf_term_user_event(m_term, &evt); -} -//----------------------------------------------------- -void CNativeWrapper::onKeyPress(int keycode, int rawkeycode, int up, int flag){ - GF_Event evt; - if (up == 0) evt.type = GF_EVENT_KEYUP; - else evt.type = GF_EVENT_KEYDOWN; - - evt.key.flags = 0; - evt.key.hw_code = rawkeycode; - - char msg[100]; - sprintf(msg, "onKeyPress keycode=%d", keycode); - debug_log(msg); - - //translate_key(keycode, &evt.key); - evt.key.key_code = GF_KEY_A; - int ret = gf_term_user_event(m_term, &evt); - /*generate a key up*/ - - sprintf(msg, "onKeyPress gpac keycode=%d, GF_KEY_A=%d, ret=%d", evt.key.key_code, GF_KEY_A, ret); - debug_log(msg); -} -//----------------------------------------------------- -void CNativeWrapper::translate_key(ANDROID_KEYCODE keycode, GF_EventKey *evt){ - evt->flags = 0; - - char msg[100]; - sprintf(msg, "translate_key keycode=%d", keycode); - debug_log(msg); - - switch (keycode) { - case ANDROID_KEYCODE_BACK: evt->key_code = GF_KEY_BACKSPACE; break; - case ANDROID_KEYCODE_TAB: evt->key_code = GF_KEY_TAB; break; - case ANDROID_KEYCODE_CLEAR: evt->key_code = GF_KEY_CLEAR; break; - case ANDROID_KEYCODE_ENTER: evt->key_code = GF_KEY_ENTER; break; - case ANDROID_KEYCODE_SHIFT_LEFT: evt->key_code = GF_KEY_SHIFT; break; - case ANDROID_KEYCODE_SHIFT_RIGHT: evt->key_code = GF_KEY_SHIFT; break; - //case VK_CONTROL: evt->key_code = GF_KEY_CONTROL; break; - case ANDROID_KEYCODE_ALT_LEFT: evt->key_code = GF_KEY_ALT; break; - case ANDROID_KEYCODE_ALT_RIGHT: evt->key_code = GF_KEY_ALT; break; - //case VK_PAUSE: evt->key_code = GF_KEY_PAUSE; break; - //case VK_CAPITAL: evt->key_code = GF_KEY_CAPSLOCK; break; - //case VK_KANA: evt->key_code = GF_KEY_KANAMODE; break; - //case VK_JUNJA: evt->key_code = GF_KEY_JUNJAMODE; break; - //case VK_FINAL: evt->key_code = GF_KEY_FINALMODE; break; - //case VK_KANJI: evt->key_code = GF_KEY_KANJIMODE; break; - //case VK_ESCAPE: evt->key_code = GF_KEY_ESCAPE; break; - //case VK_CONVERT: evt->key_code = GF_KEY_CONVERT; break; - case ANDROID_KEYCODE_SPACE: evt->key_code = GF_KEY_SPACE; break; - //case VK_PRIOR: evt->key_code = GF_KEY_PAGEUP; break; - //case VK_NEXT: evt->key_code = GF_KEY_PAGEDOWN; break; - //case VK_END: evt->key_code = GF_KEY_END; break; - case ANDROID_KEYCODE_HOME: evt->key_code = GF_KEY_HOME; break; - case ANDROID_KEYCODE_DPAD_LEFT: evt->key_code = GF_KEY_LEFT; break; - case ANDROID_KEYCODE_DPAD_UP: evt->key_code = GF_KEY_UP; break; - case ANDROID_KEYCODE_DPAD_RIGHT: evt->key_code = GF_KEY_RIGHT; break; - case ANDROID_KEYCODE_DPAD_DOWN: evt->key_code = GF_KEY_DOWN; break; - //case VK_SELECT: evt->key_code = GF_KEY_SELECT; break; - //case VK_PRINT: - //case VK_SNAPSHOT: - // evt->key_code = GF_KEY_PRINTSCREEN; break; - //case VK_EXECUTE: evt->key_code = GF_KEY_EXECUTE; break; - //case VK_INSERT: evt->key_code = GF_KEY_INSERT; break; - case ANDROID_KEYCODE_DEL: evt->key_code = GF_KEY_DEL; break; - //case VK_HELP: evt->key_code = GF_KEY_HELP; break; - - -/* case '!': evt->key_code = GF_KEY_EXCLAMATION; break; - case '"': evt->key_code = GF_KEY_QUOTATION; break; - case '#': evt->key_code = GF_KEY_NUMBER; break; - case '$': evt->key_code = GF_KEY_DOLLAR; break; - case '&': evt->key_code = GF_KEY_AMPERSAND; break; - case '\'': evt->key_code = GF_KEY_APOSTROPHE; break; - case '(': evt->key_code = GF_KEY_LEFTPARENTHESIS; break; - case ')': evt->key_code = GF_KEY_RIGHTPARENTHESIS; break; - case ',': evt->key_code = GF_KEY_COMMA; break; - case ':': evt->key_code = GF_KEY_COLON; break; - case ';': evt->key_code = GF_KEY_SEMICOLON; break; - case '<': evt->key_code = GF_KEY_LESSTHAN; break; - case '>': evt->key_code = GF_KEY_GREATERTHAN; break; - case '?': evt->key_code = GF_KEY_QUESTION; break; - case '@': evt->key_code = GF_KEY_AT; break; - case '[': evt->key_code = GF_KEY_LEFTSQUAREBRACKET; break; - case ']': evt->key_code = GF_KEY_RIGHTSQUAREBRACKET; break; - case '\\': evt->key_code = GF_KEY_BACKSLASH; break; - case '_': evt->key_code = GF_KEY_UNDERSCORE; break; - case '`': evt->key_code = GF_KEY_GRAVEACCENT; break; - case ' ': evt->key_code = GF_KEY_SPACE; break; - case '/': evt->key_code = GF_KEY_SLASH; break; - case '*': evt->key_code = GF_KEY_STAR; break; - case '-': evt->key_code = GF_KEY_HIPHEN; break; - case '+': evt->key_code = GF_KEY_PLUS; break; - case '=': evt->key_code = GF_KEY_EQUALS; break; - case '^': evt->key_code = GF_KEY_CIRCUM; break; - case '{': evt->key_code = GF_KEY_LEFTCURLYBRACKET; break; - case '}': evt->key_code = GF_KEY_RIGHTCURLYBRACKET; break; - case '|': evt->key_code = GF_KEY_PIPE; break; -*/ - - -/* case VK_LWIN: return ; - case VK_RWIN: return ; - case VK_APPS: return ; -*/ - case ANDROID_KEYCODE_0: - evt->key_code = GF_KEY_0; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case ANDROID_KEYCODE_1: - evt->key_code = GF_KEY_1; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case ANDROID_KEYCODE_2: - evt->key_code = GF_KEY_2; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case ANDROID_KEYCODE_3: - evt->key_code = GF_KEY_3; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case ANDROID_KEYCODE_4: - evt->key_code = GF_KEY_4; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case ANDROID_KEYCODE_5: - evt->key_code = GF_KEY_5; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case ANDROID_KEYCODE_6: - evt->key_code = GF_KEY_6; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case ANDROID_KEYCODE_7: - evt->key_code = GF_KEY_7; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case ANDROID_KEYCODE_8: - evt->key_code = GF_KEY_8; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case ANDROID_KEYCODE_9: - evt->key_code = GF_KEY_9; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case ANDROID_KEYCODE_A: - evt->key_code = GF_KEY_9; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - /* - case VK_MULTIPLY: - evt->key_code = GF_KEY_STAR; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case VK_ADD: - evt->key_code = GF_KEY_PLUS; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case VK_SEPARATOR: - evt->key_code = GF_KEY_FULLSTOP; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case VK_SUBTRACT: - evt->key_code = GF_KEY_HYPHEN; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case VK_DECIMAL: - evt->key_code = GF_KEY_COMMA; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case VK_DIVIDE: - evt->key_code = GF_KEY_SLASH; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - - case VK_F1: evt->key_code = GF_KEY_F1; break; - case VK_F2: evt->key_code = GF_KEY_F2; break; - case VK_F3: evt->key_code = GF_KEY_F3; break; - case VK_F4: evt->key_code = GF_KEY_F4; break; - case VK_F5: evt->key_code = GF_KEY_F5; break; - case VK_F6: evt->key_code = GF_KEY_F6; break; - case VK_F7: evt->key_code = GF_KEY_F7; break; - case VK_F8: evt->key_code = GF_KEY_F8; break; - case VK_F9: evt->key_code = GF_KEY_F9; break; - case VK_F10: evt->key_code = GF_KEY_F10; break; - case VK_F11: evt->key_code = GF_KEY_F11; break; - case VK_F12: evt->key_code = GF_KEY_F12; break; - case VK_F13: evt->key_code = GF_KEY_F13; break; - case VK_F14: evt->key_code = GF_KEY_F14; break; - case VK_F15: evt->key_code = GF_KEY_F15; break; - case VK_F16: evt->key_code = GF_KEY_F16; break; - case VK_F17: evt->key_code = GF_KEY_F17; break; - case VK_F18: evt->key_code = GF_KEY_F18; break; - case VK_F19: evt->key_code = GF_KEY_F19; break; - case VK_F20: evt->key_code = GF_KEY_F20; break; - case VK_F21: evt->key_code = GF_KEY_F21; break; - case VK_F22: evt->key_code = GF_KEY_F22; break; - case VK_F23: evt->key_code = GF_KEY_F23; break; - case VK_F24: evt->key_code = GF_KEY_F24; break; - - case VK_NUMLOCK: evt->key_code = GF_KEY_NUMLOCK; break; - case VK_SCROLL: evt->key_code = GF_KEY_SCROLL; break; - */ - -/* - * VK_L* & VK_R* - left and right Alt, Ctrl and Shift virtual keys. - * Used only as parameters to GetAsyncKeyState() and GetKeyState(). - * No other API or message will distinguish left and right keys in this way. - */ - /* - case ANDROID_KEYCODE_SHIFT_LEFT: - evt->key_code = GF_KEY_SHIFT; - evt->flags = GF_KEY_EXT_LEFT; - break; - case ANDROID_KEYCODE_SHIFT_RIGHT: - evt->key_code = GF_KEY_SHIFT; - evt->flags = GF_KEY_EXT_RIGHT; - break; - case VK_LCONTROL: - evt->key_code = GF_KEY_CONTROL; - evt->flags = GF_KEY_EXT_LEFT; - break; - case VK_RCONTROL: - evt->key_code = GF_KEY_CONTROL; - evt->flags = GF_KEY_EXT_RIGHT; - break; - case VK_LMENU: - evt->key_code = GF_KEY_ALT; - evt->flags = GF_KEY_EXT_LEFT; - break; - case VK_RMENU: - evt->key_code = GF_KEY_ALT; - evt->flags = GF_KEY_EXT_RIGHT; - break; - */ - - /*thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) */ - /* VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */ - default: - if ((keycode>=ANDROID_KEYCODE_A) && (keycode<=ANDROID_KEYCODE_Z)) { evt->key_code = GF_KEY_A + keycode - ANDROID_KEYCODE_A; debug_log("default keycode"); } - else - evt->key_code = GF_KEY_UNIDENTIFIED; - break; - } - - //evt->hw_code = keycode; - evt->hw_code = evt->key_code; -} -//----------------------------------------------------- -GF_Config *CNativeWrapper::create_default_config(char *file_path, char *file_name){ - GF_Config *cfg; - char szPath[GF_MAX_PATH]; - FILE *f; - sprintf(szPath, "%s%c%s", file_path, GF_PATH_SEPARATOR, file_name); - f = fopen(szPath, "wt"); - fprintf(stdout, "create %s: %s\n", szPath, (f==NULL) ? "Error" : "OK"); - if (!f) return NULL; - fclose(f); - - cfg = gf_cfg_new(file_path, file_name); - if (!cfg) return NULL; - -#ifdef GPAC_MODULES_PATH - fprintf(stdout, "Using module directory %s \n", GPAC_MODULES_PATH); - strcpy(szPath, GPAC_MODULES_PATH); -#elif defined(WIN32) - strcpy(szPath, file_path); -#else - fprintf(stdout, "Please enter full path to GPAC modules directory:\n"); - scanf("%s", szPath); -#endif - gf_cfg_set_key(cfg, "General", "ModulesDirectory", szPath); - gf_cfg_set_key(cfg, "Audio", "ForceConfig", "yes"); - gf_cfg_set_key(cfg, "Audio", "NumBuffers", "2"); - gf_cfg_set_key(cfg, "Audio", "TotalDuration", "120"); - gf_cfg_set_key(cfg, "Audio", "DisableNotification", "no"); - gf_cfg_set_key(cfg, "FontEngine", "FontReader", "ft_font"); - - /*these fonts seems installed by default on many systems...*/ - //gf_cfg_set_key(cfg, "FontEngine", "FontSerif", "Bitstream Vera Serif"); - //gf_cfg_set_key(cfg, "FontEngine", "FontSans", "Bitstream Vera Sans"); - //gf_cfg_set_key(cfg, "FontEngine", "FontFixed", "Bitstream Vera Monospace"); - strcpy(szPath, "/system/fonts/"); - - fprintf(stdout, "Using default font directory %s\n", szPath); - gf_cfg_set_key(cfg, "FontEngine", "FontDirectory", szPath); - - fprintf(stdout, "Using /tmp as a cache directory for HTTP downloads:\n"); - gf_cfg_set_key(cfg, "General", "CacheDirectory", "/data/osmo/tmp"); - - gf_cfg_set_key(cfg, "Downloader", "CleanCache", "yes"); - gf_cfg_set_key(cfg, "Compositor", "AntiAlias", "All"); - gf_cfg_set_key(cfg, "Compositor", "FrameRate", "30"); - /*use power-of-2 emulation*/ - gf_cfg_set_key(cfg, "Compositor", "EmulatePOW2", "yes"); - - gf_cfg_set_key(cfg, "Video", "DriverName", "Android Video Output"); - /*x11 only supports scalable zoom*/ - gf_cfg_set_key(cfg, "Compositor", "ScalableZoom", "yes"); - gf_cfg_set_key(cfg, "Audio", "DriverName", "SDL Audio Output"); - - gf_cfg_set_key(cfg, "Video", "SwitchResolution", "no"); - gf_cfg_set_key(cfg, "Network", "AutoReconfigUDP", "yes"); - gf_cfg_set_key(cfg, "Network", "UDPTimeout", "10000"); - gf_cfg_set_key(cfg, "Network", "BufferLength", "3000"); - - /*store and reload*/ - gf_cfg_del(cfg); - return gf_cfg_new(file_path, file_name); -} -//--------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------- -// this function will be called by Java to init gpac - -void gpac_init(JNIEnv * env, jobject * bitmap){ - - gpac_obj = new CNativeWrapper(); - if (gpac_obj) gpac_obj->init(env, bitmap); - //if (gpac_obj) gpac_obj->connect("/data/osmo/tidycity.mp4"); -} - -void gpac_render(JNIEnv * env, jobject * bitmap){ - if (gpac_obj) gpac_obj->step(env, bitmap); -} - -void gpac_connect(const char *url){ - //gpac_obj->connect("/data/osmo/tidycity.mp4"); - gpac_obj->connect(url); -} - -void gpac_resize(int w, int h){ - if (gpac_obj) gpac_obj->resize(w, h); -} - -void gpac_disconnect(){ - if (gpac_obj) gpac_obj->disconnect(); -} - -void gpac_free(){ - if (gpac_obj) delete gpac_obj; -} - -void gpac_onmousedown(float x, float y){ - if (gpac_obj) gpac_obj->onMouseDown(x, y); -} - -void gpac_onmouseup(float x, float y){ - if (gpac_obj) gpac_obj->onMouseUp(x, y); -} -void gpac_onkeypress(int keycode, int rawkeycode, int up, int flag){ - if (gpac_obj) gpac_obj->onKeyPress(keycode, rawkeycode, up, flag); -} -//--------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------- - -JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GpacObject_gpacinit(JNIEnv * env, jobject obj, jobject bitmap, jint width, jint height) -{ - int x = width; - int y = height; - gpac_init(env, &bitmap); - //initGL(); -} -//----------------------------------- -JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GpacObject_gpacconnect(JNIEnv * env, jobject obj, jstring url) -{ - const char *the_url = env->GetStringUTFChars(url, NULL); - //(*env)->ReleaseStringUTFChars(env, prompt, str); - gpac_connect(the_url); -} -//----------------------------------- -JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GpacObject_gpacdisconnect(JNIEnv * env, jobject obj){ - gpac_disconnect(); -} -//----------------------------------- -JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GpacObject_gpacfree(JNIEnv * env, jobject obj) -{ - gpac_free(); -} -//----------------------------------- -JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GpacObject_gpacrender (JNIEnv * env, jobject obj, jobject bitmap) -{ - gpac_render(env, &bitmap); - //drawGLScene(); -} -//----------------------------------- -JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GpacObject_gpacresize (JNIEnv * env, jobject obj, jint width, jint height) -{ - int w = width; - int h = height; - gpac_resize(w,h); - //resizeWindow(w,h); -} -//----------------------------------- -JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GpacObject_gpaceventmousedown(JNIEnv * env, jobject obj, jfloat x, jfloat y){ - gpac_onmousedown(x, y); -} -//----------------------------------- -JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GpacObject_gpaceventmouseup(JNIEnv * env, jobject obj, jfloat x, jfloat y){ - gpac_onmouseup(x, y); -} -//----------------------------------- -JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GpacObject_gpaceventkeypress(JNIEnv * env, jobject obj, jint keycode, jint rawkeycode, jint up, jint flag){ - gpac_onkeypress(keycode, rawkeycode, up, flag); -} -//----------------------------------- diff --git a/applications/osmo4_android/jni/wrapper-bitmap-20-09-2010.h b/applications/osmo4_android/jni/wrapper-bitmap-20-09-2010.h deleted file mode 100644 index 8e39ad9..0000000 --- a/applications/osmo4_android/jni/wrapper-bitmap-20-09-2010.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) ENST 2009- - * Authors: Jean Le Feuvre - * All rights reserved - * - * Created by NGO Van Luyen, Ivica ARSOV / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010 - * - * This file is part of GPAC / Wrapper - * - * 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 - -#include -#include -#include -#include - -#include - -#define KErrGeneral 1 -#define GPAC_CFG_DIR "/data/osmo/" -#define GPAC_MODULES_DIR "/data/osmo/modules/" -#define GPAC_MODULES_PATH "/data/osmo/modules/" -#define GPAC_CACHE_DIR "/data/osmo/cache/" -#define GPAC_LOG_FILE "/data/osmo/gpac_logs.txt" -#define GPAC_FONT_DIR "/system/fonts/" - -#define DEBUG_MODE 1 -#define DEBUG_FILE "/data/osmo/osmo_debug.txt" - -// keyboard code -#define ANDROID_KEYCODE int -#define ANDROID_KEYCODE_0 7 -#define ANDROID_KEYCODE_1 8 -#define ANDROID_KEYCODE_2 9 -#define ANDROID_KEYCODE_3 10 -#define ANDROID_KEYCODE_4 11 -#define ANDROID_KEYCODE_5 12 -#define ANDROID_KEYCODE_6 13 -#define ANDROID_KEYCODE_7 14 -#define ANDROID_KEYCODE_8 15 -#define ANDROID_KEYCODE_9 16 -#define ANDROID_KEYCODE_A 29 -#define ANDROID_KEYCODE_B 30 -#define ANDROID_KEYCODE_C 31 -#define ANDROID_KEYCODE_D 32 -#define ANDROID_KEYCODE_E 33 -#define ANDROID_KEYCODE_F 34 -#define ANDROID_KEYCODE_G 35 -#define ANDROID_KEYCODE_H 36 -#define ANDROID_KEYCODE_I 37 -#define ANDROID_KEYCODE_J 38 -#define ANDROID_KEYCODE_K 39 -#define ANDROID_KEYCODE_L 40 -#define ANDROID_KEYCODE_M 41 -#define ANDROID_KEYCODE_N 42 -#define ANDROID_KEYCODE_O 43 -#define ANDROID_KEYCODE_P 44 -#define ANDROID_KEYCODE_Q 45 -#define ANDROID_KEYCODE_R 46 -#define ANDROID_KEYCODE_S 47 -#define ANDROID_KEYCODE_T 48 -#define ANDROID_KEYCODE_U 49 -#define ANDROID_KEYCODE_V 50 -#define ANDROID_KEYCODE_W 51 -#define ANDROID_KEYCODE_X 52 -#define ANDROID_KEYCODE_Y 53 -#define ANDROID_KEYCODE_Z 54 -#define ANDROID_KEYCODE_ALT_LEFT 57 -#define ANDROID_KEYCODE_ALT_RIGHT 58 -#define ANDROID_KEYCODE_AT 77 -#define ANDROID_KEYCODE_BACK 4 -#define ANDROID_KEYCODE_BACKSLASH 73 -#define ANDROID_KEYCODE_CALL 5 -#define ANDROID_KEYCODE_CAMERA 27 -#define ANDROID_KEYCODE_CLEAR 28 -#define ANDROID_KEYCODE_COMMA 55 -#define ANDROID_KEYCODE_DEL 67 -#define ANDROID_KEYCODE_DPAD_CENTER 23 -#define ANDROID_KEYCODE_DPAD_DOWN 20 -#define ANDROID_KEYCODE_DPAD_LEFT 21 -#define ANDROID_KEYCODE_DPAD_RIGHT 22 -#define ANDROID_KEYCODE_DPAD_UP 19 -#define ANDROID_KEYCODE_ENDCALL 6 -#define ANDROID_KEYCODE_ENTER 66 -#define ANDROID_KEYCODE_ENVELOPE 65 -#define ANDROID_KEYCODE_EQUALS 70 -#define ANDROID_KEYCODE_EXPLORER 64 -#define ANDROID_KEYCODE_FOCUS 80 -#define ANDROID_KEYCODE_GRAVE 68 -#define ANDROID_KEYCODE_HEADSETHOOK 79 -#define ANDROID_KEYCODE_HOME 3 -#define ANDROID_KEYCODE_LEFT_BRACKET 71 -#define ANDROID_KEYCODE_MEDIA_FAST_FORWARD 90 -#define ANDROID_KEYCODE_MEDIA_NEXT 87 -#define ANDROID_KEYCODE_MEDIA_PLAY_PAUSE 85 -#define ANDROID_KEYCODE_MEDIA_PREVIOUS 88 -#define ANDROID_KEYCODE_MEDIA_REWIND 89 -#define ANDROID_KEYCODE_MEDIA_STOP 86 -#define ANDROID_KEYCODE_MENU 82 -#define ANDROID_KEYCODE_MINUS 69 -#define ANDROID_KEYCODE_MUTE 91 -#define ANDROID_KEYCODE_NUM 78 -#define ANDROID_KEYCODE_PLUS 81 -#define ANDROID_KEYCODE_POWER 26 -#define ANDROID_KEYCODE_RIGHT_BRACKET 72 -#define ANDROID_KEYCODE_SEARCH 84 -#define ANDROID_KEYCODE_SEMICOLON 74 -#define ANDROID_KEYCODE_SHIFT_LEFT 59 -#define ANDROID_KEYCODE_SHIFT_RIGHT 60 -#define ANDROID_KEYCODE_SLASH 76 -#define ANDROID_KEYCODE_SOFT_LEFT 1 -#define ANDROID_KEYCODE_SOFT_RIGHT 2 -#define ANDROID_KEYCODE_SPACE 62 -#define ANDROID_KEYCODE_STAR 17 -#define ANDROID_KEYCODE_SYM 63 -#define ANDROID_KEYCODE_TAB 61 - -#define ANDROID_KEYCODE_UNKWON -1 - -//--------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------- -class CPeriodic{ - public: - CPeriodic(); - ~CPeriodic(); - - void Start(); - void Cancel(); - -}; -//--------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------- -class CNativeWrapper{ - - private: - void* m_window; - void* m_session; - - GF_User *GetUser() { return &m_user; } - GF_Terminal *m_term; - - CPeriodic *m_pTimer; - GF_Mutex *m_mx; - GF_User m_user; - GF_SystemRTInfo m_rti; - - int do_log; - FILE *logfile; - private: - void SetupLogs(); - void Shutdown(); - void DisplayRTI(); - public: - CNativeWrapper(); - ~CNativeWrapper(); - int init(JNIEnv * env, jobject * bitmap); - int OnTick(); - - int connect(const char *url); - void disconnect(); - void step(JNIEnv * env, jobject * bitmap); - void resize(int w, int h); - - void onMouseDown(float x, float y); - void onMouseUp(float x, float y); - void onKeyPress(int keycode, int rawkeycode, int up, int flag); - void translate_key(ANDROID_KEYCODE keycode, GF_EventKey *evt); - public: - int MessageBox(const char* msg, const char* title); - int Quit(int code); - GF_Config *create_default_config(char *file_path, char *file_name); - - static void on_gpac_log(void *cbk, u32 ll, u32 lm, const char *fmt, va_list list); - static Bool GPAC_EventProc(void *ptr, GF_Event *evt); - static void Osmo4_progress_cbk(void *usr, char *title, u32 done, u32 total); - - private: -#ifdef DEBUG_MODE - FILE *debug_f; -#endif - void debug_log(const char* msg); - -}; -//--------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------- -// this function will be called by Java to init gpac -CNativeWrapper* gpac_obj = NULL; - -/* -void gpac_init(); -void gpac_connect(const char *url); -void gpac_disconnect(); -void gpac_render(); -void gpac_free(); -*/ -//--------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------- -extern "C" { - JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GpacObject_gpacinit(JNIEnv * env, jobject obj, jobject bitmap, jint width, jint height); - JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GpacObject_gpacconnect(JNIEnv * env, jobject obj, jstring url); - JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GpacObject_gpacdisconnect(JNIEnv * env, jobject obj); - JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GpacObject_gpacrender(JNIEnv * env, jobject obj, jobject bitmap); - JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GpacObject_gpacresize (JNIEnv * env, jobject obj, jint width, jint height); - JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GpacObject_gpacfree(JNIEnv * env, jobject obj); - - JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GpacObject_gpaceventmousedown(JNIEnv * env, jobject obj, jfloat x, jfloat y); - JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GpacObject_gpaceventmouseup(JNIEnv * env, jobject obj, jfloat x, jfloat y); - JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GpacObject_gpaceventkeypress(JNIEnv * env, jobject obj, jint keycode, jint rawkeycode, jint up, jint flag); -}; - diff --git a/applications/osmo4_android/jni/wrapper.cpp b/applications/osmo4_android/jni/wrapper.cpp index 4855fad..93b0394 100644 --- a/applications/osmo4_android/jni/wrapper.cpp +++ b/applications/osmo4_android/jni/wrapper.cpp @@ -1,910 +1,916 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) ENST 2009- - * Authors: Jean Le Feuvre - * All rights reserved - * - * Created by NGO Van Luyen, Ivica ARSOV / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010 - * - * This file is part of GPAC / Wrapper - * - * 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 - -#include -#include -#include -#include -#include -#include - -#include "wrapper.h" -#include "wrapper_jni.c" - -#include -#include - -#define TAG "GPAC_WRAPPER" - -#define LOGV(X, Y) __android_log_print(ANDROID_LOG_VERBOSE, TAG, X, Y) -#define LOGD(X, Y) __android_log_print(ANDROID_LOG_DEBUG, TAG, X, Y) -#define LOGE(X, Y) __android_log_print(ANDROID_LOG_ERROR, TAG, X, Y) -#define LOGW(X, Y) __android_log_print(ANDROID_LOG_WARN, TAG, X, Y) -#define LOGI(X, Y) __android_log_print(ANDROID_LOG_INFO, TAG, X, Y) -#include - -static JavaVM* javaVM = NULL; - -static pthread_key_t jni_thread_env_key = 0; - -/** - * This method is called when a pthread is destroyed, so we can delete the JNI env - */ -static void jni_destroy_env_func(void * env) { - LOGI("Destroying a thread with attached data, env=%p.\n", env); - JavaEnvTh * jniEnv = (JavaEnvTh *) env; - if (jniEnv){ - /*jniEnv->env->DeleteLocalRef(&jniEnv->cbk_displayMessage); - jniEnv->env->DeleteLocalRef(&jniEnv->cbk_onProgress); - jniEnv->env->DeleteLocalRef(&jniEnv->cbk_showKeyboard); - jniEnv->env->DeleteLocalRef(&jniEnv->cbk_setCaption); - jniEnv->env->DeleteLocalRef(&jniEnv->cbk_onLog);*/ - memset(jniEnv, 0, sizeof(JavaEnvTh)); - gf_free(jniEnv); - } - pthread_setspecific(jni_thread_env_key, NULL); - if (javaVM) - javaVM->DetachCurrentThread(); -} - -static int jniRegisterNativeMethods(JNIEnv* env, const char* className, - const JNINativeMethod* gMethods, int numMethods) -{ - jclass clazz; - clazz = env->FindClass(className); - if (clazz == NULL) { - LOGE("Native registration unable to find class '%s'\n", className); - return -1; - } - if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) { - LOGE("RegisterNatives failed for '%s'\n", className); - return -1; - } - return 0; -} - -static JNINativeMethod sMethods[] = { - /* name, signature, funcPtr */ - - {"createInstance", - "(Lcom/artemis/Osmo4/GpacCallback;IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)J", - (void*)&Java_com_artemis_Osmo4_GPACInstance_createInstance}, - {"gpacdisconnect", - "()V", - (void*)Java_com_artemis_Osmo4_GPACInstance_gpacdisconnect}, - {"gpacrender", - "()V", - (void*)Java_com_artemis_Osmo4_GPACInstance_gpacrender}, - {"gpacresize", - "(II)V", - (void*)Java_com_artemis_Osmo4_GPACInstance_gpacresize}, - {"gpacfree", - "()V", - (void*)Java_com_artemis_Osmo4_GPACInstance_gpacfree}, - {"gpaceventkeypress", - "(IIIII)V", - (void*)Java_com_artemis_Osmo4_GPACInstance_gpaceventkeypress}, - {"gpaceventmousedown", - "(FF)V", - (void*)Java_com_artemis_Osmo4_GPACInstance_gpaceventmousedown}, - {"gpaceventmouseup", - "(FF)V", - (void*)Java_com_artemis_Osmo4_GPACInstance_gpaceventmouseup}, - {"gpaceventmousemove", - "(FF)V", - (void*)Java_com_artemis_Osmo4_GPACInstance_gpaceventmousemove}, - {"setGpacPreference", - "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", - (void*)Java_com_artemis_Osmo4_GPACInstance_setGpacPreference}, - NULL -}; - - -jint JNI_OnUnLoad(JavaVM* vm, void* reserved){ - LOGI("Deleting library, vm=%p...\n", vm); - if (pthread_key_delete(jni_thread_env_key)){ - LOGW("Failed to delete key jni_thread_env_key jni_thread_env_key=%p\n", jni_thread_env_key); - } - javaVM = NULL; - jni_thread_env_key = NULL; -} - -//--------------------------------------------------------------------------------------------------- -jint JNI_OnLoad(JavaVM* vm, void* reserved){ - const char * className = "com/artemis/Osmo4/GPACInstance"; - JNIEnv * env; - if (!vm) - return -1; - if (vm->GetEnv((void**)(&env), JNI_VERSION_1_2) != JNI_OK) - return -1; - javaVM = vm; - LOGI("Registering %s natives\n", className); - if (jniRegisterNativeMethods(env, className, sMethods, 9) < 0){ - LOGE("Failed to register native methods for %s !\n", className); - return -1; - } - LOGI("Registering natives DONE, now registering pthread_keys with destructor=%p\n", &jni_destroy_env_func); - int ret = pthread_key_create(&jni_thread_env_key, &jni_destroy_env_func); - if (ret){ - LOGE("Failed to register jni_thread_env_key jni_thread_env_key=%p\n", jni_thread_env_key); - } - return JNI_VERSION_1_2; -} - -//--------------------------------------------------------------------------------------------------- -//CNativeWrapper -//------------------------------- - -CNativeWrapper::CNativeWrapper(){ - do_log = 1; - m_term = NULL; - m_mx = NULL; -#ifndef GPAC_GUI_ONLY - memset(&m_user, 0, sizeof(GF_User)); - memset(&m_rti, 0, sizeof(GF_SystemRTInfo)); -#endif -} -//------------------------------- -CNativeWrapper::~CNativeWrapper(){ - debug_log("~CNativeWrapper()"); - JavaEnvTh * env = getEnv(); - if (env && env->cbk_obj) - env->env->DeleteGlobalRef(env->cbk_obj); - Shutdown(); - debug_log("~CNativeWrapper() : DONE\n"); -} -//------------------------------- -void CNativeWrapper::debug_log(const char* msg){ - LOGV("%s", msg); -} -//------------------------------- -void CNativeWrapper::Shutdown() -{ - debug_log("shutdown"); - if (m_term) - gf_term_disconnect(m_term); - if (m_mx) - gf_mx_del(m_mx); - m_mx = NULL; -#ifndef GPAC_GUI_ONLY - if (m_term) { - GF_Terminal *t = m_term; - m_term = NULL; - gf_term_del(t); - } - if (m_user.config) { - gf_cfg_del(m_user.config); - m_user.config = NULL; - } - if (m_user.modules) { - gf_modules_del(m_user.modules); - m_user.modules = NULL; - } -#endif - m_term = NULL; - debug_log("shutdown end"); -} - -void CNativeWrapper::setJavaEnv(JavaEnvTh * envToSet, JNIEnv *env, jobject callback){ - assert( envToSet ); - jclass localRef = env->GetObjectClass(callback); - envToSet->env = env; - envToSet->javaThreadId = gf_th_id(); - envToSet->cbk_obj = callback; - envToSet->cbk_displayMessage = - env->GetMethodID(localRef, "displayMessage", "(Ljava/lang/String;Ljava/lang/String;I)V"); - envToSet->cbk_onProgress = - env->GetMethodID(localRef, "onProgress", "(Ljava/lang/String;II)V"); - envToSet->cbk_onLog = - env->GetMethodID(localRef, "onLog", "(IILjava/lang/String;)V"); - envToSet->cbk_setCaption = - env->GetMethodID(localRef, "setCaption", "(Ljava/lang/String;)V"); - envToSet->cbk_showKeyboard = - env->GetMethodID(localRef, "showKeyboard", "(Z)V"); - env->DeleteLocalRef(localRef); -} - -static u32 beforeThreadExits(void * param){ - LOGI("Before Thread exist, detach the JavaVM from Thread for thread %p...\n", gf_th_current()); - if (javaVM) - javaVM->DetachCurrentThread(); -} - -JavaEnvTh * CNativeWrapper::getEnv(){ - JNIEnv *env; - JavaEnvTh * javaEnv; - if (!javaVM){ - debug_log("************* No JVM Found ************"); - return NULL; - } - javaEnv = (JavaEnvTh*) pthread_getspecific( jni_thread_env_key ); - if (javaEnv) - return javaEnv; - javaEnv = (JavaEnvTh *) gf_malloc(sizeof(JavaEnvTh)); - if (!javaEnv) - return NULL; - memset(javaEnv, 0, sizeof(JavaEnvTh)); - javaVM->AttachCurrentThread(&env, NULL); - if (!env){ - LOGE("Attaching to thread did faild for thread id=%d", gf_th_id()); - gf_free(javaEnv); - return NULL; - } - LOGI("Rebuilding methods for thread %d", gf_th_id()); - setJavaEnv(javaEnv, env, mainJavaEnv.cbk_obj); - if (pthread_setspecific(jni_thread_env_key, javaEnv)){ - LOGE("Failed to set specific thread data to jni_thread_env_key for thread=%d. No ENV available !", gf_th_id()); - gf_free(javaEnv); - return NULL; - } - GF_Thread * t; - LOGI("Getting current Thread %d...", gf_th_id()); - t = gf_th_current(); - LOGI("Getting current Thread DONE = %p, now registering before exit...", t); - - if (GF_OK != gf_register_before_exit_function(gf_th_current(), &beforeThreadExits)){ - LOGE("Failed to register exit function for thread %p, no javaEnv for current thread.", gf_th_current()); - //javaVM->DetachCurrentThread(); - gf_free(javaEnv); - javaEnv = NULL; - } - LOGI("Registering DONE for %d", gf_th_id()); - return javaEnv; -} - - -//------------------------------- -int CNativeWrapper::MessageBox(const char* msg, const char* title, GF_Err status){ - LOGV("MessageBox start %s", msg); - JavaEnvTh * env = getEnv(); - if (!env || !env->cbk_displayMessage) - return 0; - env->env->PushLocalFrame(2); - jstring tit = env->env->NewStringUTF(title?title:"null"); - jstring mes = env->env->NewStringUTF(msg?msg:"null"); - env->env->CallVoidMethod(env->cbk_obj, env->cbk_displayMessage, mes, tit, status); - env->env->PopLocalFrame(NULL); - LOGV("MessageBox done %s", msg); - return 1; -} -//------------------------------- -void CNativeWrapper::DisplayRTI(){ -#ifndef GPAC_GUI_ONLY - // display some system informations ? -#endif -} -//------------------------------- -int CNativeWrapper::Quit(int code){ - - Shutdown(); - // send shutdown request to java - return code; -} - -#include - -//------------------------------- -void CNativeWrapper::on_gpac_log(void *cbk, u32 ll, u32 lm, const char *fmt, va_list list){ - char szMsg[4096]; - const char * tag; - char unknTag[32]; - int debug; - // We do not want to be flood by mutexes - if (ll == GF_LOG_DEBUG && lm == GF_LOG_MUTEX) - return; - switch (ll){ - case GF_LOG_DEBUG: - debug = ANDROID_LOG_DEBUG; - break; - case GF_LOG_INFO: - debug = ANDROID_LOG_INFO; - break; - case GF_LOG_WARNING: - debug = ANDROID_LOG_WARN; - break; - case GF_LOG_ERROR: - debug = ANDROID_LOG_ERROR; - break; - default: - debug = ANDROID_LOG_INFO; - } - vsnprintf(szMsg, 4096, fmt, list); - CNativeWrapper * self = (CNativeWrapper *) cbk; - if (!self) - goto displayInAndroidlogs; - - { - JavaEnvTh *env = self->getEnv(); - jstring msg; - if (!env || !env->cbk_onLog) - goto displayInAndroidlogs; - env->env->PushLocalFrame(1); - msg = env->env->NewStringUTF(szMsg); - env->env->CallVoidMethod(env->cbk_obj, env->cbk_onLog, debug, lm, msg); - env->env->PopLocalFrame(NULL); - return; - } -displayInAndroidlogs: - { - /* When no callback is properly set, we use direct logging */ - switch( lm){ - case GF_LOG_CORE: - tag="GF_LOG_CORE"; - break; - case GF_LOG_CODING: - tag="GF_LOG_CODING"; - break; - case GF_LOG_CONTAINER: - tag="GF_LOG_CONTAINER"; - break; - case GF_LOG_NETWORK: - tag="GF_LOG_NETWORK"; - break; - case GF_LOG_RTP: - tag="GF_LOG_RTP"; - break; - case GF_LOG_AUTHOR: - tag="GF_LOG_AUTHOR"; - break; - case GF_LOG_SYNC: - tag="GF_LOG_SYNC"; - break; - case GF_LOG_CODEC: - tag="GF_LOG_CODEC"; - break; - case GF_LOG_PARSER: - tag="GF_LOG_PARSER"; - break; - case GF_LOG_MEDIA: - tag="GF_LOG_MEDIA"; - break; - case GF_LOG_SCENE: - tag="GF_LOG_SCENE"; - break; - case GF_LOG_SCRIPT: - tag="GF_LOG_SCRIPT"; - break; - case GF_LOG_INTERACT: - tag="GF_LOG_INTERACT"; - break; - case GF_LOG_COMPOSE: - tag="GF_LOG_COMPOSE"; - break; - case GF_LOG_CACHE: - tag="GF_LOG_CACHE"; - break; - case GF_LOG_MMIO: - tag="GF_LOG_MMIO"; - break; - case GF_LOG_RTI: - tag="GF_LOG_RTI"; - break; - case GF_LOG_SMIL: - tag="GF_LOG_SMIL"; - break; - case GF_LOG_MEMORY: - tag="GF_LOG_MEMORY"; - break; - case GF_LOG_AUDIO: - tag="GF_LOG_AUDIO"; - break; - case GF_LOG_MODULE: - tag="GF_LOG_MODULE"; - break; - case GF_LOG_MUTEX: - tag="GF_LOG_MUTEX"; - break; - default: - snprintf(unknTag, 32, "GPAC_UNKNOWN[%d]", lm); - tag = unknTag; - } - __android_log_print(debug, tag, szMsg); - } -} -//------------------------------- -Bool CNativeWrapper::GPAC_EventProc(void *cbk, GF_Event *evt){ - if (cbk) - { - CNativeWrapper* ptr = (CNativeWrapper*)cbk; - char msg[4096]; - msg[0] = 0; - LOGD("GPAC_EventProc() Message=%d", evt->type); - switch (evt->type){ - case GF_EVENT_CLICK: - case GF_EVENT_MOUSEUP: - case GF_EVENT_MOUSEDOWN: - case GF_EVENT_MOUSEOVER: - case GF_EVENT_MOUSEOUT: - case GF_EVENT_MOUSEMOVE: - case GF_EVENT_MOUSEWHEEL: - case GF_EVENT_KEYUP: - case GF_EVENT_KEYDOWN: - case GF_EVENT_LONGKEYPRESS: - case GF_EVENT_TEXTINPUT: - /* We ignore all these events */ - break; - case GF_EVENT_MEDIA_BEGIN_SESSION_SETUP: - case GF_EVENT_MEDIA_END_SESSION_SETUP: - case GF_EVENT_MEDIA_DATA_REQUEST: - case GF_EVENT_MEDIA_PLAYABLE: - case GF_EVENT_MEDIA_NOT_PLAYABLE: - case GF_EVENT_MEDIA_DATA_PROGRESS: - case GF_EVENT_MEDIA_END_OF_DATA: - case GF_EVENT_MEDIA_STOP: - case GF_EVENT_MEDIA_ERROR: - LOGD("GPAC_EventProc() Media Event detected = [index=%d]", evt->type - GF_EVENT_MEDIA_BEGIN_SESSION_SETUP); - break; - case GF_EVENT_MESSAGE: - { - ptr->debug_log("GPAC_EventProc start"); - if ( evt->message.message ) - { - strcat(msg, evt->message.message); - strcat(msg, ": "); - } - strcat(msg, gf_error_to_string(evt->message.error)); - - ptr->debug_log(msg); - ptr->MessageBox(msg, evt->message.service ? evt->message.service : "GF_EVENT_MESSAGE", evt->message.error); - ptr->debug_log("GPAC_EventProc end"); - }; - break; - case GF_EVENT_CONNECT: - if (evt->connect.is_connected) - ptr->MessageBox("Connected", "Connected to scene", GF_OK); - else - ptr->MessageBox("Disconnected", "Disconnected from scene.", GF_OK); - break; - case GF_EVENT_PROGRESS: - { - const char * szTitle;; - if (evt->progress.progress_type==0) - szTitle = "Buffering"; - else if (evt->progress.progress_type==1) - szTitle = "Downloading..."; - else if (evt->progress.progress_type==2) - szTitle = "Import "; - else - szTitle = "Unknown Progress Event"; - ptr->Osmo4_progress_cbk(ptr, szTitle, evt->progress.done, evt->progress.total); - gf_set_progress(szTitle, evt->progress.done, evt->progress.total); - } - break; - case GF_EVENT_TEXT_EDITING_START: - case GF_EVENT_TEXT_EDITING_END: - { - JavaEnvTh * env = ptr->getEnv(); - if (!env || !env->cbk_showKeyboard) - return 0; - LOGI("Needs to display/hide the Virtual Keyboard (%d)", evt->type); - env->env->CallVoidMethod(env->cbk_obj, env->cbk_showKeyboard, GF_EVENT_TEXT_EDITING_START == evt->type); - LOGV("Done showing virtual keyboard (%d)", evt->type); - } - break; - case GF_EVENT_EOS: - LOGI("EOS Reached (%d)", evt->type); - break; - case GF_EVENT_DISCONNECT: - /* FIXME : not sure about this behaviour */ - if (ptr) - ptr->disconnect(); - break; - default: - LOGI("Unknown Message %d", evt->type); - } - } - return 0; -} - - -void CNativeWrapper::progress_cbk(const char *title, u64 done, u64 total){ - JavaEnvTh *env = getEnv(); - if (!env || !env->cbk_onProgress) - return; - debug_log("Osmo4_progress_cbk start"); - env->env->PushLocalFrame(1); - jstring js = env->env->NewStringUTF(title); - env->env->CallVoidMethod(env->cbk_obj, env->cbk_onProgress, js, done, total); - env->env->PopLocalFrame(NULL); - debug_log("Osmo4_progress_cbk end"); -} - - -//------------------------------- -void CNativeWrapper::Osmo4_progress_cbk(const void *usr, const char *title, u64 done, u64 total){ - if (!usr) - return; - CNativeWrapper * self = (CNativeWrapper *) usr; - self->progress_cbk(title, done, total); -} -//------------------------------- -void CNativeWrapper::SetupLogs(){ - const char *opt; - debug_log("SetupLogs()"); - - gf_mx_p(m_mx); - - /*setup GPAC logs: log all errors*/ - gf_log_set_level(GF_LOG_DEBUG); - gf_log_set_tools(0xFFFFFFFF); - - opt = gf_cfg_get_key(m_user.config, "General", "LogLevel"); - /* FIXME : set the loglevel according to config file */ - - opt = gf_cfg_get_key(m_user.config, "General", "LogTools"); - if (opt) gf_log_set_tools(gf_log_parse_tools(opt)); - - gf_log_set_callback(this, on_gpac_log); - gf_mx_v(m_mx); - - GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("Osmo4 logs initialized\n")); - /* Test for JNI invocations, should work properly - int k; - for (k = 0 ; k < 512; k++){ - GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("Message %d\n", k)); - }*/ -} -//------------------------------- -// dir should end with / -int CNativeWrapper::init(JNIEnv * env, void * bitmap, jobject * callback, int width, int height, const char * cfg_dir, const char * modules_dir, const char * cache_dir, const char * font_dir, const char * urlToLoad){ - LOGI("Initializing GPAC with URL=%s...", urlToLoad); - strcpy(m_cfg_dir, cfg_dir); - strcpy(m_modules_dir, modules_dir); - strcpy(m_cache_dir, cache_dir); - strcpy(m_font_dir, font_dir); - - char m_cfg_filename[GF_MAX_PATH]; - strcpy(m_cfg_filename, m_cfg_dir); - strcat(m_cfg_filename, "GPAC.cfg"); - - int m_Width = width; - int m_Height = height; - - int first_launch = 0; - const char *opt; - - m_window = env; - m_session = bitmap; - setJavaEnv(&mainJavaEnv, env, env->NewGlobalRef(*callback)); - if (pthread_setspecific( jni_thread_env_key, &mainJavaEnv)){ - LOGE("Failed to set specific thread data to jni_thread_env_key=%p for main thread !", jni_thread_env_key); - } - - m_mx = gf_mx_new("Osmo4"); - - //load config file - LOGI("Loading User Config %s...", "GPAC.cfg"); - m_user.config = gf_cfg_force_new(cfg_dir, "GPAC.cfg"); - SetupLogs(); - gf_set_progress_callback(this, Osmo4_progress_cbk); - - opt = gf_cfg_get_key(m_user.config, "General", "ModulesDirectory"); - if (!opt) { - FILE * fstart; - char msg[256]; - LOGI("First launch, initializing new Config %s...", "GPAC.cfg"); - /*hardcode module directory*/ - gf_cfg_set_key(m_user.config, "Downloader", "CleanCache", "yes"); - /*startup file*/ - snprintf(msg, 256, "%sgui/gui.bt", cfg_dir); - fstart = fopen(msg, "r"); - if (fstart){ - fclose(fstart); - gf_cfg_set_key(m_user.config, "General", "StartupFile", msg); - } else { - gf_cfg_set_key(m_user.config, "General", "#StartupFile", msg); - } - gf_cfg_set_key(m_user.config, "GUI", "UnhideControlPlayer", "1"); - /*setup UDP traffic autodetect*/ - gf_cfg_set_key(m_user.config, "Network", "AutoReconfigUDP", "yes"); - gf_cfg_set_key(m_user.config, "Network", "UDPTimeout", "10000"); - gf_cfg_set_key(m_user.config, "Network", "BufferLength", "3000"); - gf_cfg_set_key(m_user.config, "Compositor", "TextureTextMode", "Default"); - //gf_cfg_set_key(m_user.config, "Compositor", "FrameRate", "30"); - gf_cfg_set_key(m_user.config, "Audio", "ForceConfig", "no"); - gf_cfg_set_key(m_user.config, "Audio", "NumBuffers", "1"); - gf_cfg_set_key(m_user.config, "FontEngine", "FontReader", "ft_font"); - } - /* All of this has to be done for every instance */ - gf_cfg_set_key(m_user.config, "General", "ModulesDirectory", modules_dir ? modules_dir : GPAC_MODULES_DIR); - gf_cfg_set_key(m_user.config, "General", "CacheDirectory", cache_dir ? cache_dir : GPAC_CACHE_DIR); - gf_cfg_set_key(m_user.config, "General", "LastWorkingDir", cfg_dir); - gf_cfg_set_key(m_user.config, "FontEngine", "FontDirectory", GPAC_FONT_DIR); - gf_cfg_set_key(m_user.config, "Video", "DriverName", "Android Video Output"); - gf_cfg_set_key(m_user.config, "Audio", "DriverName", "Android Audio Output"); - - opt = gf_cfg_get_key(m_user.config, "General", "ModulesDirectory"); - LOGI("loading modules in directory %s...", opt); - m_user.modules = gf_modules_new(opt, m_user.config); - if (!m_user.modules || !gf_modules_get_count(m_user.modules)) { - LOGE("No modules found in directory %s !", opt); - if (m_user.modules) - gf_modules_del(m_user.modules); - gf_cfg_del(m_user.config); - m_user.config = NULL; - return Quit(KErrGeneral); - } - - /*we don't thread the visual compositor to be able to minimize the app and still have audio running*/ - m_user.init_flags = GF_TERM_NO_COMPOSITOR_THREAD | GF_TERM_NO_REGULATION; - //m_user.init_flags |= GF_TERM_NO_AUDIO; - m_user.opaque = this; - - m_user.os_window_handler = m_window; - m_user.os_display = m_session; - m_user.EventProc = GPAC_EventProc; - if (!javaVM){ - LOGE("NO JAVA VM FOUND, m_user=%p !!!!\n", &m_user); - return Quit(KErrGeneral); - } - - LOGD("Loading GPAC terminal, m_user=%p...", &m_user); - m_term = gf_term_new(&m_user); - if (!m_term) { - LOGE("Cannot load GPAC Terminal with m_user=%p", m_user); - MessageBox("Cannot load GPAC terminal", "Fatal Error", GF_SERVICE_ERROR); - gf_modules_del(m_user.modules); - m_user.modules = NULL; - gf_cfg_del(m_user.config); - m_user.config = NULL; - return Quit(KErrGeneral); - } - - //setAudioEnvironment(javaVM); - - LOGD("Setting term size m_user=%p...", &m_user); - gf_term_set_size(m_term, m_Width, m_Height); - - opt = gf_cfg_get_key(m_user.config, "General", "StartupFile"); - LOGD("File loaded at startup=%s.", opt); - - if (!urlToLoad) - urlToLoad = opt; - if (urlToLoad){ - LOGI("Connecting to %s...", urlToLoad); - gf_term_connect(m_term, urlToLoad); - } - debug_log("init end"); - LOGD("Saving config file %s...\n", m_cfg_filename); - gf_cfg_save(m_user.config); - LOGI("Initialization complete, config file saved as %s.\n", m_cfg_filename); - return 0; -} -//------------------------------- -int CNativeWrapper::connect(const char *url){ - if (m_term){ - debug_log("Starting to connect ..."); - gf_term_connect_from_time(m_term, url, 0, false); - debug_log("connected ..."); - } -} - -void CNativeWrapper::setGpacPreference( const char * category, const char * name, const char * value) -{ - if (m_user.config){ - gf_cfg_set_key(m_user.config, category, name, value); - gf_cfg_save(m_user.config); - } -} - -//----------------------------------------------------- -void CNativeWrapper::disconnect(){ - if (m_term){ - debug_log("disconnecting"); - gf_term_disconnect(m_term); - debug_log("disconnected ..."); - } -} -//----------------------------------------------------- -void CNativeWrapper::step(void * env, void * bitmap){ - m_window = env; - m_session = bitmap; - //debug_log("Step ..."); - if (!m_term){ - debug_log("step(): No m_term found."); - return; - } else - if (!m_term->compositor) - debug_log("step(): No compositor found."); - else if (!m_term->compositor->video_out) - debug_log("step(): No video_out found"); - else if (!m_term->compositor->video_out->Setup) - debug_log("step(): No video_out->Setup found"); - else { - //debug_log("step(): gf_term_process_step : start()"); - m_term->compositor->frame_draw_type = GF_SC_DRAW_FRAME; - gf_term_process_step(m_term); - //debug_log("step(): gf_term_process_step : end()"); - } -} - -//----------------------------------------------------- -void CNativeWrapper::setAudioEnvironment(JavaVM* javaVM){ - if (!m_term){ - debug_log("setAudioEnvironment(): no m_term found."); - return; - } - debug_log("setAudioEnvironment start"); - m_term->compositor->audio_renderer->audio_out->Setup(m_term->compositor->audio_renderer->audio_out, javaVM, 0, 0); - debug_log("setAudioEnvironment end"); -} -//----------------------------------------------------- -void CNativeWrapper::resize(int w, int h){ - if (!m_term) - return; - debug_log("resize start"); - gf_term_set_size(m_term, w, h); - debug_log("resize end"); -} -//----------------------------------------------------- -void CNativeWrapper::onMouseDown(float x, float y){ - if (!m_term) - return; - debug_log("onMouseDown start"); - //char msg[100]; - //sprintf(msg, "onMousedown x=%f, y=%f", x, y ); - //debug_log(msg); - - GF_Event evt; - evt.type = GF_EVENT_MOUSEDOWN; - evt.mouse.button = GF_MOUSE_LEFT; - evt.mouse.x = x; - evt.mouse.y = y; - - int ret = gf_term_user_event(m_term, &evt); - debug_log("onMouseDown end"); -} -//----------------------------------------------------- -void CNativeWrapper::onMouseUp(float x, float y){ - if (!m_term) - return; - debug_log("onMouseUp start"); - //char msg[100]; - //sprintf(msg, "onMouseUp x=%f, y=%f", x, y ); - //debug_log(msg); - - GF_Event evt; - evt.type = GF_EVENT_MOUSEUP; - evt.mouse.button = GF_MOUSE_LEFT; - evt.mouse.x = x; - evt.mouse.y = y; - - int ret = gf_term_user_event(m_term, &evt); - debug_log("onMouseUp end"); -} -//----------------------------------------------------- -void CNativeWrapper::onMouseMove(float x, float y){ - if (!m_term) - return; - GF_Event evt; - evt.type = GF_EVENT_MOUSEMOVE; - evt.mouse.button = GF_MOUSE_LEFT; - evt.mouse.x = x; - evt.mouse.y = y; - - int ret = gf_term_user_event(m_term, &evt); -} -//----------------------------------------------------- -void CNativeWrapper::onKeyPress(int keycode, int rawkeycode, int up, int flag, int unicode){ - if (!m_term) - return; - debug_log("onKeyPress start"); - GF_Event evt; - memset(&evt, 0, sizeof(GF_Event)); - if (up == 0) evt.type = GF_EVENT_KEYUP; - else evt.type = GF_EVENT_KEYDOWN; - - evt.key.flags = 0; - evt.key.hw_code = rawkeycode; - - translate_key(keycode, &evt.key); - //evt.key.key_code = GF_KEY_A; - int ret = gf_term_user_event(m_term, &evt); - - if (evt.type == GF_EVENT_KEYUP && unicode){ - memset(&evt, 0, sizeof(GF_Event)); - evt.type = GF_EVENT_TEXTINPUT; - evt.character.unicode_char = unicode; - ret = gf_term_user_event(m_term, &evt); - } -} -//----------------------------------------------------- -void CNativeWrapper::translate_key(ANDROID_KEYCODE keycode, GF_EventKey *evt){ - evt->flags = 0; - switch (keycode) { - case ANDROID_KEYCODE_BACK: evt->key_code = GF_KEY_BACKSPACE; break; - case ANDROID_KEYCODE_TAB: evt->key_code = GF_KEY_TAB; break; - case ANDROID_KEYCODE_CLEAR: evt->key_code = GF_KEY_CLEAR; break; - case ANDROID_KEYCODE_ENTER: evt->key_code = GF_KEY_ENTER; break; - case ANDROID_KEYCODE_SHIFT_LEFT: evt->key_code = GF_KEY_SHIFT; break; - case ANDROID_KEYCODE_SHIFT_RIGHT: evt->key_code = GF_KEY_SHIFT; break; - case ANDROID_KEYCODE_ALT_LEFT: evt->key_code = GF_KEY_ALT; break; - case ANDROID_KEYCODE_ALT_RIGHT: evt->key_code = GF_KEY_ALT; break; - case ANDROID_KEYCODE_SPACE: evt->key_code = GF_KEY_SPACE; break; - case ANDROID_KEYCODE_HOME: evt->key_code = GF_KEY_HOME; break; - case ANDROID_KEYCODE_DPAD_LEFT: evt->key_code = GF_KEY_LEFT; break; - case ANDROID_KEYCODE_DPAD_UP: evt->key_code = GF_KEY_UP; break; - case ANDROID_KEYCODE_DPAD_RIGHT: evt->key_code = GF_KEY_RIGHT; break; - case ANDROID_KEYCODE_DPAD_DOWN: evt->key_code = GF_KEY_DOWN; break; - case ANDROID_KEYCODE_DEL: evt->key_code = GF_KEY_DEL; break; - case ANDROID_KEYCODE_0: - evt->key_code = GF_KEY_0; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case ANDROID_KEYCODE_1: - evt->key_code = GF_KEY_1; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case ANDROID_KEYCODE_2: - evt->key_code = GF_KEY_2; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case ANDROID_KEYCODE_3: - evt->key_code = GF_KEY_3; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case ANDROID_KEYCODE_4: - evt->key_code = GF_KEY_4; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case ANDROID_KEYCODE_5: - evt->key_code = GF_KEY_5; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case ANDROID_KEYCODE_6: - evt->key_code = GF_KEY_6; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case ANDROID_KEYCODE_7: - evt->key_code = GF_KEY_7; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case ANDROID_KEYCODE_8: - evt->key_code = GF_KEY_8; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - case ANDROID_KEYCODE_9: - evt->key_code = GF_KEY_9; - evt->flags = GF_KEY_EXT_NUMPAD; - break; - /*thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) */ - /* VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */ - default: - if ((keycode>=ANDROID_KEYCODE_A) && (keycode<=ANDROID_KEYCODE_Z)){ - evt->key_code = GF_KEY_A + keycode - ANDROID_KEYCODE_A; - } else { - evt->key_code = GF_KEY_UNIDENTIFIED; - } - break; - } - evt->hw_code = evt->key_code; -} - -//--------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------- +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) ENST 2009- + * Authors: Jean Le Feuvre + * All rights reserved + * + * Created by NGO Van Luyen, Ivica ARSOV / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010 + * + * This file is part of GPAC / Wrapper + * + * 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 + +#include +#include +#include +#include +#include +#include + +#include "wrapper.h" +#include "wrapper_jni.c" + +#include +#include + +#define TAG "GPAC_WRAPPER" + +#define LOGV(X, Y) __android_log_print(ANDROID_LOG_VERBOSE, TAG, X, Y) +#define LOGD(X, Y) __android_log_print(ANDROID_LOG_DEBUG, TAG, X, Y) +#define LOGE(X, Y) __android_log_print(ANDROID_LOG_ERROR, TAG, X, Y) +#define LOGW(X, Y) __android_log_print(ANDROID_LOG_WARN, TAG, X, Y) +#define LOGI(X, Y) __android_log_print(ANDROID_LOG_INFO, TAG, X, Y) +#include + +static JavaVM* javaVM = NULL; + +static pthread_key_t jni_thread_env_key = 0; + +/** + * This method is called when a pthread is destroyed, so we can delete the JNI env + */ +static void jni_destroy_env_func(void * env) { + LOGI("Destroying a thread with attached data, env=%p.\n", env); + JavaEnvTh * jniEnv = (JavaEnvTh *) env; + if (jniEnv){ + /*jniEnv->env->DeleteLocalRef(&jniEnv->cbk_displayMessage); + jniEnv->env->DeleteLocalRef(&jniEnv->cbk_onProgress); + jniEnv->env->DeleteLocalRef(&jniEnv->cbk_showKeyboard); + jniEnv->env->DeleteLocalRef(&jniEnv->cbk_setCaption); + jniEnv->env->DeleteLocalRef(&jniEnv->cbk_onLog);*/ + memset(jniEnv, 0, sizeof(JavaEnvTh)); + gf_free(jniEnv); + } + pthread_setspecific(jni_thread_env_key, NULL); + if (javaVM) + javaVM->DetachCurrentThread(); +} + +static int jniRegisterNativeMethods(JNIEnv* env, const char* className, + const JNINativeMethod* gMethods, int numMethods) +{ + jclass clazz; + clazz = env->FindClass(className); + if (clazz == NULL) { + LOGE("Native registration unable to find class '%s'\n", className); + return -1; + } + if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) { + LOGE("RegisterNatives failed for '%s'\n", className); + return -1; + } + return 0; +} + +static JNINativeMethod sMethods[] = { + /* name, signature, funcPtr */ + + {"createInstance", + "(Lcom/gpac/Osmo4/GpacCallback;IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)J", + (void*)&Java_com_gpac_Osmo4_GPACInstance_createInstance}, + {"gpacdisconnect", + "()V", + (void*)Java_com_gpac_Osmo4_GPACInstance_gpacdisconnect}, + {"gpacrender", + "()V", + (void*)Java_com_gpac_Osmo4_GPACInstance_gpacrender}, + {"gpacresize", + "(II)V", + (void*)Java_com_gpac_Osmo4_GPACInstance_gpacresize}, + {"gpacfree", + "()V", + (void*)Java_com_gpac_Osmo4_GPACInstance_gpacfree}, + {"gpaceventkeypress", + "(IIIII)V", + (void*)Java_com_gpac_Osmo4_GPACInstance_gpaceventkeypress}, + {"gpaceventmousedown", + "(FF)V", + (void*)Java_com_gpac_Osmo4_GPACInstance_gpaceventmousedown}, + {"gpaceventmouseup", + "(FF)V", + (void*)Java_com_gpac_Osmo4_GPACInstance_gpaceventmouseup}, + {"gpaceventmousemove", + "(FF)V", + (void*)Java_com_gpac_Osmo4_GPACInstance_gpaceventmousemove}, + {"setGpacPreference", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V", + (void*)Java_com_gpac_Osmo4_GPACInstance_setGpacPreference}, + NULL +}; + + +jint JNI_OnUnLoad(JavaVM* vm, void* reserved){ + LOGI("Deleting library, vm=%p...\n", vm); + if (pthread_key_delete(jni_thread_env_key)){ + LOGW("Failed to delete key jni_thread_env_key jni_thread_env_key=%p\n", jni_thread_env_key); + } + javaVM = NULL; + jni_thread_env_key = NULL; +} + +//--------------------------------------------------------------------------------------------------- +jint JNI_OnLoad(JavaVM* vm, void* reserved){ + const char * className = "com/gpac/Osmo4/GPACInstance"; + JNIEnv * env; + if (!vm) + return -1; + if (vm->GetEnv((void**)(&env), JNI_VERSION_1_2) != JNI_OK) + return -1; + javaVM = vm; + LOGI("Registering %s natives\n", className); + if (jniRegisterNativeMethods(env, className, sMethods, 9) < 0){ + LOGE("Failed to register native methods for %s !\n", className); + return -1; + } + LOGI("Registering natives DONE, now registering pthread_keys with destructor=%p\n", &jni_destroy_env_func); + int ret = pthread_key_create(&jni_thread_env_key, &jni_destroy_env_func); + if (ret){ + LOGE("Failed to register jni_thread_env_key jni_thread_env_key=%p\n", jni_thread_env_key); + } + return JNI_VERSION_1_2; +} + +//--------------------------------------------------------------------------------------------------- +//CNativeWrapper +//------------------------------- + +CNativeWrapper::CNativeWrapper(){ + do_log = 1; + m_term = NULL; + m_mx = NULL; +#ifndef GPAC_GUI_ONLY + memset(&m_user, 0, sizeof(GF_User)); + memset(&m_rti, 0, sizeof(GF_SystemRTInfo)); +#endif +} +//------------------------------- +CNativeWrapper::~CNativeWrapper(){ + debug_log("~CNativeWrapper()"); + JavaEnvTh * env = getEnv(); + if (env && env->cbk_obj) + env->env->DeleteGlobalRef(env->cbk_obj); + Shutdown(); + debug_log("~CNativeWrapper() : DONE\n"); +} +//------------------------------- +void CNativeWrapper::debug_log(const char* msg){ + LOGV("%s", msg); +} +//------------------------------- +void CNativeWrapper::Shutdown() +{ + debug_log("shutdown"); + if (m_term) + gf_term_disconnect(m_term); + if (m_mx) + gf_mx_del(m_mx); + m_mx = NULL; +#ifndef GPAC_GUI_ONLY + if (m_term) { + GF_Terminal *t = m_term; + m_term = NULL; + gf_term_del(t); + } + if (m_user.config) { + gf_cfg_del(m_user.config); + m_user.config = NULL; + } + if (m_user.modules) { + gf_modules_del(m_user.modules); + m_user.modules = NULL; + } +#endif + m_term = NULL; + debug_log("shutdown end"); +} + +void CNativeWrapper::setJavaEnv(JavaEnvTh * envToSet, JNIEnv *env, jobject callback){ + assert( envToSet ); + jclass localRef = env->GetObjectClass(callback); + envToSet->env = env; + envToSet->javaThreadId = gf_th_id(); + envToSet->cbk_obj = callback; + envToSet->cbk_displayMessage = + env->GetMethodID(localRef, "displayMessage", "(Ljava/lang/String;Ljava/lang/String;I)V"); + envToSet->cbk_onProgress = + env->GetMethodID(localRef, "onProgress", "(Ljava/lang/String;II)V"); + envToSet->cbk_onLog = + env->GetMethodID(localRef, "onLog", "(IILjava/lang/String;)V"); + envToSet->cbk_setCaption = + env->GetMethodID(localRef, "setCaption", "(Ljava/lang/String;)V"); + envToSet->cbk_showKeyboard = + env->GetMethodID(localRef, "showKeyboard", "(Z)V"); + env->DeleteLocalRef(localRef); +} + +static u32 beforeThreadExits(void * param){ + LOGI("Before Thread exist, detach the JavaVM from Thread for thread %p...\n", gf_th_current()); + if (javaVM) + javaVM->DetachCurrentThread(); +} + +JavaEnvTh * CNativeWrapper::getEnv(){ + JNIEnv *env; + JavaEnvTh * javaEnv; + if (!javaVM){ + debug_log("************* No JVM Found ************"); + return NULL; + } + javaEnv = (JavaEnvTh*) pthread_getspecific( jni_thread_env_key ); + if (javaEnv) + return javaEnv; + javaEnv = (JavaEnvTh *) gf_malloc(sizeof(JavaEnvTh)); + if (!javaEnv) + return NULL; + memset(javaEnv, 0, sizeof(JavaEnvTh)); + javaVM->AttachCurrentThread(&env, NULL); + if (!env){ + LOGE("Attaching to thread did faild for thread id=%d", gf_th_id()); + gf_free(javaEnv); + return NULL; + } + LOGI("Rebuilding methods for thread %d", gf_th_id()); + setJavaEnv(javaEnv, env, mainJavaEnv.cbk_obj); + if (pthread_setspecific(jni_thread_env_key, javaEnv)){ + LOGE("Failed to set specific thread data to jni_thread_env_key for thread=%d. No ENV available !", gf_th_id()); + gf_free(javaEnv); + return NULL; + } + GF_Thread * t; + LOGI("Getting current Thread %d...", gf_th_id()); + t = gf_th_current(); + LOGI("Getting current Thread DONE = %p, now registering before exit...", t); + + if (GF_OK != gf_register_before_exit_function(gf_th_current(), &beforeThreadExits)){ + LOGE("Failed to register exit function for thread %p, no javaEnv for current thread.", gf_th_current()); + //javaVM->DetachCurrentThread(); + gf_free(javaEnv); + javaEnv = NULL; + } + LOGI("Registering DONE for %d", gf_th_id()); + return javaEnv; +} + + +//------------------------------- +int CNativeWrapper::MessageBox(const char* msg, const char* title, GF_Err status){ + LOGV("MessageBox start %s", msg); + JavaEnvTh * env = getEnv(); + if (!env || !env->cbk_displayMessage) + return 0; + env->env->PushLocalFrame(2); + jstring tit = env->env->NewStringUTF(title?title:"null"); + jstring mes = env->env->NewStringUTF(msg?msg:"null"); + env->env->CallVoidMethod(env->cbk_obj, env->cbk_displayMessage, mes, tit, status); + env->env->PopLocalFrame(NULL); + LOGV("MessageBox done %s", msg); + return 1; +} +//------------------------------- +void CNativeWrapper::DisplayRTI(){ +#ifndef GPAC_GUI_ONLY + // display some system informations ? +#endif +} +//------------------------------- +int CNativeWrapper::Quit(int code){ + + Shutdown(); + // send shutdown request to java + return code; +} + +#include + +//------------------------------- +void CNativeWrapper::on_gpac_log(void *cbk, u32 ll, u32 lm, const char *fmt, va_list list){ + char szMsg[4096]; + const char * tag; + char unknTag[32]; + int debug; + // We do not want to be flood by mutexes + if (ll == GF_LOG_DEBUG && lm == GF_LOG_MUTEX) + return; + switch (ll){ + case GF_LOG_DEBUG: + debug = ANDROID_LOG_DEBUG; + break; + case GF_LOG_INFO: + debug = ANDROID_LOG_INFO; + break; + case GF_LOG_WARNING: + debug = ANDROID_LOG_WARN; + break; + case GF_LOG_ERROR: + debug = ANDROID_LOG_ERROR; + break; + default: + debug = ANDROID_LOG_INFO; + } + vsnprintf(szMsg, 4096, fmt, list); + CNativeWrapper * self = (CNativeWrapper *) cbk; + if (!self) + goto displayInAndroidlogs; + + { + JavaEnvTh *env = self->getEnv(); + jstring msg; + if (!env || !env->cbk_onLog) + goto displayInAndroidlogs; + env->env->PushLocalFrame(1); + msg = env->env->NewStringUTF(szMsg); + env->env->CallVoidMethod(env->cbk_obj, env->cbk_onLog, debug, lm, msg); + env->env->PopLocalFrame(NULL); + return; + } +displayInAndroidlogs: + { + /* When no callback is properly set, we use direct logging */ + switch( lm){ + case GF_LOG_CORE: + tag="GF_LOG_CORE"; + break; + case GF_LOG_CODING: + tag="GF_LOG_CODING"; + break; + case GF_LOG_CONTAINER: + tag="GF_LOG_CONTAINER"; + break; + case GF_LOG_NETWORK: + tag="GF_LOG_NETWORK"; + break; + case GF_LOG_RTP: + tag="GF_LOG_RTP"; + break; + case GF_LOG_AUTHOR: + tag="GF_LOG_AUTHOR"; + break; + case GF_LOG_SYNC: + tag="GF_LOG_SYNC"; + break; + case GF_LOG_CODEC: + tag="GF_LOG_CODEC"; + break; + case GF_LOG_PARSER: + tag="GF_LOG_PARSER"; + break; + case GF_LOG_MEDIA: + tag="GF_LOG_MEDIA"; + break; + case GF_LOG_SCENE: + tag="GF_LOG_SCENE"; + break; + case GF_LOG_SCRIPT: + tag="GF_LOG_SCRIPT"; + break; + case GF_LOG_INTERACT: + tag="GF_LOG_INTERACT"; + break; + case GF_LOG_COMPOSE: + tag="GF_LOG_COMPOSE"; + break; + case GF_LOG_CACHE: + tag="GF_LOG_CACHE"; + break; + case GF_LOG_MMIO: + tag="GF_LOG_MMIO"; + break; + case GF_LOG_RTI: + tag="GF_LOG_RTI"; + break; + case GF_LOG_SMIL: + tag="GF_LOG_SMIL"; + break; + case GF_LOG_MEMORY: + tag="GF_LOG_MEMORY"; + break; + case GF_LOG_AUDIO: + tag="GF_LOG_AUDIO"; + break; + case GF_LOG_MODULE: + tag="GF_LOG_MODULE"; + break; + case GF_LOG_MUTEX: + tag="GF_LOG_MUTEX"; + break; + default: + snprintf(unknTag, 32, "GPAC_UNKNOWN[%d]", lm); + tag = unknTag; + } + __android_log_print(debug, tag, szMsg); + } +} +//------------------------------- +Bool CNativeWrapper::GPAC_EventProc(void *cbk, GF_Event *evt){ + if (cbk) + { + CNativeWrapper* ptr = (CNativeWrapper*)cbk; + char msg[4096]; + msg[0] = 0; + LOGD("GPAC_EventProc() Message=%d", evt->type); + switch (evt->type){ + case GF_EVENT_CLICK: + case GF_EVENT_MOUSEUP: + case GF_EVENT_MOUSEDOWN: + case GF_EVENT_MOUSEOVER: + case GF_EVENT_MOUSEOUT: + case GF_EVENT_MOUSEMOVE: + case GF_EVENT_MOUSEWHEEL: + case GF_EVENT_KEYUP: + case GF_EVENT_KEYDOWN: + case GF_EVENT_LONGKEYPRESS: + case GF_EVENT_TEXTINPUT: + /* We ignore all these events */ + break; + case GF_EVENT_MEDIA_BEGIN_SESSION_SETUP: + case GF_EVENT_MEDIA_END_SESSION_SETUP: + case GF_EVENT_MEDIA_DATA_REQUEST: + case GF_EVENT_MEDIA_PLAYABLE: + case GF_EVENT_MEDIA_NOT_PLAYABLE: + case GF_EVENT_MEDIA_DATA_PROGRESS: + case GF_EVENT_MEDIA_END_OF_DATA: + case GF_EVENT_MEDIA_STOP: + case GF_EVENT_MEDIA_ERROR: + LOGD("GPAC_EventProc() Media Event detected = [index=%d]", evt->type - GF_EVENT_MEDIA_BEGIN_SESSION_SETUP); + break; + case GF_EVENT_MESSAGE: + { + ptr->debug_log("GPAC_EventProc start"); + if ( evt->message.message ) + { + strcat(msg, evt->message.message); + strcat(msg, ": "); + } + strcat(msg, gf_error_to_string(evt->message.error)); + + ptr->debug_log(msg); + ptr->MessageBox(msg, evt->message.service ? evt->message.service : "GF_EVENT_MESSAGE", evt->message.error); + ptr->debug_log("GPAC_EventProc end"); + }; + break; + case GF_EVENT_CONNECT: + if (evt->connect.is_connected) + ptr->MessageBox("Connected", "Connected to scene", GF_OK); + else + ptr->MessageBox("Disconnected", "Disconnected from scene.", GF_OK); + break; + case GF_EVENT_PROGRESS: + { + const char * szTitle;; + if (evt->progress.progress_type==0) + szTitle = "Buffering"; + else if (evt->progress.progress_type==1) + szTitle = "Downloading..."; + else if (evt->progress.progress_type==2) + szTitle = "Import "; + else + szTitle = "Unknown Progress Event"; + ptr->Osmo4_progress_cbk(ptr, szTitle, evt->progress.done, evt->progress.total); + gf_set_progress(szTitle, evt->progress.done, evt->progress.total); + } + break; + case GF_EVENT_TEXT_EDITING_START: + case GF_EVENT_TEXT_EDITING_END: + { + JavaEnvTh * env = ptr->getEnv(); + if (!env || !env->cbk_showKeyboard) + return 0; + LOGI("Needs to display/hide the Virtual Keyboard (%d)", evt->type); + env->env->CallVoidMethod(env->cbk_obj, env->cbk_showKeyboard, GF_EVENT_TEXT_EDITING_START == evt->type); + LOGV("Done showing virtual keyboard (%d)", evt->type); + } + break; + case GF_EVENT_EOS: + LOGI("EOS Reached (%d)", evt->type); + break; + case GF_EVENT_DISCONNECT: + /* FIXME : not sure about this behaviour */ + if (ptr) + ptr->disconnect(); + break; + case GF_EVENT_NAVIGATE: + ptr->navigate( evt); + break; + default: + LOGI("Unknown Message %d", evt->type); + } + } + return 0; +} + +void CNativeWrapper::navigate( GF_Event* evt) +{ + if (gf_term_is_supported_url(m_term, evt->navigate.to_url, 1, 1)) + { + gf_term_navigate_to(m_term, evt->navigate.to_url); + } +} + +void CNativeWrapper::progress_cbk(const char *title, u64 done, u64 total){ + JavaEnvTh *env = getEnv(); + if (!env || !env->cbk_onProgress) + return; + debug_log("Osmo4_progress_cbk start"); + env->env->PushLocalFrame(1); + jstring js = env->env->NewStringUTF(title); + env->env->CallVoidMethod(env->cbk_obj, env->cbk_onProgress, js, done, total); + env->env->PopLocalFrame(NULL); + debug_log("Osmo4_progress_cbk end"); +} + + +//------------------------------- +void CNativeWrapper::Osmo4_progress_cbk(const void *usr, const char *title, u64 done, u64 total){ + if (!usr) + return; + CNativeWrapper * self = (CNativeWrapper *) usr; + self->progress_cbk(title, done, total); +} +//------------------------------- +void CNativeWrapper::SetupLogs(){ + const char *opt; + debug_log("SetupLogs()"); + + gf_mx_p(m_mx); + + u32 ll = gf_log_parse_level( gf_cfg_get_key(m_user.config, "General", "LogLevel") ); + gf_log_set_level(ll); + u32 lt = gf_log_parse_tools( gf_cfg_get_key(m_user.config, "General", "LogTools") ); + gf_log_set_tools(lt); + + gf_log_set_callback(this, on_gpac_log); + gf_mx_v(m_mx); + + GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("Osmo4 logs initialized\n")); + /* Test for JNI invocations, should work properly + int k; + for (k = 0 ; k < 512; k++){ + GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("Message %d\n", k)); + }*/ +} +//------------------------------- +// dir should end with / +int CNativeWrapper::init(JNIEnv * env, void * bitmap, jobject * callback, int width, int height, const char * cfg_dir, const char * modules_dir, const char * cache_dir, const char * font_dir, const char * urlToLoad){ + LOGI("Initializing GPAC with URL=%s...", urlToLoad); + strcpy(m_cfg_dir, cfg_dir); + strcpy(m_modules_dir, modules_dir); + strcpy(m_cache_dir, cache_dir); + strcpy(m_font_dir, font_dir); + + char m_cfg_filename[GF_MAX_PATH]; + strcpy(m_cfg_filename, m_cfg_dir); + strcat(m_cfg_filename, "GPAC.cfg"); + + int m_Width = width; + int m_Height = height; + + int first_launch = 0; + const char *opt; + + m_window = env; + m_session = bitmap; + setJavaEnv(&mainJavaEnv, env, env->NewGlobalRef(*callback)); + if (pthread_setspecific( jni_thread_env_key, &mainJavaEnv)){ + LOGE("Failed to set specific thread data to jni_thread_env_key=%p for main thread !", jni_thread_env_key); + } + + m_mx = gf_mx_new("Osmo4"); + + //load config file + LOGI("Loading User Config %s...", "GPAC.cfg"); + m_user.config = gf_cfg_force_new(cfg_dir, "GPAC.cfg"); + SetupLogs(); + gf_set_progress_callback(this, Osmo4_progress_cbk); + + opt = gf_cfg_get_key(m_user.config, "General", "ModulesDirectory"); + if (!opt) { + FILE * fstart; + char msg[256]; + LOGI("First launch, initializing new Config %s...", "GPAC.cfg"); + /*hardcode module directory*/ + gf_cfg_set_key(m_user.config, "Downloader", "CleanCache", "yes"); + /*startup file*/ + snprintf(msg, 256, "%sgui/gui.bt", cfg_dir); + fstart = fopen(msg, "r"); + if (fstart){ + fclose(fstart); + gf_cfg_set_key(m_user.config, "General", "StartupFile", msg); + } else { + gf_cfg_set_key(m_user.config, "General", "#StartupFile", msg); + } + gf_cfg_set_key(m_user.config, "GUI", "UnhideControlPlayer", "1"); + /*setup UDP traffic autodetect*/ + gf_cfg_set_key(m_user.config, "Network", "AutoReconfigUDP", "yes"); + gf_cfg_set_key(m_user.config, "Network", "UDPTimeout", "10000"); + gf_cfg_set_key(m_user.config, "Network", "BufferLength", "3000"); + gf_cfg_set_key(m_user.config, "Compositor", "TextureTextMode", "Default"); + //gf_cfg_set_key(m_user.config, "Compositor", "FrameRate", "30"); + gf_cfg_set_key(m_user.config, "Audio", "ForceConfig", "no"); + gf_cfg_set_key(m_user.config, "Audio", "NumBuffers", "1"); + gf_cfg_set_key(m_user.config, "FontEngine", "FontReader", "ft_font"); + } + /* All of this has to be done for every instance */ + gf_cfg_set_key(m_user.config, "General", "ModulesDirectory", modules_dir ? modules_dir : GPAC_MODULES_DIR); + gf_cfg_set_key(m_user.config, "General", "CacheDirectory", cache_dir ? cache_dir : GPAC_CACHE_DIR); + gf_cfg_set_key(m_user.config, "General", "LastWorkingDir", cfg_dir); + gf_cfg_set_key(m_user.config, "FontEngine", "FontDirectory", GPAC_FONT_DIR); + gf_cfg_set_key(m_user.config, "Video", "DriverName", "Android Video Output"); + gf_cfg_set_key(m_user.config, "Audio", "DriverName", "Android Audio Output"); + + opt = gf_cfg_get_key(m_user.config, "General", "ModulesDirectory"); + LOGI("loading modules in directory %s...", opt); + m_user.modules = gf_modules_new(opt, m_user.config); + if (!m_user.modules || !gf_modules_get_count(m_user.modules)) { + LOGE("No modules found in directory %s !", opt); + if (m_user.modules) + gf_modules_del(m_user.modules); + gf_cfg_del(m_user.config); + m_user.config = NULL; + return Quit(KErrGeneral); + } + + /*we don't thread the visual compositor to be able to minimize the app and still have audio running*/ + m_user.init_flags = GF_TERM_NO_COMPOSITOR_THREAD | GF_TERM_NO_REGULATION; + //m_user.init_flags |= GF_TERM_NO_AUDIO; + m_user.opaque = this; + + m_user.os_window_handler = m_window; + m_user.os_display = m_session; + m_user.EventProc = GPAC_EventProc; + if (!javaVM){ + LOGE("NO JAVA VM FOUND, m_user=%p !!!!\n", &m_user); + return Quit(KErrGeneral); + } + + LOGD("Loading GPAC terminal, m_user=%p...", &m_user); + m_term = gf_term_new(&m_user); + if (!m_term) { + LOGE("Cannot load GPAC Terminal with m_user=%p", m_user); + MessageBox("Cannot load GPAC terminal", "Fatal Error", GF_SERVICE_ERROR); + gf_modules_del(m_user.modules); + m_user.modules = NULL; + gf_cfg_del(m_user.config); + m_user.config = NULL; + return Quit(KErrGeneral); + } + + //setAudioEnvironment(javaVM); + + LOGD("Setting term size m_user=%p...", &m_user); + gf_term_set_size(m_term, m_Width, m_Height); + + opt = gf_cfg_get_key(m_user.config, "General", "StartupFile"); + LOGD("File loaded at startup=%s.", opt); + + if (!urlToLoad) + urlToLoad = opt; + if (urlToLoad){ + LOGI("Connecting to %s...", urlToLoad); + gf_term_connect(m_term, urlToLoad); + } + debug_log("init end"); + LOGD("Saving config file %s...\n", m_cfg_filename); + gf_cfg_save(m_user.config); + LOGI("Initialization complete, config file saved as %s.\n", m_cfg_filename); + + return 0; +} +//------------------------------- +int CNativeWrapper::connect(const char *url){ + if (m_term){ + debug_log("Starting to connect ..."); + gf_term_connect_from_time(m_term, url, 0, false); + debug_log("connected ..."); + } +} + +void CNativeWrapper::setGpacPreference( const char * category, const char * name, const char * value) +{ + if (m_user.config){ + gf_cfg_set_key(m_user.config, category, name, value); + gf_cfg_save(m_user.config); + } +} + +//----------------------------------------------------- +void CNativeWrapper::disconnect(){ + if (m_term){ + debug_log("disconnecting"); + gf_term_disconnect(m_term); + debug_log("disconnected ..."); + } +} +//----------------------------------------------------- +void CNativeWrapper::step(void * env, void * bitmap){ + m_window = env; + m_session = bitmap; + //debug_log("Step ..."); + if (!m_term){ + debug_log("step(): No m_term found."); + return; + } else + if (!m_term->compositor) + debug_log("step(): No compositor found."); + else if (!m_term->compositor->video_out) + debug_log("step(): No video_out found"); + else if (!m_term->compositor->video_out->Setup) + debug_log("step(): No video_out->Setup found"); + else { + //debug_log("step(): gf_term_process_step : start()"); + m_term->compositor->frame_draw_type = GF_SC_DRAW_FRAME; + gf_term_process_step(m_term); + //debug_log("step(): gf_term_process_step : end()"); + } +} + +//----------------------------------------------------- +void CNativeWrapper::setAudioEnvironment(JavaVM* javaVM){ + if (!m_term){ + debug_log("setAudioEnvironment(): no m_term found."); + return; + } + debug_log("setAudioEnvironment start"); + m_term->compositor->audio_renderer->audio_out->Setup(m_term->compositor->audio_renderer->audio_out, javaVM, 0, 0); + debug_log("setAudioEnvironment end"); +} +//----------------------------------------------------- +void CNativeWrapper::resize(int w, int h){ + if (!m_term) + return; + debug_log("resize start"); + gf_term_set_size(m_term, w, h); + debug_log("resize end"); +} +//----------------------------------------------------- +void CNativeWrapper::onMouseDown(float x, float y){ + if (!m_term) + return; + debug_log("onMouseDown start"); + //char msg[100]; + //sprintf(msg, "onMousedown x=%f, y=%f", x, y ); + //debug_log(msg); + + GF_Event evt; + evt.type = GF_EVENT_MOUSEDOWN; + evt.mouse.button = GF_MOUSE_LEFT; + evt.mouse.x = x; + evt.mouse.y = y; + + int ret = gf_term_user_event(m_term, &evt); + debug_log("onMouseDown end"); +} +//----------------------------------------------------- +void CNativeWrapper::onMouseUp(float x, float y){ + if (!m_term) + return; + debug_log("onMouseUp start"); + //char msg[100]; + //sprintf(msg, "onMouseUp x=%f, y=%f", x, y ); + //debug_log(msg); + + GF_Event evt; + evt.type = GF_EVENT_MOUSEUP; + evt.mouse.button = GF_MOUSE_LEFT; + evt.mouse.x = x; + evt.mouse.y = y; + + int ret = gf_term_user_event(m_term, &evt); + debug_log("onMouseUp end"); +} +//----------------------------------------------------- +void CNativeWrapper::onMouseMove(float x, float y){ + if (!m_term) + return; + GF_Event evt; + evt.type = GF_EVENT_MOUSEMOVE; + evt.mouse.button = GF_MOUSE_LEFT; + evt.mouse.x = x; + evt.mouse.y = y; + + int ret = gf_term_user_event(m_term, &evt); +} +//----------------------------------------------------- +void CNativeWrapper::onKeyPress(int keycode, int rawkeycode, int up, int flag, int unicode){ + if (!m_term) + return; + debug_log("onKeyPress start"); + GF_Event evt; + memset(&evt, 0, sizeof(GF_Event)); + if (up == 0) evt.type = GF_EVENT_KEYUP; + else evt.type = GF_EVENT_KEYDOWN; + + evt.key.flags = 0; + evt.key.hw_code = rawkeycode; + + translate_key(keycode, &evt.key); + //evt.key.key_code = GF_KEY_A; + int ret = gf_term_user_event(m_term, &evt); + + if (evt.type == GF_EVENT_KEYUP && unicode){ + memset(&evt, 0, sizeof(GF_Event)); + evt.type = GF_EVENT_TEXTINPUT; + evt.character.unicode_char = unicode; + ret = gf_term_user_event(m_term, &evt); + } +} +//----------------------------------------------------- +void CNativeWrapper::translate_key(ANDROID_KEYCODE keycode, GF_EventKey *evt){ + evt->flags = 0; + switch (keycode) { + case ANDROID_KEYCODE_BACK: evt->key_code = GF_KEY_BACKSPACE; break; + case ANDROID_KEYCODE_TAB: evt->key_code = GF_KEY_TAB; break; + case ANDROID_KEYCODE_CLEAR: evt->key_code = GF_KEY_CLEAR; break; + case ANDROID_KEYCODE_ENTER: evt->key_code = GF_KEY_ENTER; break; + case ANDROID_KEYCODE_SHIFT_LEFT: evt->key_code = GF_KEY_SHIFT; break; + case ANDROID_KEYCODE_SHIFT_RIGHT: evt->key_code = GF_KEY_SHIFT; break; + case ANDROID_KEYCODE_ALT_LEFT: evt->key_code = GF_KEY_ALT; break; + case ANDROID_KEYCODE_ALT_RIGHT: evt->key_code = GF_KEY_ALT; break; + case ANDROID_KEYCODE_SPACE: evt->key_code = GF_KEY_SPACE; break; + case ANDROID_KEYCODE_HOME: evt->key_code = GF_KEY_HOME; break; + case ANDROID_KEYCODE_DPAD_LEFT: evt->key_code = GF_KEY_LEFT; break; + case ANDROID_KEYCODE_DPAD_UP: evt->key_code = GF_KEY_UP; break; + case ANDROID_KEYCODE_DPAD_RIGHT: evt->key_code = GF_KEY_RIGHT; break; + case ANDROID_KEYCODE_DPAD_DOWN: evt->key_code = GF_KEY_DOWN; break; + case ANDROID_KEYCODE_DEL: evt->key_code = GF_KEY_DEL; break; + case ANDROID_KEYCODE_0: + evt->key_code = GF_KEY_0; + evt->flags = GF_KEY_EXT_NUMPAD; + break; + case ANDROID_KEYCODE_1: + evt->key_code = GF_KEY_1; + evt->flags = GF_KEY_EXT_NUMPAD; + break; + case ANDROID_KEYCODE_2: + evt->key_code = GF_KEY_2; + evt->flags = GF_KEY_EXT_NUMPAD; + break; + case ANDROID_KEYCODE_3: + evt->key_code = GF_KEY_3; + evt->flags = GF_KEY_EXT_NUMPAD; + break; + case ANDROID_KEYCODE_4: + evt->key_code = GF_KEY_4; + evt->flags = GF_KEY_EXT_NUMPAD; + break; + case ANDROID_KEYCODE_5: + evt->key_code = GF_KEY_5; + evt->flags = GF_KEY_EXT_NUMPAD; + break; + case ANDROID_KEYCODE_6: + evt->key_code = GF_KEY_6; + evt->flags = GF_KEY_EXT_NUMPAD; + break; + case ANDROID_KEYCODE_7: + evt->key_code = GF_KEY_7; + evt->flags = GF_KEY_EXT_NUMPAD; + break; + case ANDROID_KEYCODE_8: + evt->key_code = GF_KEY_8; + evt->flags = GF_KEY_EXT_NUMPAD; + break; + case ANDROID_KEYCODE_9: + evt->key_code = GF_KEY_9; + evt->flags = GF_KEY_EXT_NUMPAD; + break; + /*thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) */ + /* VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */ + default: + if ((keycode>=ANDROID_KEYCODE_A) && (keycode<=ANDROID_KEYCODE_Z)){ + evt->key_code = GF_KEY_A + keycode - ANDROID_KEYCODE_A; + } else { + evt->key_code = GF_KEY_UNIDENTIFIED; + } + break; + } + evt->hw_code = evt->key_code; +} + +//--------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------- diff --git a/applications/osmo4_android/jni/wrapper.h b/applications/osmo4_android/jni/wrapper.h index e220627..1cd231d 100644 --- a/applications/osmo4_android/jni/wrapper.h +++ b/applications/osmo4_android/jni/wrapper.h @@ -1,227 +1,228 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) ENST 2009- - * Authors: Jean Le Feuvre - * All rights reserved - * - * Created by NGO Van Luyen, Ivica ARSOV / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010 - * - * This file is part of GPAC / Wrapper - * - * 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 - -#include -#include -#include -#include - -//#define MAX_PATH 255 - -#define KErrGeneral 1 -//#define GPAC_CFG_DIR "/data/osmo/" -#define GPAC_CFG_DIR m_cfg_dir -//#define GPAC_MODULES_DIR "/data/osmo/modules/" -#define GPAC_MODULES_DIR m_modules_dir -//#define GPAC_MODULES_PATH "/data/osmo/modules/" -#define GPAC_MODULES_PATH m_modules_dir -//#define GPAC_CACHE_DIR "/data/osmo/cache/" -#define GPAC_CACHE_DIR m_cache_dir -//#define GPAC_LOG_FILE "/data/osmo/gpac_logs.txt" -#define GPAC_LOG_FILE m_log_filename -//#define GPAC_FONT_DIR "/system/fonts/" -#define GPAC_FONT_DIR m_font_dir - -#define DEBUG_MODE 1 -//#define DEBUG_FILE "/data/osmo/osmo_debug.txt" -#define DEBUG_FILE m_debug_filename - -// keyboard code -#define ANDROID_KEYCODE int -#define ANDROID_KEYCODE_0 7 -#define ANDROID_KEYCODE_1 8 -#define ANDROID_KEYCODE_2 9 -#define ANDROID_KEYCODE_3 10 -#define ANDROID_KEYCODE_4 11 -#define ANDROID_KEYCODE_5 12 -#define ANDROID_KEYCODE_6 13 -#define ANDROID_KEYCODE_7 14 -#define ANDROID_KEYCODE_8 15 -#define ANDROID_KEYCODE_9 16 -#define ANDROID_KEYCODE_A 29 -#define ANDROID_KEYCODE_B 30 -#define ANDROID_KEYCODE_C 31 -#define ANDROID_KEYCODE_D 32 -#define ANDROID_KEYCODE_E 33 -#define ANDROID_KEYCODE_F 34 -#define ANDROID_KEYCODE_G 35 -#define ANDROID_KEYCODE_H 36 -#define ANDROID_KEYCODE_I 37 -#define ANDROID_KEYCODE_J 38 -#define ANDROID_KEYCODE_K 39 -#define ANDROID_KEYCODE_L 40 -#define ANDROID_KEYCODE_M 41 -#define ANDROID_KEYCODE_N 42 -#define ANDROID_KEYCODE_O 43 -#define ANDROID_KEYCODE_P 44 -#define ANDROID_KEYCODE_Q 45 -#define ANDROID_KEYCODE_R 46 -#define ANDROID_KEYCODE_S 47 -#define ANDROID_KEYCODE_T 48 -#define ANDROID_KEYCODE_U 49 -#define ANDROID_KEYCODE_V 50 -#define ANDROID_KEYCODE_W 51 -#define ANDROID_KEYCODE_X 52 -#define ANDROID_KEYCODE_Y 53 -#define ANDROID_KEYCODE_Z 54 -#define ANDROID_KEYCODE_ALT_LEFT 57 -#define ANDROID_KEYCODE_ALT_RIGHT 58 -#define ANDROID_KEYCODE_AT 77 -#define ANDROID_KEYCODE_BACK 4 -#define ANDROID_KEYCODE_BACKSLASH 73 -#define ANDROID_KEYCODE_CALL 5 -#define ANDROID_KEYCODE_CAMERA 27 -#define ANDROID_KEYCODE_CLEAR 28 -#define ANDROID_KEYCODE_COMMA 55 -#define ANDROID_KEYCODE_DEL 67 -#define ANDROID_KEYCODE_DPAD_CENTER 23 -#define ANDROID_KEYCODE_DPAD_DOWN 20 -#define ANDROID_KEYCODE_DPAD_LEFT 21 -#define ANDROID_KEYCODE_DPAD_RIGHT 22 -#define ANDROID_KEYCODE_DPAD_UP 19 -#define ANDROID_KEYCODE_ENDCALL 6 -#define ANDROID_KEYCODE_ENTER 66 -#define ANDROID_KEYCODE_ENVELOPE 65 -#define ANDROID_KEYCODE_EQUALS 70 -#define ANDROID_KEYCODE_EXPLORER 64 -#define ANDROID_KEYCODE_FOCUS 80 -#define ANDROID_KEYCODE_GRAVE 68 -#define ANDROID_KEYCODE_HEADSETHOOK 79 -#define ANDROID_KEYCODE_HOME 3 -#define ANDROID_KEYCODE_LEFT_BRACKET 71 -#define ANDROID_KEYCODE_MEDIA_FAST_FORWARD 90 -#define ANDROID_KEYCODE_MEDIA_NEXT 87 -#define ANDROID_KEYCODE_MEDIA_PLAY_PAUSE 85 -#define ANDROID_KEYCODE_MEDIA_PREVIOUS 88 -#define ANDROID_KEYCODE_MEDIA_REWIND 89 -#define ANDROID_KEYCODE_MEDIA_STOP 86 -#define ANDROID_KEYCODE_MENU 82 -#define ANDROID_KEYCODE_MINUS 69 -#define ANDROID_KEYCODE_MUTE 91 -#define ANDROID_KEYCODE_NUM 78 -#define ANDROID_KEYCODE_PLUS 81 -#define ANDROID_KEYCODE_POWER 26 -#define ANDROID_KEYCODE_RIGHT_BRACKET 72 -#define ANDROID_KEYCODE_SEARCH 84 -#define ANDROID_KEYCODE_SEMICOLON 74 -#define ANDROID_KEYCODE_SHIFT_LEFT 59 -#define ANDROID_KEYCODE_SHIFT_RIGHT 60 -#define ANDROID_KEYCODE_SLASH 76 -#define ANDROID_KEYCODE_SOFT_LEFT 1 -#define ANDROID_KEYCODE_SOFT_RIGHT 2 -#define ANDROID_KEYCODE_SPACE 62 -#define ANDROID_KEYCODE_STAR 17 -#define ANDROID_KEYCODE_SYM 63 -#define ANDROID_KEYCODE_TAB 61 - -#define ANDROID_KEYCODE_UNKWON -1 - -#include - -typedef struct _JavaEnvTh { - JNIEnv * env; - u32 javaThreadId; - jobject cbk_obj; - jmethodID cbk_displayMessage; - jmethodID cbk_onProgress; - jmethodID cbk_showKeyboard; - jmethodID cbk_setCaption; - jmethodID cbk_onLog; -} JavaEnvTh; - - -//--------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------- -class CNativeWrapper{ - - private: - void* m_window; - void* m_session; - - GF_User *GetUser() { return &m_user; } - GF_Terminal *m_term; - - /* - * Callback management - */ - JavaEnvTh mainJavaEnv; - - GF_Mutex *m_mx; - GF_User m_user; - GF_SystemRTInfo m_rti; - - int do_log; - private: - char m_cfg_dir[GF_MAX_PATH]; - char m_modules_dir[GF_MAX_PATH]; - char m_cache_dir[GF_MAX_PATH]; - char m_font_dir[GF_MAX_PATH]; - void setJavaEnv(JavaEnvTh * envToSet, JNIEnv *env, jobject callback); - private: - void SetupLogs(); - void Shutdown(); - void DisplayRTI(); - protected: - JavaEnvTh * getEnv(); - - public: - CNativeWrapper(); - ~CNativeWrapper(); - int init(JNIEnv * env, void * bitmap, jobject * callback, int width, int height, const char * cfg_dir, const char * modules_dir, const char * cache_dir, const char * font_dir, const char * urlToLoad); - - int connect(const char *url); - void disconnect(); - void step(void * env, void * bitmap); - void resize(int w, int h); - void setAudioEnvironment(JavaVM* javaVM); - - void onMouseDown(float x, float y); - void onMouseUp(float x, float y); - void onMouseMove(float x, float y); - void onKeyPress(int keycode, int rawkeycode, int up, int flag, int unicode); - void translate_key(ANDROID_KEYCODE keycode, GF_EventKey *evt); - void setGpacPreference( const char * category, const char * name, const char * value); - public: - int MessageBox(const char* msg, const char* title, GF_Err status); - int Quit(int code); - GF_Config *create_default_config(char *file_path, char *file_name); - - static void on_gpac_log(void *cbk, u32 ll, u32 lm, const char *fmt, va_list list); - static Bool GPAC_EventProc(void *cbk, GF_Event *evt); - void progress_cbk(const char *title, u64 done, u64 total); - static void Osmo4_progress_cbk(const void *usr, const char *title, u64 done, u64 total); - - private: -#ifdef DEBUG_MODE - FILE *debug_f; -#endif - void debug_log(const char* msg); - -}; - +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) ENST 2009- + * Authors: Jean Le Feuvre + * All rights reserved + * + * Created by NGO Van Luyen, Ivica ARSOV / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010 + * + * This file is part of GPAC / Wrapper + * + * 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 + +#include +#include +#include +#include + +//#define MAX_PATH 255 + +#define KErrGeneral 1 +//#define GPAC_CFG_DIR "/data/osmo/" +#define GPAC_CFG_DIR m_cfg_dir +//#define GPAC_MODULES_DIR "/data/osmo/modules/" +#define GPAC_MODULES_DIR m_modules_dir +//#define GPAC_MODULES_PATH "/data/osmo/modules/" +#define GPAC_MODULES_PATH m_modules_dir +//#define GPAC_CACHE_DIR "/data/osmo/cache/" +#define GPAC_CACHE_DIR m_cache_dir +//#define GPAC_LOG_FILE "/data/osmo/gpac_logs.txt" +#define GPAC_LOG_FILE m_log_filename +//#define GPAC_FONT_DIR "/system/fonts/" +#define GPAC_FONT_DIR m_font_dir + +#define DEBUG_MODE 1 +//#define DEBUG_FILE "/data/osmo/osmo_debug.txt" +#define DEBUG_FILE m_debug_filename + +// keyboard code +#define ANDROID_KEYCODE int +#define ANDROID_KEYCODE_0 7 +#define ANDROID_KEYCODE_1 8 +#define ANDROID_KEYCODE_2 9 +#define ANDROID_KEYCODE_3 10 +#define ANDROID_KEYCODE_4 11 +#define ANDROID_KEYCODE_5 12 +#define ANDROID_KEYCODE_6 13 +#define ANDROID_KEYCODE_7 14 +#define ANDROID_KEYCODE_8 15 +#define ANDROID_KEYCODE_9 16 +#define ANDROID_KEYCODE_A 29 +#define ANDROID_KEYCODE_B 30 +#define ANDROID_KEYCODE_C 31 +#define ANDROID_KEYCODE_D 32 +#define ANDROID_KEYCODE_E 33 +#define ANDROID_KEYCODE_F 34 +#define ANDROID_KEYCODE_G 35 +#define ANDROID_KEYCODE_H 36 +#define ANDROID_KEYCODE_I 37 +#define ANDROID_KEYCODE_J 38 +#define ANDROID_KEYCODE_K 39 +#define ANDROID_KEYCODE_L 40 +#define ANDROID_KEYCODE_M 41 +#define ANDROID_KEYCODE_N 42 +#define ANDROID_KEYCODE_O 43 +#define ANDROID_KEYCODE_P 44 +#define ANDROID_KEYCODE_Q 45 +#define ANDROID_KEYCODE_R 46 +#define ANDROID_KEYCODE_S 47 +#define ANDROID_KEYCODE_T 48 +#define ANDROID_KEYCODE_U 49 +#define ANDROID_KEYCODE_V 50 +#define ANDROID_KEYCODE_W 51 +#define ANDROID_KEYCODE_X 52 +#define ANDROID_KEYCODE_Y 53 +#define ANDROID_KEYCODE_Z 54 +#define ANDROID_KEYCODE_ALT_LEFT 57 +#define ANDROID_KEYCODE_ALT_RIGHT 58 +#define ANDROID_KEYCODE_AT 77 +#define ANDROID_KEYCODE_BACK 4 +#define ANDROID_KEYCODE_BACKSLASH 73 +#define ANDROID_KEYCODE_CALL 5 +#define ANDROID_KEYCODE_CAMERA 27 +#define ANDROID_KEYCODE_CLEAR 28 +#define ANDROID_KEYCODE_COMMA 55 +#define ANDROID_KEYCODE_DEL 67 +#define ANDROID_KEYCODE_DPAD_CENTER 23 +#define ANDROID_KEYCODE_DPAD_DOWN 20 +#define ANDROID_KEYCODE_DPAD_LEFT 21 +#define ANDROID_KEYCODE_DPAD_RIGHT 22 +#define ANDROID_KEYCODE_DPAD_UP 19 +#define ANDROID_KEYCODE_ENDCALL 6 +#define ANDROID_KEYCODE_ENTER 66 +#define ANDROID_KEYCODE_ENVELOPE 65 +#define ANDROID_KEYCODE_EQUALS 70 +#define ANDROID_KEYCODE_EXPLORER 64 +#define ANDROID_KEYCODE_FOCUS 80 +#define ANDROID_KEYCODE_GRAVE 68 +#define ANDROID_KEYCODE_HEADSETHOOK 79 +#define ANDROID_KEYCODE_HOME 3 +#define ANDROID_KEYCODE_LEFT_BRACKET 71 +#define ANDROID_KEYCODE_MEDIA_FAST_FORWARD 90 +#define ANDROID_KEYCODE_MEDIA_NEXT 87 +#define ANDROID_KEYCODE_MEDIA_PLAY_PAUSE 85 +#define ANDROID_KEYCODE_MEDIA_PREVIOUS 88 +#define ANDROID_KEYCODE_MEDIA_REWIND 89 +#define ANDROID_KEYCODE_MEDIA_STOP 86 +#define ANDROID_KEYCODE_MENU 82 +#define ANDROID_KEYCODE_MINUS 69 +#define ANDROID_KEYCODE_MUTE 91 +#define ANDROID_KEYCODE_NUM 78 +#define ANDROID_KEYCODE_PLUS 81 +#define ANDROID_KEYCODE_POWER 26 +#define ANDROID_KEYCODE_RIGHT_BRACKET 72 +#define ANDROID_KEYCODE_SEARCH 84 +#define ANDROID_KEYCODE_SEMICOLON 74 +#define ANDROID_KEYCODE_SHIFT_LEFT 59 +#define ANDROID_KEYCODE_SHIFT_RIGHT 60 +#define ANDROID_KEYCODE_SLASH 76 +#define ANDROID_KEYCODE_SOFT_LEFT 1 +#define ANDROID_KEYCODE_SOFT_RIGHT 2 +#define ANDROID_KEYCODE_SPACE 62 +#define ANDROID_KEYCODE_STAR 17 +#define ANDROID_KEYCODE_SYM 63 +#define ANDROID_KEYCODE_TAB 61 + +#define ANDROID_KEYCODE_UNKWON -1 + +#include + +typedef struct _JavaEnvTh { + JNIEnv * env; + u32 javaThreadId; + jobject cbk_obj; + jmethodID cbk_displayMessage; + jmethodID cbk_onProgress; + jmethodID cbk_showKeyboard; + jmethodID cbk_setCaption; + jmethodID cbk_onLog; +} JavaEnvTh; + + +//--------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------- +class CNativeWrapper{ + + private: + void* m_window; + void* m_session; + + GF_User *GetUser() { return &m_user; } + GF_Terminal *m_term; + + /* + * Callback management + */ + JavaEnvTh mainJavaEnv; + + GF_Mutex *m_mx; + GF_User m_user; + GF_SystemRTInfo m_rti; + + int do_log; + private: + char m_cfg_dir[GF_MAX_PATH]; + char m_modules_dir[GF_MAX_PATH]; + char m_cache_dir[GF_MAX_PATH]; + char m_font_dir[GF_MAX_PATH]; + void setJavaEnv(JavaEnvTh * envToSet, JNIEnv *env, jobject callback); + private: + void SetupLogs(); + void Shutdown(); + void DisplayRTI(); + protected: + JavaEnvTh * getEnv(); + + public: + CNativeWrapper(); + ~CNativeWrapper(); + int init(JNIEnv * env, void * bitmap, jobject * callback, int width, int height, const char * cfg_dir, const char * modules_dir, const char * cache_dir, const char * font_dir, const char * urlToLoad); + + int connect(const char *url); + void disconnect(); + void step(void * env, void * bitmap); + void resize(int w, int h); + void setAudioEnvironment(JavaVM* javaVM); + + void onMouseDown(float x, float y); + void onMouseUp(float x, float y); + void onMouseMove(float x, float y); + void onKeyPress(int keycode, int rawkeycode, int up, int flag, int unicode); + void translate_key(ANDROID_KEYCODE keycode, GF_EventKey *evt); + void navigate( GF_Event* evt); + void setGpacPreference( const char * category, const char * name, const char * value); + public: + int MessageBox(const char* msg, const char* title, GF_Err status); + int Quit(int code); + GF_Config *create_default_config(char *file_path, char *file_name); + + static void on_gpac_log(void *cbk, u32 ll, u32 lm, const char *fmt, va_list list); + static Bool GPAC_EventProc(void *cbk, GF_Event *evt); + void progress_cbk(const char *title, u64 done, u64 total); + static void Osmo4_progress_cbk(const void *usr, const char *title, u64 done, u64 total); + + private: +#ifdef DEBUG_MODE + FILE *debug_f; +#endif + void debug_log(const char* msg); + +}; + diff --git a/applications/osmo4_android/jni/wrapper_jni.c b/applications/osmo4_android/jni/wrapper_jni.c index 48d9c27..e9bcd0b 100644 --- a/applications/osmo4_android/jni/wrapper_jni.c +++ b/applications/osmo4_android/jni/wrapper_jni.c @@ -24,11 +24,11 @@ extern "C" { // __android_log_print(ANDROID_LOG_VERBOSE, jniTAG, "Handle = %p", wr); /* - * Class: com_artemis_Osmo4_GPACInstance + * Class: com_gpac_Osmo4_GPACInstance * Method: createInstance - * Signature: (Lcom/artemis/Osmo4/GpacCallback;IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I + * Signature: (Lcom/gpac/Osmo4/GpacCallback;IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I */ -JNIEXPORT jlong JNICALL Java_com_artemis_Osmo4_GPACInstance_createInstance(JNIEnv * env, jclass obj, jobject callback, jint width, jint height, jstring cfg_dir, jstring modules_dir, jstring cache_dir, jstring font_dir, jstring url_to_open) +JNIEXPORT jlong JNICALL Java_com_gpac_Osmo4_GPACInstance_createInstance(JNIEnv * env, jclass obj, jobject callback, jint width, jint height, jstring cfg_dir, jstring modules_dir, jstring cache_dir, jstring font_dir, jstring url_to_open) { jboolean isCopy; const char * s1 = env->GetStringUTFChars(cfg_dir, &isCopy); @@ -66,7 +66,7 @@ JNIEXPORT jlong JNICALL Java_com_artemis_Osmo4_GPACInstance_createInstance(JNIEn return (jlong) gpac_obj; } //----------------------------------- -JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GPACInstance_gpacconnect(JNIEnv * env, jobject obj, jstring fileName) +JNIEXPORT void JNICALL Java_com_gpac_Osmo4_GPACInstance_gpacconnect(JNIEnv * env, jobject obj, jstring fileName) { CAST_HANDLE(wr); jniLOGV("connect::start"); @@ -83,7 +83,7 @@ JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GPACInstance_gpacconnect(JNIEnv * jniLOGV("connect::end"); } //----------------------------------- -JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GPACInstance_gpacdisconnect(JNIEnv * env, jobject obj){ +JNIEXPORT void JNICALL Java_com_gpac_Osmo4_GPACInstance_gpacdisconnect(JNIEnv * env, jobject obj){ CAST_HANDLE(wr); jniLOGV("disconnect::start"); if (wr) @@ -91,7 +91,7 @@ JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GPACInstance_gpacdisconnect(JNIEnv jniLOGV("disconnect::end"); } //----------------------------------- -JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GPACInstance_gpacfree(JNIEnv * env, jobject obj) +JNIEXPORT void JNICALL Java_com_gpac_Osmo4_GPACInstance_gpacfree(JNIEnv * env, jobject obj) { CAST_HANDLE(wr); jniLOGV("free::start"); @@ -100,7 +100,7 @@ JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GPACInstance_gpacfree(JNIEnv * env jniLOGV("free::end"); } //----------------------------------- -JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GPACInstance_gpacrender (JNIEnv * env, jobject obj) +JNIEXPORT void JNICALL Java_com_gpac_Osmo4_GPACInstance_gpacrender (JNIEnv * env, jobject obj) { CAST_HANDLE(wr); //jniLOGV("render::start"); @@ -109,7 +109,7 @@ JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GPACInstance_gpacrender (JNIEnv * //jniLOGV("render::end"); } //----------------------------------- -JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GPACInstance_gpacresize (JNIEnv * env, jobject obj, jint width, jint height) +JNIEXPORT void JNICALL Java_com_gpac_Osmo4_GPACInstance_gpacresize (JNIEnv * env, jobject obj, jint width, jint height) { CAST_HANDLE(wr); jniLOGV("resize::start"); @@ -118,7 +118,7 @@ JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GPACInstance_gpacresize (JNIEnv * jniLOGV("resize::end"); } //----------------------------------- -JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GPACInstance_gpaceventmousedown(JNIEnv * env, jobject obj, jfloat x, jfloat y){ +JNIEXPORT void JNICALL Java_com_gpac_Osmo4_GPACInstance_gpaceventmousedown(JNIEnv * env, jobject obj, jfloat x, jfloat y){ CAST_HANDLE(wr); jniLOGV("mouseDown::start"); if (wr) @@ -126,7 +126,7 @@ JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GPACInstance_gpaceventmousedown(JN jniLOGV("mouseDown::end"); } //----------------------------------- -JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GPACInstance_gpaceventmouseup(JNIEnv * env, jobject obj, jfloat x, jfloat y){ +JNIEXPORT void JNICALL Java_com_gpac_Osmo4_GPACInstance_gpaceventmouseup(JNIEnv * env, jobject obj, jfloat x, jfloat y){ CAST_HANDLE(wr); jniLOGV("mouseUp::start"); if (wr) @@ -134,7 +134,7 @@ JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GPACInstance_gpaceventmouseup(JNIE jniLOGV("mouseUp::end"); } //----------------------------------- -JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GPACInstance_gpaceventmousemove(JNIEnv * env, jobject obj, jfloat x, jfloat y){ +JNIEXPORT void JNICALL Java_com_gpac_Osmo4_GPACInstance_gpaceventmousemove(JNIEnv * env, jobject obj, jfloat x, jfloat y){ CAST_HANDLE(wr); jniLOGV("mouseMouv::start"); if (wr) @@ -142,21 +142,32 @@ JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GPACInstance_gpaceventmousemove(JN jniLOGV("mouseMouv::end"); } //----------------------------------- -JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GPACInstance_gpaceventkeypress(JNIEnv * env, jobject obj, jint keycode, jint rawkeycode, jint up, jint flag, jint unicode){ +JNIEXPORT void JNICALL Java_com_gpac_Osmo4_GPACInstance_gpaceventkeypress(JNIEnv * env, jobject obj, jint keycode, jint rawkeycode, jint up, jint flag, jint unicode){ CAST_HANDLE(wr); jniLOGV("keypress::start"); if (wr) wr->onKeyPress(keycode, rawkeycode, up, flag, unicode); jniLOGV("keypress::end"); } - +/* +JNIEXPORT void JNICALL Java_com_gpac_Osmo4_GPACInstance_getdpi(JNIEnv * env, jobject obj, jint keycode,jfloat x, jfloat y){ + CAST_HANDLE(wr); + jniLOGV("get DPI::start"); + jclass cls = (*env)->GetObjectClass(env, obj); + jmethodID mid = (*env)->GetStaticMethodID(env, cls, "getdpi", "(FF)V"); + if (mid == 0) + return; + (*env)->CallStaticIntMethod(env, cls, mid, x,y); + jniLOGV("get DPI::end"); +} +*/ /* - * Class: com_artemis_Osmo4_GPACInstance + * Class: com_gpac_Osmo4_GPACInstance * Method: setGpacPreference * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V */ -JNIEXPORT void JNICALL Java_com_artemis_Osmo4_GPACInstance_setGpacPreference +JNIEXPORT void JNICALL Java_com_gpac_Osmo4_GPACInstance_setGpacPreference (JNIEnv * env, jobject obj, jstring category, jstring name, jstring value){ CAST_HANDLE(wr); jboolean isCopy; diff --git a/applications/osmo4_android/local.properties b/applications/osmo4_android/local.properties deleted file mode 100644 index 3ec4ddb..0000000 --- a/applications/osmo4_android/local.properties +++ /dev/null @@ -1,10 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must *NOT* be checked in Version Control Systems, -# as it contains information specific to your local configuration. - -# location of the SDK. This is only used by Ant -# For customization when using a Version Control System, please read the -# header note. -sdk.dir=/opt/android-sdk diff --git a/applications/osmo4_android/proguard.cfg b/applications/osmo4_android/proguard.cfg deleted file mode 100644 index 8ad7d33..0000000 --- a/applications/osmo4_android/proguard.cfg +++ /dev/null @@ -1,34 +0,0 @@ --optimizationpasses 5 --dontusemixedcaseclassnames --dontskipnonpubliclibraryclasses --dontpreverify --verbose --optimizations !code/simplification/arithmetic,!field/*,!class/merging/* - --keep public class * extends android.app.Activity --keep public class * extends android.app.Application --keep public class * extends android.app.Service --keep public class * extends android.content.BroadcastReceiver --keep public class * extends android.content.ContentProvider --keep public class com.android.vending.licensing.ILicensingService - --keepclasseswithmembernames class * { - native ; -} - --keepclasseswithmembernames class * { - public (android.content.Context, android.util.AttributeSet); -} - --keepclasseswithmembernames class * { - public (android.content.Context, android.util.AttributeSet, int); -} - --keepclassmembers enum * { - public static **[] values(); - public static ** valueOf(java.lang.String); -} - --keep class * implements android.os.Parcelable { - public static final android.os.Parcelable$Creator *; -} diff --git a/applications/osmo4_android/src/com/artemis/Osmo4/BitmapView.java b/applications/osmo4_android/src/com/artemis/Osmo4/BitmapView.java deleted file mode 100644 index 08b6211..0000000 --- a/applications/osmo4_android/src/com/artemis/Osmo4/BitmapView.java +++ /dev/null @@ -1,93 +0,0 @@ -///** -// * Osmo on Android -// * Aug/2010 -// * NGO Van Luyen -// * -// * -// */ -//package com.artemis.Osmo4; -// -//import android.content.Context; -//import android.graphics.Bitmap; -//import android.graphics.Canvas; -//import android.util.Log; -//import android.view.View; -// -///** -// * -// * @version $Revision: 2822 $ -// * -// */ -//@Deprecated -//public class BitmapView extends View { -// -// private Bitmap m_Bitmap = null; -// -// private int m_width = 100, m_height = 100; -// -// private final static String LOG_BITMAP = BitmapView.class.getSimpleName(); -// -// /** -// * Constructor -// * -// * @param context The current view's context -// */ -// public BitmapView(Context context) { -// super(context); -// } -// -// @Override -// protected void onDraw(Canvas canvas) { -// // canvas.drawColor(0xFFCCCCCC); -// m_width = canvas.getWidth(); -// m_height = canvas.getHeight(); -// if (m_Bitmap == null) { -// if (m_width < 1) -// m_width = 100; -// if (m_height < 1) -// m_height = 100; -// m_Bitmap = Bitmap.createBitmap(m_width, m_height, Bitmap.Config.ARGB_8888); -// gpacinit(); -// } -// -// GpacObject.gpacrender(m_Bitmap); -// canvas.drawBitmap(m_Bitmap, 0, 0, null); -// // force a redraw, with a different time-based pattern. -// invalidate(); -// -// } -// -// /** -// * Called to init all GPAC resources -// */ -// private void gpacinit() { -// Log.i(LOG_BITMAP, "Going to gpacinit"); //$NON-NLS-1$ -// if (m_Bitmap != null) { -// Log.e(LOG_BITMAP, "m_Bitmap != null"); //$NON-NLS-1$ -// if (m_width < 1) -// m_width = 100; -// if (m_height < 1) -// m_height = 100; -// GpacObject.gpacinit(m_Bitmap, -// null, -// m_width, -// m_height, -// Osmo4Renderer.GPAC_CFG_DIR, -// Osmo4Renderer.GPAC_MODULES_DIR, -// Osmo4Renderer.GPAC_CACHE_DIR, -// Osmo4Renderer.GPAC_FONT_DIR, -// null); -// // GpacObject.gpacconnect("/data/osmo/bifs-2D-interactivity-stringsensor.mp4"); -// GpacObject.gpacresize(m_width, m_height); -// } -// } -// -// /** -// * Called to free all GPAC resources -// */ -// public void gpacfree() { -// Log.e(LOG_BITMAP, "gpacfree()"); //$NON-NLS-1$ -// GpacObject.gpacdisconnect(); -// GpacObject.gpacfree(); -// } -// } diff --git a/applications/osmo4_android/src/com/artemis/Osmo4/GPACInstance.java b/applications/osmo4_android/src/com/artemis/Osmo4/GPACInstance.java deleted file mode 100644 index 2f731a5..0000000 --- a/applications/osmo4_android/src/com/artemis/Osmo4/GPACInstance.java +++ /dev/null @@ -1,368 +0,0 @@ -/** - * $URL: http://gpac.svn.sourceforge.net/svnroot/gpac/trunk/gpac/applications/osmo4_android/src/com/artemis/Osmo4/GPACInstance.java $ - * - * $LastChangedBy: bad_sheep $ - $LastChangedDate: 2011-04-20 12:31:24 -0400 (Wed, 20 Apr 2011) $ - */ -package com.artemis.Osmo4; - -import java.io.File; -import java.io.PrintStream; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import android.util.Log; -import android.view.KeyEvent; -import android.view.MotionEvent; - -/** - * @version $Revision: 2972 $ - * - */ -public class GPACInstance implements GPACInstanceInterface { - - private final static String LOG_LIB = "LibrariesLoader"; //$NON-NLS-1$ - - private final Thread uniqueThread; - - private static void listing(StringBuilder sb, File root, int inc) { - StringBuilder increment = new StringBuilder(); - for (int i = 0; i < inc; i++) - increment.append(' '); - String incr = increment.toString(); - for (File f : root.listFiles()) { - sb.append(incr).append(f.getName()); - if (f.isDirectory()) { - sb.append(" [Directory]\n"); //$NON-NLS-1$ - listing(sb, f, inc + 2); - } else { - sb.append(" [").append(f.length() + " bytes]\n"); //$NON-NLS-1$//$NON-NLS-2$ - } - } - } - - /** - * Loads all libraries - * - * @param config - * - * @return a map of exceptions containing the library as key and the exception as value. If map is empty, no error - * - */ - synchronized static Map loadAllLibraries(GpacConfig config) { - if (errors != null) - return errors; - StringBuilder sb = new StringBuilder(); - final String[] toLoad = { "GLESv1_CM", "dl", "log",//$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ - "jpeg", "javaenv", //$NON-NLS-1$ //$NON-NLS-2$ - "mad", "editline", "ft2", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - "js_osmo", "openjpeg", "png", "z", //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$ - "ffmpeg", "faad", "gpac", //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ - "stdc++", "gpacWrapper" }; // //$NON-NLS-1$ //$NON-NLS-2$ - HashMap exceptions = new HashMap(); - for (String s : toLoad) { - try { - String msg = "Loading library " + s + "...";//$NON-NLS-1$//$NON-NLS-2$ - sb.append(msg); - Log.i(LOG_LIB, msg); - System.loadLibrary(s); - } catch (UnsatisfiedLinkError e) { - sb.append("Failed to load " + s + ", error=" + e.getLocalizedMessage() + " :: " //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ - + e.getClass().getSimpleName() + "\n"); //$NON-NLS-1$ - exceptions.put(s, e); - Log.e(LOG_LIB, "Failed to load library : " + s + " due to link error " + e.getLocalizedMessage(), e); //$NON-NLS-1$ //$NON-NLS-2$ - } catch (SecurityException e) { - exceptions.put(s, e); - Log.e(LOG_LIB, "Failed to load library : " + s + " due to security error " + e.getLocalizedMessage(), e); //$NON-NLS-1$ //$NON-NLS-2$ - } catch (Throwable e) { - exceptions.put(s, e); - Log.e(LOG_LIB, "Failed to load library : " + s + " due to Runtime error " + e.getLocalizedMessage(), e); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - if (!exceptions.isEmpty()) { - try { - PrintStream out = new PrintStream(config.getGpacConfigDirectory() + "debug_libs.txt", "UTF-8"); //$NON-NLS-1$//$NON-NLS-2$ - out.println("$Revision: 2972 $"); //$NON-NLS-1$ - out.println(new Date()); - out.println("\n*** Configuration\n"); //$NON-NLS-1$ - out.println(config.getConfigAsText()); - sb.append("*** Libs listing: "); //$NON-NLS-1$ - sb.append(config.getGpacLibsDirectory()); - sb.append('\n'); - listing(sb, new File(config.getGpacLibsDirectory()), 2); - sb.append("*** Modules listing: "); //$NON-NLS-1$ - sb.append(config.getGpacModulesDirectory()); - sb.append('\n'); - listing(sb, new File(config.getGpacModulesDirectory()), 2); - sb.append("*** Fonts listing: \n"); //$NON-NLS-1$ - sb.append(config.getGpacFontDirectory()); - sb.append('\n'); - listing(sb, new File(config.getGpacFontDirectory()), 2); - sb.append("*** Exceptions:\n"); //$NON-NLS-1$ - for (Map.Entry ex : exceptions.entrySet()) { - sb.append(ex.getKey()).append(": ") //$NON-NLS-1$ - .append(ex.getValue().getLocalizedMessage()) - .append('(') - .append(ex.getValue().getClass()) - .append(")\n"); //$NON-NLS-1$ - } - out.println(sb.toString()); - out.flush(); - out.close(); - } catch (Exception e) { - Log.e(LOG_LIB, "Failed to output debug info to debug file", e); //$NON-NLS-1$ - } - } - errors = Collections.unmodifiableMap(exceptions); - return errors; - } - - private static Map errors = null; - - private boolean hasToBeFreed = true; - - /** - * Constructor - * - * @param callback - * @param width - * @param height - * @param config The configuration to use for GPAC - * @param urlToOpen - * @throws GpacInstanceException - */ - public GPACInstance(GpacCallback callback, int width, int height, GpacConfig config, String urlToOpen) - throws GpacInstanceException { - StringBuilder sb = new StringBuilder(); - Map errors = loadAllLibraries(config); - if (!errors.isEmpty()) { - sb.append("Exceptions while loading libraries:"); //$NON-NLS-1$ - for (Map.Entry x : errors.entrySet()) { - sb.append('\n') - .append(x.getKey()) - .append('[') - .append(x.getValue().getClass().getSimpleName()) - .append("]: ") //$NON-NLS-1$ - .append(x.getValue().getLocalizedMessage()); - } - Log.e(LOG_LIB, sb.toString()); - } - try { - handle = createInstance(callback, - width, - height, - config.getGpacConfigDirectory(), - config.getGpacModulesDirectory(), - config.getGpacCacheDirectory(), - config.getGpacFontDirectory(), - urlToOpen); - } catch (Throwable e) { - throw new GpacInstanceException("Error while creating instance\n" + sb.toString()); //$NON-NLS-1$ - } - if (handle == 0) { - throw new GpacInstanceException("Error while creating instance, no handle created!\n" + sb.toString()); //$NON-NLS-1$ - } - synchronized (this) { - hasToBeFreed = true; - } - uniqueThread = Thread.currentThread(); - } - - /** - * This one handles the pointer to the real C object - */ - private final long handle; - - /** - * @return the handle - */ - public synchronized long getHandle() { - return handle; - } - - private void checkCurrentThread() throws RuntimeException { - if (Thread.currentThread() != uniqueThread) - throw new RuntimeException("Method called outside allowed Thread scope !"); //$NON-NLS-1$ - } - - @Override - public void disconnect() { - checkCurrentThread(); - gpacdisconnect(); - } - - @Override - public void connect(String url) { - Log.i(LOG_LIB, "connect(" + url + ")"); //$NON-NLS-1$ //$NON-NLS-2$ - checkCurrentThread(); - gpacconnect(url); - } - - /** - * Call this method when a key has been pressed - * - * @param keyCode - * @param event - * @param pressed true if key is pressed, false if key is released - * @param unicode - */ - public void eventKey(int keyCode, KeyEvent event, boolean pressed, int unicode) { - checkCurrentThread(); - gpaceventkeypress(keyCode, event.getScanCode(), pressed ? 1 : 0, event.getFlags(), unicode); - } - - /** - * Renders the current frame - */ - public void render() { - checkCurrentThread(); - gpacrender(); - } - - /** - * Resizes the object to new dimensions - * - * @param width - * @param height - */ - public void resize(int width, int height) { - Log.i(LOG_LIB, "Resizing to " + width + "x" + height); //$NON-NLS-1$ //$NON-NLS-2$ - gpacresize(width, height); - } - - /** - * Call this when a motion event occurs - * - * @param event - */ - public void motionEvent(MotionEvent event) { - checkCurrentThread(); - final float x = event.getX(); - final float y = event.getY(); - switch (event.getAction()) { - // not in 1.6 case MotionEvent.ACTION_POINTER_1_DOWN: - case MotionEvent.ACTION_DOWN: - gpaceventmousemove(x, y); - gpaceventmousedown(x, y); - break; - // not in 1.6 case MotionEvent.ACTION_POINTER_1_UP: - case MotionEvent.ACTION_UP: - gpaceventmouseup(x, y); - break; - case MotionEvent.ACTION_MOVE: - gpaceventmousemove(x, y); - } - } - - @Override - public void finalize() throws Throwable { - // Not sure how to do this..., destroy is supposed to be called already - // destroy(); - super.finalize(); - } - - /** - * All Native functions, those functions are binded using the handle - */ - - /** - * Opens an URL - * - * @param url The URL to open - */ - private native void gpacconnect(String url); - - /** - * Used to create the GPAC instance - * - * @param callback - * @param width - * @param height - * @param cfg_dir - * @param modules_dir - * @param cache_dir - * @param font_dir - * @return - */ - private native long createInstance(GpacCallback callback, int width, int height, String cfg_dir, - String modules_dir, String cache_dir, String font_dir, String url_to_open); - - /** - * Disconnects the currently loaded URL - */ - private native void gpacdisconnect(); - - /** - * Renders - * - * @param handle - */ - private native void gpacrender(); - - /** - * Resizes the current view - * - * @param width The new width to set - * @param height The new height to set - */ - private native void gpacresize(int width, int height); - - /** - * Free all GPAC resources - */ - private native void gpacfree(); - - /** - * To call when a key has been pressed - * - * @param keycode - * @param rawkeycode - * @param up - * @param flag - */ - private native void gpaceventkeypress(int keycode, int rawkeycode, int up, int flag, int unicode); - - /** - * To call when a mouse is down - * - * @param x Position in pixels - * @param y Position in pixels - */ - private native void gpaceventmousedown(float x, float y); - - /** - * To call when a mouse is up (released) - * - * @param x Position in pixels - * @param y Position in pixels - */ - private native void gpaceventmouseup(float x, float y); - - /** - * To call when a mouse is moving - * - * @param x Position in pixels - * @param y Position in pixels - */ - private native void gpaceventmousemove(float x, float y); - - @Override - public void destroy() { - boolean freeIt; - synchronized (this) { - freeIt = hasToBeFreed; - hasToBeFreed = false; - } - if (freeIt) { - disconnect(); - gpacfree(); - } - } - - /** - * @see com.artemis.Osmo4.GPACInstanceInterface#setGpacPreference(String, String, String) - */ - @Override - public native void setGpacPreference(String category, String name, String value); -} diff --git a/applications/osmo4_android/src/com/artemis/Osmo4/GPACInstanceInterface.java b/applications/osmo4_android/src/com/artemis/Osmo4/GPACInstanceInterface.java deleted file mode 100644 index 6892ab5..0000000 --- a/applications/osmo4_android/src/com/artemis/Osmo4/GPACInstanceInterface.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * $URL: http://gpac.svn.sourceforge.net/svnroot/gpac/trunk/gpac/applications/osmo4_android/src/com/artemis/Osmo4/GPACInstanceInterface.java $ - * - * $LastChangedBy: bad_sheep $ - $LastChangedDate: 2011-04-18 09:33:58 -0400 (Mon, 18 Apr 2011) $ - */ -package com.artemis.Osmo4; - -/** - * @copyright RTL Group 2008 - * @author RTL Group DTIT software development team (last changed by $LastChangedBy: bad_sheep $) - * @version $Revision: 2935 $ - * - */ -public interface GPACInstanceInterface { - - /** - * @version $Revision: 2935 $ - * - */ - public static class GpacInstanceException extends Exception { - - /** - * - */ - private static final long serialVersionUID = 3207851655866335152L; - - /** - * Constructor - * - * @param msg - */ - public GpacInstanceException(String msg) { - super(msg); - } - - }; - - /** - * Call this method to disconnect - */ - public void disconnect(); - - /** - * Call this method to connect to a given URL - * - * @param url The URL to connect to - */ - public void connect(String url); - - /** - * Destroys the current instance, you won't be able to use it anymore... - */ - public void destroy(); - - /** - * Set a GPAC preference to given value - * - * @param category - * @param name The name of preference as defined in GPAC.cfg - * @param value The value to set, if null, value will be deleted - */ - public void setGpacPreference(String category, String name, String value); - -} diff --git a/applications/osmo4_android/src/com/artemis/Osmo4/GpacCallback.java b/applications/osmo4_android/src/com/artemis/Osmo4/GpacCallback.java deleted file mode 100644 index 315c973..0000000 --- a/applications/osmo4_android/src/com/artemis/Osmo4/GpacCallback.java +++ /dev/null @@ -1,286 +0,0 @@ -/** - * $URL: http://gpac.svn.sourceforge.net/svnroot/gpac/trunk/gpac/applications/osmo4_android/src/com/artemis/Osmo4/GpacCallback.java $ - * - * $LastChangedBy: bad_sheep $ - $LastChangedDate: 2011-04-11 02:42:42 -0400 (Mon, 11 Apr 2011) $ - */ -package com.artemis.Osmo4; - -/** - * Interface to implement by Java Objects to listen for callbacks from GPAC native code - * - * @version $Revision: 2888 $ - * - */ -public interface GpacCallback { - - /** - * GPAC Error codes - * - * @version $Revision: 2888 $ - * - */ - public enum GF_Err { - - /** Message from any scripting engine used in the presentation (ECMAScript, MPEG-J, ...) (Info). */ - GF_SCRIPT_INFO(3), - /** - * Indicates an data frame has several AU packed (not MPEG-4 compliant). This is used by decoders to force - * multiple decoding of the same data frame (Info). - */ - GF_PACKED_FRAMES(2), - /** Indicates the end of a stream or of a file (Info). */ - GF_EOS(1), - /* - * ! \n\n - */ - /** Operation success (no error). */ - GF_OK(0), - /** \n */ - /** One of the input parameter is not correct or cannot be used in the current operating mode of the framework. */ - GF_BAD_PARAM(-1), - /** Memory allocation failure. */ - GF_OUT_OF_MEM(-2), - /** Input/Output failure (disk access, system call failures) */ - GF_IO_ERR(-3), - /** The desired feature or operation is not supported by the framework */ - GF_NOT_SUPPORTED(-4), - /** Input data has been corrupted */ - GF_CORRUPTED_DATA(-5), - /** A modification was attempted on a scene node which could not be found */ - GF_SG_UNKNOWN_NODE(-6), - /** The PROTO node interface does not match the nodes using it */ - GF_SG_INVALID_PROTO(-7), - /** An error occured in the scripting engine */ - GF_SCRIPT_ERROR(-8), - /** - * Buffer is too small to contain decoded data. Decoders shall use this error whenever they need to resize their - * output memory buffers - */ - GF_BUFFER_TOO_SMALL(-9), - /** Bitstream is not compliant to the specfication it refers to */ - GF_NON_COMPLIANT_BITSTREAM(-10), - /** No decoders could be found to handle the desired media type */ - GF_CODEC_NOT_FOUND(-11), - /** The URL is not properly formatted or cannot be found */ - GF_URL_ERROR(-12), - /** An service error has occured at the local side */ - GF_SERVICE_ERROR(-13), - /** A service error has occured at the remote (server) side */ - GF_REMOTE_SERVICE_ERROR(-14), - /** The desired stream could not be found in the service */ - GF_STREAM_NOT_FOUND(-15), - /** The IsoMedia file is not a valid one */ - GF_ISOM_INVALID_FILE(-20), - /** The IsoMedia file is not complete. Either the file is being downloaded, or it has been truncated */ - GF_ISOM_INCOMPLETE_FILE(-21), - /** The media in this IsoMedia track is not valid (usually due to a broken stream description) */ - GF_ISOM_INVALID_MEDIA(-22), - /** The requested operation cannot happen in the current opening mode of the IsoMedia file */ - GF_ISOM_INVALID_MODE(-23), - /** This IsoMedia track refers to media outside the file in an unknown way */ - GF_ISOM_UNKNOWN_DATA_REF(-24), - - /** An invalid MPEG-4 Object Descriptor was found */ - GF_ODF_INVALID_DESCRIPTOR(-30), - /** An MPEG-4 Object Descriptor was found or added to a forbidden descriptor */ - GF_ODF_FORBIDDEN_DESCRIPTOR(-31), - /** An invalid MPEG-4 BIFS command was detected */ - GF_ODF_INVALID_COMMAND(-32), - /** The scene has been encoded using an unknown BIFS version */ - GF_BIFS_UNKNOWN_VERSION(-33), - - /** The remote IP address could not be solved */ - GF_IP_ADDRESS_NOT_FOUND(-40), - /** The connection to the remote peer has failed */ - GF_IP_CONNECTION_FAILURE(-41), - /** The network operation has failed */ - GF_IP_NETWORK_FAILURE(-42), - /** The network connection has been closed */ - GF_IP_CONNECTION_CLOSED(-43), - /** The network operation has failed because no data is available */ - GF_IP_NETWORK_EMPTY(-44), - /** The network operation has been discarded because it would be a blocking one */ - GF_IP_SOCK_WOULD_BLOCK(-45), - /** - * UDP connection did not receive any data at all. Signaled by client services to reconfigure network if - * possible - */ - GF_IP_UDP_TIMEOUT(-46), - - /** Authentication with the remote host has failed */ - GF_AUTHENTICATION_FAILURE(-50), - /** Script not ready for playback */ - GF_SCRIPT_NOT_READY(-51), - - /** - * Unknown GPAC Error code - */ - JAVA_UNKNOWN_ERROR(-100); - - int value; - - GF_Err(int x) { - this.value = x; - }; - - /** - * Get a GPAC Error code from its value - * - * @param status The int status corresponding to the error - * @return A {@link GF_Err} object - */ - public static GF_Err getError(int status) { - for (GF_Err x : values()) { - if (x.value == status) - return x; - } - return JAVA_UNKNOWN_ERROR; - } - } - - /** - * Mapping between GPAC Log Modules and Java symbols - * - * @version $Revision: 2888 $ - * - */ - public enum GF_Log_Module implements Comparable { - /** Log message from the core library (init, threads, network calls, etc) */ - GF_LOG_CORE(1), - /** Log message from a raw media parser (BIFS, LASeR, A/V formats) */ - GF_LOG_CODING(1 << 1), - /** Log message from a bitstream parser (IsoMedia, MPEG-2 TS, OGG, ...) */ - GF_LOG_CONTAINER(1 << 2), - /** Log message from the network/service stack (messages & co) */ - GF_LOG_NETWORK(1 << 3), - /** Log message from the RTP/RTCP stack (TS info) and packet structure & hinting (debug) */ - GF_LOG_RTP(1 << 4), - /** Log message from authoring subsystem (file manip, import/export) */ - GF_LOG_AUTHOR(1 << 5), - /** Log message from the sync layer of the terminal */ - GF_LOG_SYNC(1 << 6), - /** Log message from a codec */ - GF_LOG_CODEC(1 << 7), - /** Log message from any XML parser (context loading, etc) */ - GF_LOG_PARSER(1 << 8), - /** Log message from the terminal/compositor, indicating media object state */ - GF_LOG_MEDIA(1 << 9), - /** Log message from the scene graph/scene manager (handling of nodes and attribute modif, DOM core) */ - GF_LOG_SCENE(1 << 10), - /** Log message from the scripting engine */ - GF_LOG_SCRIPT(1 << 11), - /** Log message from event handling */ - GF_LOG_INTERACT(1 << 12), - /** Log message from compositor */ - GF_LOG_COMPOSE(1 << 13), - /** Log for video object cache */ - GF_LOG_CACHE(1 << 14), - /** Log message from multimedia I/O devices (audio/video input/output, ...) */ - GF_LOG_MMIO(1 << 15), - /** Log for runtime info (times, memory, CPU usage) */ - GF_LOG_RTI(1 << 16), - /** Log for SMIL timing and animation */ - GF_LOG_SMIL(1 << 17), - /** Log for memory tracker */ - GF_LOG_MEMORY(1 << 18), - /** Log for audio compositor */ - GF_LOG_AUDIO(1 << 19), - /** generic Log for modules */ - GF_LOG_MODULE(1 << 20), - /** - * Log for GPAC mutexes and threads (Very verbose at DEBUG) - * - */ - GF_LOG_MUTEX(1 << 21), - /** - * Unknown Log subsystem - */ - GF_LOG_UNKNOWN(1 << 30); - - int value; - - /** - * Private Constructor - */ - private GF_Log_Module(int x) { - this.value = x; - }; - - /** - * Finds a module from its module_code - * - * @param module_code - * @return The Module found (never null) - */ - public static GF_Log_Module getModule(int module_code) { - for (GF_Log_Module x : values()) { - if (x.value == module_code) - return x; - } - return GF_LOG_UNKNOWN; - } - } - - /** - * Display a message - * - * @param message - * @param title - * @param errorCode - */ - public void displayMessage(String message, String title, int errorCode); - - /** - * Called when logging - * - * @param level - * @param module - * @param message - */ - public void onLog(int level, int module, String message); - - /** - * Called when progress is set - * - * @param msg - * @param done - * @param total - */ - public void onProgress(String msg, int done, int total); - - /** - * Called when GPAC is ready - */ - public void onGPACReady(); - - /** - * Called when GPAC initialization fails - * - * @param e - */ - public void onGPACError(Throwable e); - - // /** - // * Returns UserName:Password for given site - // * - // * @param siteURL The URL of site requiring authorization - // * @param userName The User Name (may be null if never set) - // * @param password The password (may be null if never set) - // * @return A String formated as username:password - // */ - // public String onGPACAuthorization(String siteURL, String userName, String password); - - /** - * Set the new caption for the application - * - * @param newCaption The new caption to set for application - */ - public void setCaption(String newCaption); - - /** - * Show the virtual keyboard - * - * @param showKeyboard - */ - public void showKeyboard(boolean showKeyboard); -} diff --git a/applications/osmo4_android/src/com/artemis/Osmo4/GpacConfig.java b/applications/osmo4_android/src/com/artemis/Osmo4/GpacConfig.java deleted file mode 100644 index a0d0a69..0000000 --- a/applications/osmo4_android/src/com/artemis/Osmo4/GpacConfig.java +++ /dev/null @@ -1,170 +0,0 @@ -/** - * $URL: http://gpac.svn.sourceforge.net/svnroot/gpac/trunk/gpac/applications/osmo4_android/src/com/artemis/Osmo4/GpacConfig.java $ - * - * $LastChangedBy: bad_sheep $ - $LastChangedDate: 2011-04-20 08:42:10 -0400 (Wed, 20 Apr 2011) $ - */ -package com.artemis.Osmo4; - -import java.io.File; -import android.content.Context; -import android.content.pm.PackageManager.NameNotFoundException; -import android.os.Environment; -import android.util.Log; - -/** - * This class handles all GPAC configuration directories - * - * @author Pierre Souchay (VizionR SAS) (last changed by $LastChangedBy: bad_sheep $) - * @version $Revision: 2964 $ - * - */ -public class GpacConfig { - - private final static String LOG_GPAC_CONFIG = GpacConfig.class.getSimpleName(); - - /** - * Default Constructor - * - * @param context - */ - public GpacConfig(Context context) { - File rootCfg = Environment.getExternalStorageDirectory(); - File osmo = new File(rootCfg, "osmo"); //$NON-NLS-1$ - gpacConfigDirectory = osmo.getAbsolutePath() + '/'; - Log.v(LOG_GPAC_CONFIG, "Using directory " + gpacConfigDirectory + " for osmo"); //$NON-NLS-1$ //$NON-NLS-2$ - gpacCacheDirectory = new File(osmo, "cache").getAbsolutePath() + '/'; //$NON-NLS-1$ - Log.v(LOG_GPAC_CONFIG, "Using directory " + gpacCacheDirectory + " for cache"); //$NON-NLS-1$ //$NON-NLS-2$ - //gpacModulesDirectory = (new File(Environment.getDataDirectory() + "/data", "com.artemis.Osmo4")).getAbsolutePath() + '/'; //$NON-NLS-1$ //$NON-NLS-2$ - //Log.v(LOG_GPAC_CONFIG, "Using directory " + gpacModulesDirectory + " for modules"); //$NON-NLS-1$ //$NON-NLS-2$ - String dataDir; - try { - if (context == null || context.getPackageManager() == null) { - dataDir = Environment.getDataDirectory() + "/data/com.artemis.Osmo4/"; //$NON-NLS-1$ - Log.e(LOG_GPAC_CONFIG, "Cannot get context or PackageManager, using default directory=" + dataDir); //$NON-NLS-1$ - } else - dataDir = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0).dataDir; - } catch (NameNotFoundException e) { - Log.e(LOG_GPAC_CONFIG, "This is bad, we cannot find ourself : " + context.getPackageName(), e); //$NON-NLS-1$ - throw new RuntimeException("Cannot find package " + context.getPackageName(), e); //$NON-NLS-1$ - } - gpacLibsDirectory = dataDir + "/lib/"; //$NON-NLS-1$ - Log.v(LOG_GPAC_CONFIG, "Using directory " + gpacLibsDirectory + " for libraries"); //$NON-NLS-1$ //$NON-NLS-2$ - - } - - /** - * Ensures all directories are created - * - * @return The {@link GpacConfig} instance itself - */ - public GpacConfig ensureAllDirectoriesExist() { - for (String s : new String[] { gpacConfigDirectory, gpacCacheDirectory }) { - createDirIfNotExist(s); - } - return this; - } - - private final String gpacConfigDirectory; - - /** - * Default directory for GPAC configuration directory, ends with / - * - * @return the gpacConfigDirectory - */ - public String getGpacConfigDirectory() { - return gpacConfigDirectory; - } - - /** - * Directory of Android containing all fonts - * - * @return the gpacFontDirectory - */ - public String getGpacFontDirectory() { - return gpacFontDirectory; - } - - /** - * Default directory for GPAC modules directory, ends with / - * - * @return the gpacModulesDirectory - */ - public String getGpacModulesDirectory() { - // return gpacModulesDirectory; - return gpacLibsDirectory; - } - - /** - * @return the gpacLibsDirectory - */ - public String getGpacLibsDirectory() { - return gpacLibsDirectory; - } - - /** - * Default directory for cached files - * - * @return the gpacCacheDirectory - */ - public String getGpacCacheDirectory() { - return gpacCacheDirectory; - } - - private final String gpacFontDirectory = "/system/fonts/"; //$NON-NLS-1$ - - // private final String gpacModulesDirectory; - - private final String gpacLibsDirectory; - - private final String gpacCacheDirectory; - - /** - * Creates a given directory if it does not exist - * - * @param path - */ - private static boolean createDirIfNotExist(String path) { - File f = new File(path); - if (!f.exists()) { - if (!f.mkdirs()) { - Log.e(LOG_GPAC_CONFIG, "Failed to create directory " + path); //$NON-NLS-1$ - return false; - } else { - Log.i(LOG_GPAC_CONFIG, "Created directory " + path); //$NON-NLS-1$ - } - } - return true; - } - - /** - * Get the GPAC.cfg file - * - * @return the file - */ - public File getGpacConfigFile() { - return new File(getGpacConfigDirectory(), "GPAC.cfg"); //$NON-NLS-1$ - } - - /** - * Get the GPAC.cfg file - * - * @return the file - */ - public File getGpacLastRevFile() { - return new File(getGpacCacheDirectory(), "lastRev.txt"); //$NON-NLS-1$ - } - - /** - * Get the configuration as text - * - * @return a String with newlines representing all the configuration - */ - public String getConfigAsText() { - StringBuilder sb = new StringBuilder(); - sb.append("GpacConfigDirectory=").append(getGpacConfigDirectory()).append('\n'); //$NON-NLS-1$ - sb.append("GpacModulesDirectory=").append(getGpacModulesDirectory()).append('\n'); //$NON-NLS-1$ - sb.append("GpacFontDirectory=").append(getGpacFontDirectory()).append('\n'); //$NON-NLS-1$ - sb.append("GpacCacheDirectory=").append(getGpacCacheDirectory()).append('\n'); //$NON-NLS-1$ - return sb.toString(); - } -} diff --git a/applications/osmo4_android/src/com/artemis/Osmo4/Osmo4.java b/applications/osmo4_android/src/com/artemis/Osmo4/Osmo4.java deleted file mode 100644 index c234886..0000000 --- a/applications/osmo4_android/src/com/artemis/Osmo4/Osmo4.java +++ /dev/null @@ -1,943 +0,0 @@ -/** - * Osmo on Android - * Aug/2010 - * NGO Van Luyen - * $Id: Osmo4.java 2964 2011-04-20 12:42:10Z bad_sheep $ - * - */ -package com.artemis.Osmo4; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.ProgressDialog; -import android.content.ActivityNotFoundException; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.DialogInterface.OnClickListener; -import android.content.res.Configuration; -import android.net.Uri; -import android.os.Bundle; -import android.os.PowerManager; -import android.os.PowerManager.WakeLock; -import android.text.InputType; -import android.util.Log; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.Window; -import android.view.WindowManager; -import android.view.inputmethod.InputMethodManager; -import android.widget.ArrayAdapter; -import android.widget.AutoCompleteTextView; -import android.widget.Toast; -import com.artemis.Osmo4.extra.FileChooserActivity; -import com.artemis.Osmo4.logs.GpacLogger; - -/** - * The main Osmo4 activity, used to launch everything - * - * @version $Revision: 2964 $ - * - */ -public class Osmo4 extends Activity implements GpacCallback { - - // private String[] m_modules_list; - - private boolean shouldDeleteGpacConfig = false; - - /** - * @return the shouldDeleteGpacConfig - */ - public synchronized boolean isShouldDeleteGpacConfig() { - return shouldDeleteGpacConfig; - } - - /** - * @param shouldDeleteGpacConfig the shouldDeleteGpacConfig to set - */ - public synchronized void setShouldDeleteGpacConfig(boolean shouldDeleteGpacConfig) { - this.shouldDeleteGpacConfig = shouldDeleteGpacConfig; - } - - private final static String CFG_STARTUP_CATEGORY = "General"; //$NON-NLS-1$ - - private final static String CFG_STARTUP_NAME = "StartupFile"; //$NON-NLS-1$ - - private boolean keyboardIsVisible = false; - - private final static int DEFAULT_BUFFER_SIZE = 8192; - - private GpacConfig gpacConfig; - - /** - * Activity request ID for picking a file from local file system - */ - public final static int PICK_FILE_REQUEST = 1; - - private final static String LOG_OSMO_TAG = "Osmo4"; //$NON-NLS-1$ - - /** - * List of all extensions recognized by Osmo - */ - public final static String OSMO_REGISTERED_FILE_EXTENSIONS = "*.mp4,*.bt,*.xmt,*.xml,*.ts,*.svg,*.mp3,*.m3u8,*.mpg,*.aac,*.m4a,*.jpg,*.png"; //$NON-NLS-1$ - - private PowerManager.WakeLock wl = null; - - private Osmo4GLSurfaceView mGLView; - - private GpacLogger logger; - - private ProgressDialog startupProgress; - - // --------------------------------------- - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - requestWindowFeature(Window.FEATURE_PROGRESS); - requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); - - final String toOpen; - if (Intent.ACTION_VIEW.equals(getIntent().getAction())) { - Uri uri = getIntent().getData(); - if (uri != null) { - synchronized (this) { - toOpen = uri.toString(); - } - } else - toOpen = null; - } else - toOpen = null; - if (gpacConfig == null) { - gpacConfig = new GpacConfig(this); - if (gpacConfig == null) - Log.e(LOG_OSMO_TAG, "Failed to load GPAC config"); //$NON-NLS-1$ - else - gpacConfig.ensureAllDirectoriesExist(); - } - if (logger == null) - logger = new GpacLogger(gpacConfig); - logger.onCreate(); - if (startupProgress == null) { - startupProgress = new ProgressDialog(this); - startupProgress.setCancelable(false); - } - startupProgress.setMessage(getResources().getText(R.string.osmoLoading)); - startupProgress.setTitle(R.string.osmoLoading); - startupProgress.show(); - if (mGLView != null) { - setContentView(mGLView); - if (toOpen != null) - openURLasync(toOpen); - // OK, it means activity has already been started - return; - } - mGLView = new Osmo4GLSurfaceView(Osmo4.this); - service.submit(new Runnable() { - - @Override - public void run() { - // loadAllModules(); - runOnUiThread(new Runnable() { - - @Override - public void run() { - startupProgress.setIndeterminate(true); - startupProgress.setMessage(getResources().getText(R.string.gpacLoading)); - PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); - WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, LOG_OSMO_TAG); - if (wl != null) - wl.acquire(); - synchronized (Osmo4.this) { - Osmo4.this.wl = wl; - } - - Osmo4Renderer renderer = new Osmo4Renderer(Osmo4.this, gpacConfig, toOpen); - mGLView.setRenderer(renderer); - setContentView(mGLView); - } - }); - - } - }); - - } - - // --------------------------------------- - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater inflater = getMenuInflater(); - inflater.inflate(R.menu.main_menu, menu); - return true; - } - - private String getRecentURLsFile() { - return gpacConfig.getGpacConfigDirectory() + "recentURLs.txt"; //$NON-NLS-1$ - } - - private boolean openURL() { - Future res = service.submit(new Callable() { - - @Override - public String[] call() throws Exception { - BufferedReader reader = null; - try { - reader = new BufferedReader(new InputStreamReader(new FileInputStream(getRecentURLsFile()), - DEFAULT_ENCODING), DEFAULT_BUFFER_SIZE); - - String s = null; - Set results = new HashSet(); - while (null != (s = reader.readLine())) { - results.add(s); - } - addAllRecentURLs(results); - return results.toArray(new String[0]); - } finally { - if (reader != null) - reader.close(); - } - } - }); - AlertDialog.Builder builder = new AlertDialog.Builder(this); - final AutoCompleteTextView textView = new AutoCompleteTextView(this); - textView.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI); - - builder.setMessage("Please enter an URL to connect to...") //$NON-NLS-1$ - .setCancelable(true) - .setPositiveButton("Open URL", new DialogInterface.OnClickListener() { //$NON-NLS-1$ - - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - final String newURL = textView.getText().toString(); - openURLasync(newURL); - service.execute(new Runnable() { - - @Override - public void run() { - addAllRecentURLs(Collections.singleton(newURL)); - File tmp = new File(getRecentURLsFile() + ".tmp"); //$NON-NLS-1$ - BufferedWriter w = null; - try { - w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tmp), - DEFAULT_ENCODING), - DEFAULT_BUFFER_SIZE); - Collection toWrite = getAllRecentURLs(); - for (String s : toWrite) { - w.write(s); - w.write("\n"); //$NON-NLS-1$ - } - w.close(); - w = null; - if (tmp.renameTo(new File(getRecentURLsFile()))) - Log.e(LOG_OSMO_TAG, - "Failed to rename " + tmp + " to " + getRecentURLsFile()); //$NON-NLS-1$//$NON-NLS-2$ - - } catch (IOException e) { - Log.e(LOG_OSMO_TAG, "Failed to write recent URLs to " + tmp, e); //$NON-NLS-1$ - try { - if (w != null) - w.close(); - } catch (IOException ex) { - Log.e(LOG_OSMO_TAG, "Failed to close stream " + tmp, ex); //$NON-NLS-1$ - } - } - - } - }); - } - }) - .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { //$NON-NLS-1$ - - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - } - }); - - textView.setText("http://"); //$NON-NLS-1$ - builder.setView(textView); - - builder.show(); - ArrayAdapter adapter; - try { - adapter = new ArrayAdapter(this, - android.R.layout.simple_dropdown_item_1line, - res.get(1, TimeUnit.SECONDS)); - textView.setAdapter(adapter); - } catch (ExecutionException e) { - // Ignored - Log.e(LOG_OSMO_TAG, "Error while parsing recent URLs", e); //$NON-NLS-1$ - } catch (TimeoutException e) { - Log.e(LOG_OSMO_TAG, "It took too long to parse recent URLs", e); //$NON-NLS-1$ - } catch (InterruptedException e) { - Log.e(LOG_OSMO_TAG, "Interrupted while parsing recent URLs", e); //$NON-NLS-1$ - } - - return true; - } - - private final ExecutorService service = Executors.newSingleThreadExecutor(); - - private final Set allRecentURLs = new HashSet(); - - private synchronized void addAllRecentURLs(Collection urlsToAdd) { - allRecentURLs.addAll(urlsToAdd); - } - - private synchronized Collection getAllRecentURLs() { - return new ArrayList(allRecentURLs); - } - - private final static Charset DEFAULT_ENCODING = Charset.forName("UTF-8"); //$NON-NLS-1$ - - /** - * Opens a new activity to select a file - * - * @return true if activity has been selected - */ - private boolean openFileDialog() { - String title = getResources().getString(R.string.pleaseSelectAFile); - Uri uriDefaultDir = Uri.fromFile(new File(gpacConfig.getGpacConfigDirectory())); - Intent intent = new Intent(); - intent.setAction(Intent.ACTION_PICK); - // Files and directories - intent.setDataAndType(uriDefaultDir, "vnd.android.cursor.dir/lysesoft.andexplorer.file"); //$NON-NLS-1$ - // Optional filtering on file extension. - intent.putExtra("browser_filter_extension_whitelist", OSMO_REGISTERED_FILE_EXTENSIONS); //$NON-NLS-1$ - // Title - intent.putExtra("explorer_title", title); //$NON-NLS-1$ - - try { - startActivityForResult(intent, PICK_FILE_REQUEST); - return true; - } catch (ActivityNotFoundException e) { - // OK, lets try with another one... (it includes out bundled one) - intent = new Intent("org.openintents.action.PICK_FILE"); //$NON-NLS-1$ - intent.setData(uriDefaultDir); - intent.putExtra(FileChooserActivity.TITLE_PARAMETER, title); - intent.putExtra("browser_filter_extension_whitelist", OSMO_REGISTERED_FILE_EXTENSIONS); //$NON-NLS-1$ - try { - startActivityForResult(intent, PICK_FILE_REQUEST); - return true; - } catch (ActivityNotFoundException ex) { - // Not found neither... We build our own dialog to display error - // Note that this should happen only if we did not embed out own intent - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setMessage("Impossible to find an Intent to choose a file... Cannot open file !") //$NON-NLS-1$ - .setCancelable(true) - .setPositiveButton("Close", new DialogInterface.OnClickListener() { //$NON-NLS-1$ - - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - } - }); - AlertDialog alert = builder.create(); - alert.show(); - return false; - } - } - } - - // --------------------------------------- - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent intent) { - if (requestCode == PICK_FILE_REQUEST) { - if (resultCode == RESULT_OK) { - Uri uri = intent.getData(); - if (uri != null) { - String url = uri.toString(); - String file = "file://"; //$NON-NLS-1$ - if (url.startsWith(file)) { - url = uri.getPath(); - } - Log.i(LOG_OSMO_TAG, "Requesting opening local file " + url); //$NON-NLS-1$ - openURLasync(url); - } - } - } - } - - private String currentURL; - - private void openURLasync(final String url) { - service.execute(new Runnable() { - - @Override - public void run() { - mGLView.connect(url); - currentURL = url; - runOnUiThread(new Runnable() { - - @Override - public void run() { - setTitle(getResources().getString(R.string.titleWithURL, url)); - } - }); - } - }); - } - - // --------------------------------------- - - @Override - public void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - } - - // --------------------------------------- - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - // Handle item selection - switch (item.getItemId()) { - case R.id.open_url: - return openURL(); - case R.id.open_file: - // newGame(); - return openFileDialog(); - case R.id.cleanCache: - return cleanCache(); - case R.id.showVirtualKeyboard: - showKeyboard(true); - return true; - case R.id.setAsStartupFile: { - AlertDialog.Builder b = new AlertDialog.Builder(this); - b.setTitle(R.string.setAsStartupFileTitle); - if (currentURL != null) { - b.setMessage(getResources().getString(R.string.setAsStartupFileMessage, currentURL)); - b.setPositiveButton(R.string.setAsStartupFileYes, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - mGLView.setGpacPreference(CFG_STARTUP_CATEGORY, CFG_STARTUP_NAME, currentURL); - } - }); - } else { - b.setMessage(getResources().getString(R.string.setAsStartupFileMessageNoURL)); - } - b.setNegativeButton(R.string.setAsStartupFileNo, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - } - }); - b.setNeutralButton(R.string.setAsStartupFileNull, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - mGLView.setGpacPreference(CFG_STARTUP_CATEGORY, CFG_STARTUP_NAME, null); - } - }); - b.show(); - return true; - } - case R.id.resetGpacConfig: { - AlertDialog.Builder b = new AlertDialog.Builder(this); - b.setCancelable(true); - b.setTitle(R.string.resetGpacConfig); - b.setMessage(R.string.resetGpacConfigMessage); - b.setNegativeButton(R.string.cancel_button, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - } - }); - b.setPositiveButton(R.string.ok_button, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - setShouldDeleteGpacConfig(true); - deleteConfigIfNeeded(); - } - }); - b.show(); - return true; - } - case R.id.about: { - Dialog d = new Dialog(this); - d.setTitle(R.string.aboutTitle); - d.setCancelable(true); - d.setContentView(R.layout.about_dialog); - d.show(); - } - return true; - case R.id.quit: - this.finish(); - mGLView.destroy(); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - - protected boolean cleanCache() { - final CharSequence oldTitle = getTitle(); - runOnUiThread(new Runnable() { - - @Override - public void run() { - startupProgress.setTitle(R.string.cleaningCache); - startupProgress.setMessage(getResources().getString(R.string.cleaningCache, - gpacConfig.getGpacCacheDirectory())); - startupProgress.setProgress(0); - startupProgress.setIndeterminate(false); - startupProgress.show(); - } - }); - service.submit(new Runnable() { - - @Override - public void run() { - File dir = new File(gpacConfig.getGpacCacheDirectory()); - if (!dir.exists() || !dir.canRead() || !dir.canWrite() || !dir.isDirectory()) { - return; - } - File files[] = dir.listFiles(); - int i = 0; - for (File f : files) { - if (f.isFile()) - if (!f.delete()) { - Log.w(LOG_OSMO_TAG, "Failed to delete file " + f); //$NON-NLS-1$ - } else { - Log.v(LOG_OSMO_TAG, f + " has been deleted"); //$NON-NLS-1$ - } - final int percent = (++i) * 100 / files.length; - runOnUiThread(new Runnable() { - - @Override - public void run() { - startupProgress.setProgress(percent); - } - }); - } - runOnUiThread(new Runnable() { - - @Override - public void run() { - startupProgress.setProgress(100); - startupProgress.setTitle(oldTitle); - startupProgress.dismiss(); - } - }); - } - }); - return true; - } - - private void deleteConfigIfNeeded() { - if (isShouldDeleteGpacConfig()) { - Log.i(LOG_OSMO_TAG, "Deleting GPAC config file..."); //$NON-NLS-1$ - File f = gpacConfig.getGpacConfigFile(); - if (f.exists() && !f.delete()) { - Log.e(LOG_OSMO_TAG, "Failed to delete " + f.getAbsolutePath()); //$NON-NLS-1$ - } - f = gpacConfig.getGpacLastRevFile(); - if (f.exists() && !f.delete()) { - Log.e(LOG_OSMO_TAG, "Failed to delete " + f.getAbsolutePath()); //$NON-NLS-1$ - } - } - } - - // --------------------------------------- - @Override - protected void onDestroy() { - deleteConfigIfNeeded(); - service.shutdown(); - logger.onDestroy(); - synchronized (this) { - if (wl != null) - wl.release(); - } - Log.d(LOG_OSMO_TAG, "Disconnecting instance..."); //$NON-NLS-1$ - mGLView.disconnect(); - Log.d(LOG_OSMO_TAG, "Destroying GPAC instance..."); //$NON-NLS-1$ - mGLView.destroy(); - // Deleteing is done two times if GPAC fails to shutdown by crashing... - deleteConfigIfNeeded(); - super.onDestroy(); - } - - // --------------------------------------- - // private void loadAllModules() { - // Log.i(LOG_OSMO_TAG, "Start loading all modules..."); //$NON-NLS-1$ - // long start = System.currentTimeMillis(); - // byte buffer[] = new byte[1024]; - // int[] ids = getAllRawResources(); - // String currentRevision = "$Revision: 2964 $"; //$NON-NLS-1$ - // File revisionFile = gpacConfig.getGpacLastRevFile(); - // boolean fastStartup = false; - // // We check if we already copied all the modules once without error... - // if (revisionFile.exists() && revisionFile.canRead()) { - // BufferedReader r = null; - // try { - // r = new BufferedReader(new InputStreamReader(new FileInputStream(revisionFile), DEFAULT_ENCODING), - // DEFAULT_BUFFER_SIZE); - // String rev = r.readLine(); - // if (currentRevision.equals(rev)) { - // fastStartup = true; - // } - // } catch (IOException ignored) { - // } finally { - // // Exception or not, always close the stream... - // if (r != null) - // try { - // r.close(); - // } catch (IOException ignored) { - // } - // } - // } - // boolean noErrors = true; - // final StringBuilder errorsMsg = new StringBuilder(); - // for (int i = 0; i < ids.length; i++) { - // OutputStream fos = null; - // InputStream ins = null; - // String fn = gpacConfig.getGpacModulesDirectory() + m_modules_list[i] + ".so"; //$NON-NLS-1$ - // File finalFile = new File(fn); - // // If file has already been copied, not need to do it again - // if (fastStartup && finalFile.exists() && finalFile.canRead()) { - // Log.i(LOG_OSMO_TAG, "Skipping " + finalFile); //$NON-NLS-1$ - // continue; - // } - // try { - // final String msg = getResources().getString(R.string.copying_native_libs, - // finalFile.getName(), - // finalFile.getParent()); - // runOnUiThread(new Runnable() { - // - // @Override - // public void run() { - // startupProgress.setIndeterminate(false); - // startupProgress.setMessage(msg); - // } - // }); - // Log.i(LOG_OSMO_TAG, "Copying resource " + ids[i] + " to " //$NON-NLS-1$//$NON-NLS-2$ - // + finalFile.getAbsolutePath()); - // File tmpFile = new File(fn + ".tmp"); //$NON-NLS-1$ - // int read; - // ins = new BufferedInputStream(getResources().openRawResource(ids[i]), DEFAULT_BUFFER_SIZE); - // fos = new BufferedOutputStream(new FileOutputStream(tmpFile), DEFAULT_BUFFER_SIZE); - // while (0 < (read = ins.read(buffer))) { - // fos.write(buffer, 0, read); - // } - // ins.close(); - // ins = null; - // fos.close(); - // fos = null; - // if (!tmpFile.renameTo(finalFile)) { - // if (finalFile.exists() && finalFile.delete() && !tmpFile.renameTo(finalFile)) - // Log.e(LOG_OSMO_TAG, "Failed to rename " + tmpFile.getAbsolutePath() + " to " //$NON-NLS-1$//$NON-NLS-2$ - // + finalFile.getAbsolutePath()); - // } - // final int percent = i * 10000 / ids.length; - // runOnUiThread(new Runnable() { - // - // @Override - // public void run() { - // startupProgress.setProgress(percent); - // } - // }); - // } catch (IOException e) { - // noErrors = false; - // String msg = "IOException for resource : " + ids[i]; //$NON-NLS-1$ - // errorsMsg.append(msg).append('\n').append(finalFile.getAbsolutePath()).append('\n'); - // errorsMsg.append(e.getLocalizedMessage()); - // Log.e(LOG_OSMO_TAG, msg, e); - // } finally { - // if (ins != null) { - // try { - // ins.close(); - // } catch (IOException e) { - // Log.e(LOG_OSMO_TAG, "Error while closing read stream", e); //$NON-NLS-1$ - // } - // } - // if (fos != null) { - // try { - // fos.close(); - // } catch (IOException e) { - // Log.e(LOG_OSMO_TAG, "Error while closing write stream", e); //$NON-NLS-1$ - // } - // } - // } - // } - // // If no error during copy, fast startup will be enabled for next time - // if (noErrors && !fastStartup) { - // BufferedWriter w = null; - // try { - // w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(revisionFile), DEFAULT_ENCODING), - // DEFAULT_BUFFER_SIZE); - // w.write(currentRevision); - // w.write('\n'); - // // We add the date as second line to ease debug in case of problem - // w.write(String.valueOf(new Date())); - // } catch (IOException ignored) { - // } finally { - // if (w != null) - // try { - // w.close(); - // } catch (IOException ignored) { - // } - // } - // } else { - // if (!noErrors) { - // setShouldDeleteGpacConfig(true); - // displayMessage(errorsMsg.toString(), "Errors while copying modules !", GF_Err.GF_IO_ERR.value); //$NON-NLS-1$ - // } - // } - // Log.i(LOG_OSMO_TAG, "Done loading all modules, took " + (System.currentTimeMillis() - start) + "ms."); //$NON-NLS-1$ //$NON-NLS-2$ - // startupProgress.setProgress(100); - // startupProgress.setIndeterminate(true); - // runOnUiThread(new Runnable() { - // - // @Override - // public void run() { - // setTitle(LOG_OSMO_TAG); - // } - // }); - // } - - // private int[] getAllRawResources() throws RuntimeException { - // R.raw r = new R.raw(); - // - // java.lang.reflect.Field fields[] = R.raw.class.getDeclaredFields(); - // final int ids[] = new int[fields.length]; - // m_modules_list = new String[fields.length]; - // - // try { - // for (int i = 0; i < fields.length; i++) { - // java.lang.reflect.Field f = fields[i]; - // ids[i] = f.getInt(r); - // m_modules_list[i] = f.getName(); - // Log.i(LOG_OSMO_TAG, "R.raw." + f.getName() + " = 0x" + Integer.toHexString(ids[i])); //$NON-NLS-1$ //$NON-NLS-2$ - // } - // } catch (IllegalArgumentException e) { - // throw new RuntimeException(e); - // } catch (IllegalAccessException e) { - // throw new RuntimeException(e); - // } - // - // return ids; - // } - - // --------------------------------------- - - private String lastDisplayedMessage; - - private void displayPopup(CharSequence message, CharSequence title) { - final String fullMsg = getResources().getString(R.string.displayPopupFormat, title, message); - synchronized (this) { - if (fullMsg.equals(lastDisplayedMessage)) - return; - lastDisplayedMessage = fullMsg; - } - runOnUiThread(new Runnable() { - - @Override - public void run() { - Toast toast = Toast.makeText(Osmo4.this, fullMsg, Toast.LENGTH_SHORT); - toast.show(); - } - }); - - } - - /** - * @see com.artemis.Osmo4.GpacCallback#displayMessage(String, String, int) - */ - @Override - public void displayMessage(final String message, final String title, final int status) { - if (status == GF_Err.GF_OK.value) - displayPopup(message, title); - else { - runOnUiThread(new Runnable() { - - @Override - public void run() { - StringBuilder sb = new StringBuilder(); - sb.append(GF_Err.getError(status)); - sb.append(' '); - sb.append(title); - AlertDialog.Builder builder = new AlertDialog.Builder(Osmo4.this); - builder.setTitle(sb.toString()); - sb.append('\n'); - sb.append(message); - builder.setMessage(sb.toString()); - builder.setCancelable(true); - builder.setPositiveButton(R.string.ok_button, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.cancel(); - } - }); - try { - builder.create().show(); - } catch (WindowManager.BadTokenException e) { - // May happen when we close the window and there are still somes messages - Log.e(LOG_OSMO_TAG, "Failed to display Message " + sb.toString(), e); //$NON-NLS-1$ - } - } - }); - } - } - - /** - * @see com.artemis.Osmo4.GpacCallback#onLog(int, int, String) - */ - @Override - public void onLog(int level, int module, String message) { - logger.onLog(level, module, message); - } - - /** - * @see com.artemis.Osmo4.GpacCallback#onProgress(java.lang.String, int, int) - */ - @Override - public void onProgress(final String msg, final int done, final int total) { - if (Log.isLoggable(LOG_OSMO_TAG, Log.DEBUG)) - Log.d(LOG_OSMO_TAG, "Setting progress to " + done + "/" + total + ", message=" + msg); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - runOnUiThread(new Runnable() { - - @Override - public void run() { - // GPAC sometimes return total = 0 - if (total < 1) { - setProgressBarIndeterminate(true); - } else { - int progress = done * 10000 / (total < 1 ? 1 : total); - if (progress > 9900) - progress = 10000; - setProgressBarIndeterminate(false); - setProgress(progress); - } - } - }); - } - - /** - * @see com.artemis.Osmo4.GpacCallback#onGPACReady() - */ - @Override - public void onGPACReady() { - startupProgress.dismiss(); - Log.i(LOG_OSMO_TAG, "GPAC is ready"); //$NON-NLS-1$ - } - - /** - * @see com.artemis.Osmo4.GpacCallback#onGPACError(java.lang.Throwable) - */ - @Override - public void onGPACError(final Throwable e) { - startupProgress.dismiss(); - Log.e(LOG_OSMO_TAG, "GPAC Error", e); //$NON-NLS-1$ - runOnUiThread(new Runnable() { - - @Override - public void run() { - // In such case, we force GPAC Configuration file deletion - setShouldDeleteGpacConfig(true); - StringBuilder sb = new StringBuilder(); - sb.append("Failed to init GPAC due to "); //$NON-NLS-1$ - sb.append(e.getClass().getSimpleName()); - AlertDialog.Builder builder = new AlertDialog.Builder(Osmo4.this); - builder.setTitle(sb.toString()); - sb.append('\n'); - sb.append("Description: "); //$NON-NLS-1$ - sb.append(e.getLocalizedMessage()); - sb.append('\n'); - sb.append("Revision: $Revision: 2964 $"); //$NON-NLS-1$ - sb.append("\nConfiguration information :\n") //$NON-NLS-1$ - .append(gpacConfig.getConfigAsText()); - builder.setMessage(sb.toString()); - builder.setCancelable(true); - builder.setPositiveButton(R.string.ok_button, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.cancel(); - } - }); - builder.create().show(); - } - }); - } - - @Override - protected void onPause() { - super.onPause(); - if (mGLView != null) - mGLView.onPause(); - } - - @Override - protected void onResume() { - super.onResume(); - if (mGLView != null) - mGLView.onResume(); - } - - /** - * @see com.artemis.Osmo4.GpacCallback#setCaption(java.lang.String) - */ - @Override - public void setCaption(final String newCaption) { - runOnUiThread(new Runnable() { - - @Override - public void run() { - setTitle(newCaption); - } - }); - } - - /** - * @see android.app.Activity#onStop() - */ - @Override - protected void onStop() { - Log.i(LOG_OSMO_TAG, "onStop called on activity"); //$NON-NLS-1$ - super.onStop(); - } - - /** - * @see com.artemis.Osmo4.GpacCallback#showKeyboard(boolean) - */ - @Override - public void showKeyboard(boolean showKeyboard) { - if (keyboardIsVisible == showKeyboard == true) - return; - InputMethodManager mgr = ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE)); - this.keyboardIsVisible = showKeyboard; - if (showKeyboard) - mgr.showSoftInput(mGLView, 0); - else - mgr.hideSoftInputFromInputMethod(mGLView.getWindowToken(), 0); - - } -} diff --git a/applications/osmo4_android/src/com/artemis/Osmo4/Osmo4GLSurfaceView.java b/applications/osmo4_android/src/com/artemis/Osmo4/Osmo4GLSurfaceView.java deleted file mode 100644 index ee41d71..0000000 --- a/applications/osmo4_android/src/com/artemis/Osmo4/Osmo4GLSurfaceView.java +++ /dev/null @@ -1,204 +0,0 @@ -package com.artemis.Osmo4; - -import android.content.Context; -import android.opengl.GLSurfaceView; -import android.util.Log; -import android.view.KeyEvent; -import android.view.MotionEvent; - -/** - * The view represented the blitted contents by libgpac - * - * @version $Revision: 2942 $ - * - */ -public class Osmo4GLSurfaceView extends GLSurfaceView implements GPACInstanceInterface { - - private final static String LOG_GL_SURFACE = Osmo4GLSurfaceView.class.getSimpleName(); - - /** - * Constructor - * - * @param context - */ - public Osmo4GLSurfaceView(Context context) { - super(context); - setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS); - setFocusable(true); - setFocusableInTouchMode(true); - } - - private Osmo4Renderer gpacRenderer; - - /** - * Set the renderer - * - * @param renderer - */ - public void setRenderer(Osmo4Renderer renderer) { - synchronized (this) { - this.gpacRenderer = renderer; - } - super.setRenderer(renderer); - setRenderMode(RENDERMODE_CONTINUOUSLY); - } - - private synchronized Osmo4Renderer getGpacRenderer() { - return gpacRenderer; - } - - private GPACInstance getInstance() { - Osmo4Renderer r = getGpacRenderer(); - if (r == null) - return null; - return r.getInstance(); - } - - // ------------------------------------ - @Override - public boolean onTouchEvent(final MotionEvent event) { - queueEvent(new Runnable() { - - @Override - public void run() { - GPACInstance instance = getInstance(); - if (instance != null) - instance.motionEvent(event); - } - }); - return true; - } - - /** - * Should we handle this key in GPAC ? - * - * @param keyCode - * @param event - * @return - */ - private static boolean handleInGPAC(int keyCode, KeyEvent event) { - if (event.isSystem()) - return false; - switch (keyCode) { - case KeyEvent.KEYCODE_MEDIA_STOP: - case KeyEvent.KEYCODE_MENU: - case KeyEvent.KEYCODE_BACK: - return false; - default: - return true; - } - } - - @Override - public boolean onKeyDown(final int keyCode, final KeyEvent event) { - if (handleInGPAC(keyCode, event)) { - Log.d(LOG_GL_SURFACE, "onKeyDown = " + keyCode); //$NON-NLS-1$ - queueEvent(new Runnable() { - - @Override - public void run() { - GPACInstance instance = getInstance(); - if (instance != null) - instance.eventKey(keyCode, event, true, event.getUnicodeChar()); - } - }); - return true; - } - return false; - } - - // ------------------------------------ - @Override - public boolean onKeyUp(final int keyCode, final KeyEvent event) { - if (handleInGPAC(keyCode, event)) { - Log.d(LOG_GL_SURFACE, "onKeyUp =" + keyCode); //$NON-NLS-1$ - queueEvent(new Runnable() { - - @Override - public void run() { - GPACInstance instance = getInstance(); - if (instance != null) - instance.eventKey(keyCode, event, false, event.getUnicodeChar()); - } - }); - return true; - } - return false; - } - - @Override - public void onResume() { - if (getInstance() != null) - super.onResume(); - } - - @Override - public void onPause() { - if (getInstance() != null) - super.onPause(); - } - - /** - * @see com.artemis.Osmo4.GPACInstanceInterface#connect(java.lang.String) - */ - @Override - public void connect(final String url) { - queueEvent(new Runnable() { - - @Override - public void run() { - GPACInstance instance = getInstance(); - if (instance != null) - instance.connect(url); - } - }); - } - - /** - * @see com.artemis.Osmo4.GPACInstanceInterface#disconnect() - */ - @Override - public void disconnect() { - queueEvent(new Runnable() { - - @Override - public void run() { - GPACInstance instance = getInstance(); - if (instance != null) - instance.disconnect(); - } - }); - } - - /** - * @see com.artemis.Osmo4.GPACInstanceInterface#destroy() - */ - @Override - public void destroy() { - queueEvent(new Runnable() { - - @Override - public void run() { - GPACInstance instance = getInstance(); - if (instance != null) - instance.destroy(); - } - }); - } - - /** - * @see com.artemis.Osmo4.GPACInstanceInterface#setGpacPreference(String, String, String) - */ - @Override - public void setGpacPreference(final String category, final String name, final String value) { - queueEvent(new Runnable() { - - @Override - public void run() { - GPACInstance instance = getInstance(); - if (instance != null) - instance.setGpacPreference(category, name, value); - } - }); - } -} diff --git a/applications/osmo4_android/src/com/artemis/Osmo4/Osmo4Renderer.java b/applications/osmo4_android/src/com/artemis/Osmo4/Osmo4Renderer.java deleted file mode 100644 index 4da698a..0000000 --- a/applications/osmo4_android/src/com/artemis/Osmo4/Osmo4Renderer.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.artemis.Osmo4; - -import javax.microedition.khronos.egl.EGLConfig; -import javax.microedition.khronos.opengles.GL10; -import android.opengl.GLSurfaceView; -import android.util.Log; - -/** - * The renderer - * - * @version $Revision: 2950 $ - * - */ -public class Osmo4Renderer implements GLSurfaceView.Renderer { - - private final GpacConfig gpacConfig; - - private final static String LOG_RENDERER = Osmo4Renderer.class.getSimpleName(); - - @Override - public void onSurfaceCreated(GL10 gl, EGLConfig config) { - if (instance == null) { - try { - Log.i(LOG_RENDERER, "Creating instance from thread " + Thread.currentThread()); //$NON-NLS-1$ - instance = new GPACInstance(callback, 320, 430, gpacConfig, urlToLoad); - } catch (com.artemis.Osmo4.GPACInstanceInterface.GpacInstanceException e) { - Log.e(LOG_RENDERER, "Failed to create new GPAC instance !"); //$NON-NLS-1$ - instance = null; - callback.onGPACError(e); - return; - } - if (callback != null) - callback.onGPACReady(); - } - } - - private GPACInstance instance = null; - - private final String urlToLoad; - - /** - * @return the urlToLoad - */ - public synchronized String getUrlToLoad() { - return urlToLoad; - } - - /** - * Constructor - * - * @param callback - * @param gpacConfig - * @param urlToLoad The URL to load at startup, can be null - */ - public Osmo4Renderer(GpacCallback callback, GpacConfig gpacConfig, String urlToLoad) { - this.callback = callback; - this.urlToLoad = urlToLoad; - this.gpacConfig = gpacConfig; - } - - private final GpacCallback callback; - - @Override - public void onSurfaceChanged(GL10 gl, int w, int h) { - // gl.glViewport(0, 0, w, h); - if (instance != null) { - Log.i(LOG_RENDERER, "Surface changed from thread " + Thread.currentThread()); //$NON-NLS-1$ - instance.resize(w, h); - } - } - - private int frames; - - private long startFrame = System.currentTimeMillis(); - - @Override - public void onDrawFrame(GL10 gl) { - if (instance != null) { - frames++; - if (frames % 1000 == 0) { - long now = System.currentTimeMillis(); - Log.i(LOG_RENDERER, "Frames Per Second = " + ((now - startFrame) / 1000) + " fps"); //$NON-NLS-1$//$NON-NLS-2$ - this.startFrame = now; - } - instance.render(); - } - } - - /** - * Get the current GPAC Instance - * - * @return the instance - */ - synchronized GPACInstance getInstance() { - return instance; - } -} diff --git a/applications/osmo4_android/src/com/artemis/Osmo4/extra/FileArrayAdapter.java b/applications/osmo4_android/src/com/artemis/Osmo4/extra/FileArrayAdapter.java deleted file mode 100644 index da0fd36..0000000 --- a/applications/osmo4_android/src/com/artemis/Osmo4/extra/FileArrayAdapter.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * $URL: http://gpac.svn.sourceforge.net/svnroot/gpac/trunk/gpac/applications/osmo4_android/src/com/artemis/Osmo4/extra/FileArrayAdapter.java $ - * - * $LastChangedBy: bad_sheep $ - $LastChangedDate: 2011-04-06 10:23:04 -0400 (Wed, 06 Apr 2011) $ - */ -package com.artemis.Osmo4.extra; - -import java.io.File; -import java.util.List; -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.TextView; -import com.artemis.Osmo4.R; - -/** - * Class that contains the list of file for given directory - * - * @version $Revision: 2864 $ - * - */ -public class FileArrayAdapter extends ArrayAdapter { - - private final Context context; - - private final int id; - - private final List items; - - /** - * Constructor - * - * @param context - * @param textViewResourceId - * @param objects - */ - public FileArrayAdapter(Context context, int textViewResourceId, List objects) { - super(context, textViewResourceId, objects); - this.context = context; - id = textViewResourceId; - items = objects; - } - - @Override - public FileEntry getItem(int i) { - return items.get(i); - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - View v = convertView; - if (v == null) { - LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - v = vi.inflate(id, null); - } - final FileEntry o = items.get(position); - if (o != null) { - TextView t1 = (TextView) v.findViewById(R.id.TextView01); - TextView t2 = (TextView) v.findViewById(R.id.TextView02); - - if (t1 != null) - t1.setText(o.getName()); - if (t2 != null) { - File f = o.getFile(); - if (f.isDirectory()) - t2.setText(context.getString(R.string.directory)); - else - t2.setText(context.getString(R.string.fileSize, f.length())); - } - } - return v; - } - -} diff --git a/applications/osmo4_android/src/com/artemis/Osmo4/extra/FileChooserActivity.java b/applications/osmo4_android/src/com/artemis/Osmo4/extra/FileChooserActivity.java deleted file mode 100644 index 0c1aa5d..0000000 --- a/applications/osmo4_android/src/com/artemis/Osmo4/extra/FileChooserActivity.java +++ /dev/null @@ -1,97 +0,0 @@ -/** - * $URL: http://gpac.svn.sourceforge.net/svnroot/gpac/trunk/gpac/applications/osmo4_android/src/com/artemis/Osmo4/extra/FileChooserActivity.java $ - * - * $LastChangedBy: bad_sheep $ - $LastChangedDate: 2011-04-06 10:23:04 -0400 (Wed, 06 Apr 2011) $ - */ -package com.artemis.Osmo4.extra; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import android.app.ListActivity; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.view.View; -import android.widget.ListView; -import com.artemis.Osmo4.R; - -/** - * @version $Revision: 2864 $ - * - */ -public class FileChooserActivity extends ListActivity { - - private File currentDir; - - private FileArrayAdapter adapter; - - /** - * The parameter name to use to search for title - */ - public final static String TITLE_PARAMETER = "org.openintents.extra.TITLE"; //$NON-NLS-1$ - - private String customTitle; - - private void updateTitle(File currentPath) { - setTitle(getResources().getString(R.string.selectFileTitlePattern, customTitle, currentPath.getAbsolutePath())); - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - Intent intent = getIntent(); - currentDir = new File("/"); //$NON-NLS-1$ - this.customTitle = getResources().getString(R.string.selectFileDefaultTitle); - if (intent != null) { - if (intent.getData() != null) { - File f = new File(intent.getData().getPath()); - if (f.exists() && f.isDirectory() && f.canRead()) - currentDir = f; - } - String title = intent.getExtras().getString(TITLE_PARAMETER); - if (title != null) - this.customTitle = title; - } - fillList(currentDir); - } - - private void fillList(File f) { - File[] dirs = f.listFiles(); - updateTitle(f); - List dir = new ArrayList(); - List fls = new ArrayList(); - if (dirs != null) { - for (File ff : dirs) { - dir.add(new FileEntry(ff.getAbsoluteFile())); - } - Collections.sort(dir); - Collections.sort(fls); - dir.addAll(fls); - } - if (f.getParentFile() != null) - dir.add(0, new FileEntry(f.getParentFile(), getResources().getString(R.string.parentDirectory))); - adapter = new FileArrayAdapter(this, R.layout.file_view, dir); - this.setListAdapter(adapter); - } - - @Override - protected void onListItemClick(ListView l, View v, int position, long id) { - super.onListItemClick(l, v, position, id); - FileEntry o = adapter.getItem(position); - if (o.getFile().isDirectory()) { - fillList(o.getFile()); - } else { - onFileClick(o); - } - } - - private void onFileClick(FileEntry o) { - Intent data = new Intent(); - data.setData(Uri.fromFile(o.getFile())); - setResult(RESULT_OK, data); - finish(); - } - -} diff --git a/applications/osmo4_android/src/com/artemis/Osmo4/extra/FileEntry.java b/applications/osmo4_android/src/com/artemis/Osmo4/extra/FileEntry.java deleted file mode 100644 index 9138a0a..0000000 --- a/applications/osmo4_android/src/com/artemis/Osmo4/extra/FileEntry.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * $URL: http://gpac.svn.sourceforge.net/svnroot/gpac/trunk/gpac/applications/osmo4_android/src/com/artemis/Osmo4/extra/FileEntry.java $ - * - * $LastChangedBy: bad_sheep $ - $LastChangedDate: 2011-04-06 10:23:04 -0400 (Wed, 06 Apr 2011) $ - */ -package com.artemis.Osmo4.extra; - -import java.io.File; - -/** - * @version $Revision: 2864 $ - * - */ -public class FileEntry implements Comparable { - - private final File file; - - private final String name; - - /** - * Constructor - * - * @param f - */ - public FileEntry(File f) { - this.file = f; - this.name = f.getName(); - } - - /** - * Constructor - * - * @param f - * @param name The name to use - */ - public FileEntry(File f, String name) { - this.file = f.getAbsoluteFile(); - this.name = name; - } - - /** - * Get the name of option - * - * @return The name of option - */ - public String getName() { - return name; - } - - @Override - public int compareTo(FileEntry o) { - return getName().toLowerCase().compareTo(o.getName()); - } - - /** - * @return the file - */ - public File getFile() { - return file; - } -} \ No newline at end of file diff --git a/applications/osmo4_android/src/com/artemis/Osmo4/logs/GpacLogger.java b/applications/osmo4_android/src/com/artemis/Osmo4/logs/GpacLogger.java deleted file mode 100644 index 6a93ffe..0000000 --- a/applications/osmo4_android/src/com/artemis/Osmo4/logs/GpacLogger.java +++ /dev/null @@ -1,157 +0,0 @@ -/** - * $URL: http://gpac.svn.sourceforge.net/svnroot/gpac/trunk/gpac/applications/osmo4_android/src/com/artemis/Osmo4/logs/GpacLogger.java $ - * - * $LastChangedBy: bad_sheep $ - $LastChangedDate: 2011-04-19 09:16:05 -0400 (Tue, 19 Apr 2011) $ - */ -package com.artemis.Osmo4.logs; - -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileOutputStream; -import java.io.PrintStream; -import java.util.Date; -import java.util.SortedSet; -import java.util.TreeSet; -import android.util.Log; -import com.artemis.Osmo4.GpacConfig; -import com.artemis.Osmo4.GpacCallback.GF_Log_Module; - -/** - * This class handles logging. - * - * It will be extended soon to be configurable and enable saving files on disk - * - * @version $Revision: 2950 $ - * - */ -public class GpacLogger { - - /** - * Default Constructor - * - * @param gpacConfig - */ - public GpacLogger(GpacConfig gpacConfig) { - loggedModules.add(GF_Log_Module.GF_LOG_AUDIO); - loggedModules.add(GF_Log_Module.GF_LOG_MEDIA); - loggedModules.add(GF_Log_Module.GF_LOG_MODULE); - loggedModules.add(GF_Log_Module.GF_LOG_CORE); - logger = new File(gpacConfig.getGpacCacheDirectory(), "gpac.log"); //$NON-NLS-1$ - } - - private boolean enableLogOnDisk = false; - - /** - * @return the enableLogOnDisk - */ - public synchronized boolean isEnableLogOnDisk() { - return enableLogOnDisk; - } - - /** - * @param enableLogOnDisk the enableLogOnDisk to set - */ - public synchronized void setEnableLogOnDisk(boolean enableLogOnDisk) { - this.enableLogOnDisk = enableLogOnDisk; - } - - private final File logger; - - /** - * Called when creating logger - */ - public void onCreate() { - if (!enableLogOnDisk) - return; - if (writer == null) { - try { - writer = new PrintStream(new BufferedOutputStream(new FileOutputStream(logger), 128), true, "UTF-8"); //$NON-NLS-1$ - } catch (Exception e) { - Log.e(GpacLogger.class.getSimpleName(), "Failed to create writer", e); //$NON-NLS-1$ - } - } - if (writer != null) - writer.println("New log $Revision: 2950 $ at " + new Date()); //$NON-NLS-1$ - } - - /** - * Called when stopping logger - */ - public void onDestroy() { - if (!enableLogOnDisk) - return; - PrintStream w = this.writer; - writer = null; - if (w != null) { - w.println("Closing log file at " + new Date()); //$NON-NLS-1$ - w.close(); - } - } - - /** - * Logs from C-code - * - * @param level - * @param module - * @param message - */ - public void onLog(int level, int module, String message) { - GF_Log_Module gModule = GF_Log_Module.getModule(module); - if (loggedModules.contains(gModule)) { - if (loggedLevel <= level) - doLog(gModule, level, message); - } else if (defaultLoggedLevel <= level) { - doLog(gModule, level, message); - } - } - - private void doLog(GF_Log_Module module, int level, String message) { - Log.println(level, module.name(), message); - if (enableLogOnDisk) { - PrintStream s = writer; - if (s != null) { - s.println(module.name() + "\t" + message); //$NON-NLS-1$ - s.flush(); - } - } - } - - private final SortedSet loggedModules = new TreeSet(); - - // The log level used by GPAC modules that are part of loggedModules collection - private int loggedLevel = Log.DEBUG; - - // The log level used by GPAC modules not part of loggedModules collection - private int defaultLoggedLevel = Log.INFO; - - /** - * @return the loggedLevel - */ - public synchronized int getLoggedLevel() { - return loggedLevel; - } - - /** - * @param loggedLevel the loggedLevel to set - */ - public synchronized void setLoggedLevel(int loggedLevel) { - this.loggedLevel = loggedLevel; - } - - /** - * @return the defaultLoggedLevel - */ - public synchronized int getDefaultLoggedLevel() { - return defaultLoggedLevel; - } - - /** - * @param defaultLoggedLevel the defaultLoggedLevel to set - */ - public synchronized void setDefaultLoggedLevel(int defaultLoggedLevel) { - this.defaultLoggedLevel = defaultLoggedLevel; - } - - private volatile PrintStream writer; - -}; diff --git a/applications/osmo4_android/src/com/gpac/Osmo4/BitmapView.java b/applications/osmo4_android/src/com/gpac/Osmo4/BitmapView.java new file mode 100644 index 0000000..d851a82 --- /dev/null +++ b/applications/osmo4_android/src/com/gpac/Osmo4/BitmapView.java @@ -0,0 +1,93 @@ +///** +// * Osmo on Android +// * Aug/2010 +// * NGO Van Luyen +// * +// * +// */ +//package com.gpac.Osmo4; +// +//import android.content.Context; +//import android.graphics.Bitmap; +//import android.graphics.Canvas; +//import android.util.Log; +//import android.view.View; +// +///** +// * +// * @version $Revision: 3371 $ +// * +// */ +//@Deprecated +//public class BitmapView extends View { +// +// private Bitmap m_Bitmap = null; +// +// private int m_width = 100, m_height = 100; +// +// private final static String LOG_BITMAP = BitmapView.class.getSimpleName(); +// +// /** +// * Constructor +// * +// * @param context The current view's context +// */ +// public BitmapView(Context context) { +// super(context); +// } +// +// @Override +// protected void onDraw(Canvas canvas) { +// // canvas.drawColor(0xFFCCCCCC); +// m_width = canvas.getWidth(); +// m_height = canvas.getHeight(); +// if (m_Bitmap == null) { +// if (m_width < 1) +// m_width = 100; +// if (m_height < 1) +// m_height = 100; +// m_Bitmap = Bitmap.createBitmap(m_width, m_height, Bitmap.Config.ARGB_8888); +// gpacinit(); +// } +// +// GpacObject.gpacrender(m_Bitmap); +// canvas.drawBitmap(m_Bitmap, 0, 0, null); +// // force a redraw, with a different time-based pattern. +// invalidate(); +// +// } +// +// /** +// * Called to init all GPAC resources +// */ +// private void gpacinit() { +// Log.i(LOG_BITMAP, "Going to gpacinit"); //$NON-NLS-1$ +// if (m_Bitmap != null) { +// Log.e(LOG_BITMAP, "m_Bitmap != null"); //$NON-NLS-1$ +// if (m_width < 1) +// m_width = 100; +// if (m_height < 1) +// m_height = 100; +// GpacObject.gpacinit(m_Bitmap, +// null, +// m_width, +// m_height, +// Osmo4Renderer.GPAC_CFG_DIR, +// Osmo4Renderer.GPAC_MODULES_DIR, +// Osmo4Renderer.GPAC_CACHE_DIR, +// Osmo4Renderer.GPAC_FONT_DIR, +// null); +// // GpacObject.gpacconnect("/data/osmo/bifs-2D-interactivity-stringsensor.mp4"); +// GpacObject.gpacresize(m_width, m_height); +// } +// } +// +// /** +// * Called to free all GPAC resources +// */ +// public void gpacfree() { +// Log.e(LOG_BITMAP, "gpacfree()"); //$NON-NLS-1$ +// GpacObject.gpacdisconnect(); +// GpacObject.gpacfree(); +// } +// } diff --git a/applications/osmo4_android/src/com/gpac/Osmo4/GPACInstance.java b/applications/osmo4_android/src/com/gpac/Osmo4/GPACInstance.java new file mode 100644 index 0000000..863a347 --- /dev/null +++ b/applications/osmo4_android/src/com/gpac/Osmo4/GPACInstance.java @@ -0,0 +1,368 @@ +/** + * $URL: http://gpac.svn.sourceforge.net/svnroot/gpac/trunk/gpac/applications/osmo4_android/src/com/gpac/Osmo4/GPACInstance.java $ + * + * $LastChangedBy: enst_devs $ - $LastChangedDate: 2011-07-05 12:35:26 -0400 (Tue, 05 Jul 2011) $ + */ +package com.gpac.Osmo4; + +import java.io.File; +import java.io.PrintStream; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import android.util.Log; +import android.view.KeyEvent; +import android.view.MotionEvent; + +/** + * @version $Revision: 3371 $ + * + */ +public class GPACInstance implements GPACInstanceInterface { + + private final static String LOG_LIB = "LibrariesLoader"; //$NON-NLS-1$ + + private final Thread uniqueThread; + + private static void listing(StringBuilder sb, File root, int inc) { + StringBuilder increment = new StringBuilder(); + for (int i = 0; i < inc; i++) + increment.append(' '); + String incr = increment.toString(); + for (File f : root.listFiles()) { + sb.append(incr).append(f.getName()); + if (f.isDirectory()) { + sb.append(" [Directory]\n"); //$NON-NLS-1$ + listing(sb, f, inc + 2); + } else { + sb.append(" [").append(f.length() + " bytes]\n"); //$NON-NLS-1$//$NON-NLS-2$ + } + } + } + + /** + * Loads all libraries + * + * @param config + * + * @return a map of exceptions containing the library as key and the exception as value. If map is empty, no error + * + */ + synchronized static Map loadAllLibraries(GpacConfig config) { + if (errors != null) + return errors; + StringBuilder sb = new StringBuilder(); + final String[] toLoad = { "GLESv1_CM", "dl", "log",//$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ + "jpeg", "javaenv", //$NON-NLS-1$ //$NON-NLS-2$ + "mad", "editline", "ft2", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + "js_osmo", "openjpeg", "png", "z", //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ //$NON-NLS-4$ + "ffmpeg", "faad", "gpac", //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ + "stdc++", "gpacWrapper" }; // //$NON-NLS-1$ //$NON-NLS-2$ + HashMap exceptions = new HashMap(); + for (String s : toLoad) { + try { + String msg = "Loading library " + s + "...";//$NON-NLS-1$//$NON-NLS-2$ + sb.append(msg); + Log.i(LOG_LIB, msg); + System.loadLibrary(s); + } catch (UnsatisfiedLinkError e) { + sb.append("Failed to load " + s + ", error=" + e.getLocalizedMessage() + " :: " //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + + e.getClass().getSimpleName() + "\n"); //$NON-NLS-1$ + exceptions.put(s, e); + Log.e(LOG_LIB, "Failed to load library : " + s + " due to link error " + e.getLocalizedMessage(), e); //$NON-NLS-1$ //$NON-NLS-2$ + } catch (SecurityException e) { + exceptions.put(s, e); + Log.e(LOG_LIB, "Failed to load library : " + s + " due to security error " + e.getLocalizedMessage(), e); //$NON-NLS-1$ //$NON-NLS-2$ + } catch (Throwable e) { + exceptions.put(s, e); + Log.e(LOG_LIB, "Failed to load library : " + s + " due to Runtime error " + e.getLocalizedMessage(), e); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + if (!exceptions.isEmpty()) { + try { + PrintStream out = new PrintStream(config.getGpacConfigDirectory() + "debug_libs.txt", "UTF-8"); //$NON-NLS-1$//$NON-NLS-2$ + out.println("$Revision: 3371 $"); //$NON-NLS-1$ + out.println(new Date()); + out.println("\n*** Configuration\n"); //$NON-NLS-1$ + out.println(config.getConfigAsText()); + sb.append("*** Libs listing: "); //$NON-NLS-1$ + sb.append(config.getGpacLibsDirectory()); + sb.append('\n'); + listing(sb, new File(config.getGpacLibsDirectory()), 2); + sb.append("*** Modules listing: "); //$NON-NLS-1$ + sb.append(config.getGpacModulesDirectory()); + sb.append('\n'); + listing(sb, new File(config.getGpacModulesDirectory()), 2); + sb.append("*** Fonts listing: \n"); //$NON-NLS-1$ + sb.append(config.getGpacFontDirectory()); + sb.append('\n'); + listing(sb, new File(config.getGpacFontDirectory()), 2); + sb.append("*** Exceptions:\n"); //$NON-NLS-1$ + for (Map.Entry ex : exceptions.entrySet()) { + sb.append(ex.getKey()).append(": ") //$NON-NLS-1$ + .append(ex.getValue().getLocalizedMessage()) + .append('(') + .append(ex.getValue().getClass()) + .append(")\n"); //$NON-NLS-1$ + } + out.println(sb.toString()); + out.flush(); + out.close(); + } catch (Exception e) { + Log.e(LOG_LIB, "Failed to output debug info to debug file", e); //$NON-NLS-1$ + } + } + errors = Collections.unmodifiableMap(exceptions); + return errors; + } + + private static Map errors = null; + + private boolean hasToBeFreed = true; + + /** + * Constructor + * + * @param callback + * @param width + * @param height + * @param config The configuration to use for GPAC + * @param urlToOpen + * @throws GpacInstanceException + */ + public GPACInstance(GpacCallback callback, int width, int height, GpacConfig config, String urlToOpen) + throws GpacInstanceException { + StringBuilder sb = new StringBuilder(); + Map errors = loadAllLibraries(config); + if (!errors.isEmpty()) { + sb.append("Exceptions while loading libraries:"); //$NON-NLS-1$ + for (Map.Entry x : errors.entrySet()) { + sb.append('\n') + .append(x.getKey()) + .append('[') + .append(x.getValue().getClass().getSimpleName()) + .append("]: ") //$NON-NLS-1$ + .append(x.getValue().getLocalizedMessage()); + } + Log.e(LOG_LIB, sb.toString()); + } + try { + handle = createInstance(callback, + width, + height, + config.getGpacConfigDirectory(), + config.getGpacModulesDirectory(), + config.getGpacCacheDirectory(), + config.getGpacFontDirectory(), + urlToOpen); + } catch (Throwable e) { + throw new GpacInstanceException("Error while creating instance\n" + sb.toString()); //$NON-NLS-1$ + } + if (handle == 0) { + throw new GpacInstanceException("Error while creating instance, no handle created!\n" + sb.toString()); //$NON-NLS-1$ + } + synchronized (this) { + hasToBeFreed = true; + } + uniqueThread = Thread.currentThread(); + } + + /** + * This one handles the pointer to the real C object + */ + private final long handle; + + /** + * @return the handle + */ + public synchronized long getHandle() { + return handle; + } + + private void checkCurrentThread() throws RuntimeException { + if (Thread.currentThread() != uniqueThread) + throw new RuntimeException("Method called outside allowed Thread scope !"); //$NON-NLS-1$ + } + + @Override + public void disconnect() { + checkCurrentThread(); + gpacdisconnect(); + } + + @Override + public void connect(String url) { + Log.i(LOG_LIB, "connect(" + url + ")"); //$NON-NLS-1$ //$NON-NLS-2$ + checkCurrentThread(); + gpacconnect(url); + } + + /** + * Call this method when a key has been pressed + * + * @param keyCode + * @param event + * @param pressed true if key is pressed, false if key is released + * @param unicode + */ + public void eventKey(int keyCode, KeyEvent event, boolean pressed, int unicode) { + checkCurrentThread(); + gpaceventkeypress(keyCode, event.getScanCode(), pressed ? 1 : 0, event.getFlags(), unicode); + } + + /** + * Renders the current frame + */ + public void render() { + checkCurrentThread(); + gpacrender(); + } + + /** + * Resizes the object to new dimensions + * + * @param width + * @param height + */ + public void resize(int width, int height) { + Log.i(LOG_LIB, "Resizing to " + width + "x" + height); //$NON-NLS-1$ //$NON-NLS-2$ + gpacresize(width, height); + } + + /** + * Call this when a motion event occurs + * + * @param event + */ + public void motionEvent(MotionEvent event) { + checkCurrentThread(); + final float x = event.getX(); + final float y = event.getY(); + switch (event.getAction()) { + // not in 1.6 case MotionEvent.ACTION_POINTER_1_DOWN: + case MotionEvent.ACTION_DOWN: + gpaceventmousemove(x, y); + gpaceventmousedown(x, y); + break; + // not in 1.6 case MotionEvent.ACTION_POINTER_1_UP: + case MotionEvent.ACTION_UP: + gpaceventmouseup(x, y); + break; + case MotionEvent.ACTION_MOVE: + gpaceventmousemove(x, y); + } + } + + @Override + public void finalize() throws Throwable { + // Not sure how to do this..., destroy is supposed to be called already + // destroy(); + super.finalize(); + } + + /** + * All Native functions, those functions are binded using the handle + */ + + /** + * Opens an URL + * + * @param url The URL to open + */ + private native void gpacconnect(String url); + + /** + * Used to create the GPAC instance + * + * @param callback + * @param width + * @param height + * @param cfg_dir + * @param modules_dir + * @param cache_dir + * @param font_dir + * @return + */ + private native long createInstance(GpacCallback callback, int width, int height, String cfg_dir, + String modules_dir, String cache_dir, String font_dir, String url_to_open); + + /** + * Disconnects the currently loaded URL + */ + private native void gpacdisconnect(); + + /** + * Renders + * + * @param handle + */ + private native void gpacrender(); + + /** + * Resizes the current view + * + * @param width The new width to set + * @param height The new height to set + */ + private native void gpacresize(int width, int height); + + /** + * Free all GPAC resources + */ + private native void gpacfree(); + + /** + * To call when a key has been pressed + * + * @param keycode + * @param rawkeycode + * @param up + * @param flag + */ + private native void gpaceventkeypress(int keycode, int rawkeycode, int up, int flag, int unicode); + + /** + * To call when a mouse is down + * + * @param x Position in pixels + * @param y Position in pixels + */ + private native void gpaceventmousedown(float x, float y); + + /** + * To call when a mouse is up (released) + * + * @param x Position in pixels + * @param y Position in pixels + */ + private native void gpaceventmouseup(float x, float y); + + /** + * To call when a mouse is moving + * + * @param x Position in pixels + * @param y Position in pixels + */ + private native void gpaceventmousemove(float x, float y); + + @Override + public void destroy() { + boolean freeIt; + synchronized (this) { + freeIt = hasToBeFreed; + hasToBeFreed = false; + } + if (freeIt) { + disconnect(); + gpacfree(); + } + } + + /** + * @see com.gpac.Osmo4.GPACInstanceInterface#setGpacPreference(String, String, String) + */ + @Override + public native void setGpacPreference(String category, String name, String value); +} diff --git a/applications/osmo4_android/src/com/gpac/Osmo4/GPACInstanceInterface.java b/applications/osmo4_android/src/com/gpac/Osmo4/GPACInstanceInterface.java new file mode 100644 index 0000000..fa11124 --- /dev/null +++ b/applications/osmo4_android/src/com/gpac/Osmo4/GPACInstanceInterface.java @@ -0,0 +1,64 @@ +/** + * $URL: http://gpac.svn.sourceforge.net/svnroot/gpac/trunk/gpac/applications/osmo4_android/src/com/gpac/Osmo4/GPACInstanceInterface.java $ + * + * $LastChangedBy: enst_devs $ - $LastChangedDate: 2011-07-05 12:35:26 -0400 (Tue, 05 Jul 2011) $ + */ +package com.gpac.Osmo4; + +/** + * @copyright RTL Group 2008 + * @author RTL Group DTIT software development team (last changed by $LastChangedBy: enst_devs $) + * @version $Revision: 3371 $ + * + */ +public interface GPACInstanceInterface { + + /** + * @version $Revision: 3371 $ + * + */ + public static class GpacInstanceException extends Exception { + + /** + * + */ + private static final long serialVersionUID = 3207851655866335152L; + + /** + * Constructor + * + * @param msg + */ + public GpacInstanceException(String msg) { + super(msg); + } + + }; + + /** + * Call this method to disconnect + */ + public void disconnect(); + + /** + * Call this method to connect to a given URL + * + * @param url The URL to connect to + */ + public void connect(String url); + + /** + * Destroys the current instance, you won't be able to use it anymore... + */ + public void destroy(); + + /** + * Set a GPAC preference to given value + * + * @param category + * @param name The name of preference as defined in GPAC.cfg + * @param value The value to set, if null, value will be deleted + */ + public void setGpacPreference(String category, String name, String value); + +} diff --git a/applications/osmo4_android/src/com/gpac/Osmo4/GpacCallback.java b/applications/osmo4_android/src/com/gpac/Osmo4/GpacCallback.java new file mode 100644 index 0000000..1aa07d0 --- /dev/null +++ b/applications/osmo4_android/src/com/gpac/Osmo4/GpacCallback.java @@ -0,0 +1,286 @@ +/** + * $URL: http://gpac.svn.sourceforge.net/svnroot/gpac/trunk/gpac/applications/osmo4_android/src/com/gpac/Osmo4/GpacCallback.java $ + * + * $LastChangedBy: enst_devs $ - $LastChangedDate: 2011-07-05 12:35:26 -0400 (Tue, 05 Jul 2011) $ + */ +package com.gpac.Osmo4; + +/** + * Interface to implement by Java Objects to listen for callbacks from GPAC native code + * + * @version $Revision: 3371 $ + * + */ +public interface GpacCallback { + + /** + * GPAC Error codes + * + * @version $Revision: 3371 $ + * + */ + public enum GF_Err { + + /** Message from any scripting engine used in the presentation (ECMAScript, MPEG-J, ...) (Info). */ + GF_SCRIPT_INFO(3), + /** + * Indicates an data frame has several AU packed (not MPEG-4 compliant). This is used by decoders to force + * multiple decoding of the same data frame (Info). + */ + GF_PACKED_FRAMES(2), + /** Indicates the end of a stream or of a file (Info). */ + GF_EOS(1), + /* + * ! \n\n + */ + /** Operation success (no error). */ + GF_OK(0), + /** \n */ + /** One of the input parameter is not correct or cannot be used in the current operating mode of the framework. */ + GF_BAD_PARAM(-1), + /** Memory allocation failure. */ + GF_OUT_OF_MEM(-2), + /** Input/Output failure (disk access, system call failures) */ + GF_IO_ERR(-3), + /** The desired feature or operation is not supported by the framework */ + GF_NOT_SUPPORTED(-4), + /** Input data has been corrupted */ + GF_CORRUPTED_DATA(-5), + /** A modification was attempted on a scene node which could not be found */ + GF_SG_UNKNOWN_NODE(-6), + /** The PROTO node interface does not match the nodes using it */ + GF_SG_INVALID_PROTO(-7), + /** An error occured in the scripting engine */ + GF_SCRIPT_ERROR(-8), + /** + * Buffer is too small to contain decoded data. Decoders shall use this error whenever they need to resize their + * output memory buffers + */ + GF_BUFFER_TOO_SMALL(-9), + /** Bitstream is not compliant to the specfication it refers to */ + GF_NON_COMPLIANT_BITSTREAM(-10), + /** No decoders could be found to handle the desired media type */ + GF_CODEC_NOT_FOUND(-11), + /** The URL is not properly formatted or cannot be found */ + GF_URL_ERROR(-12), + /** An service error has occured at the local side */ + GF_SERVICE_ERROR(-13), + /** A service error has occured at the remote (server) side */ + GF_REMOTE_SERVICE_ERROR(-14), + /** The desired stream could not be found in the service */ + GF_STREAM_NOT_FOUND(-15), + /** The IsoMedia file is not a valid one */ + GF_ISOM_INVALID_FILE(-20), + /** The IsoMedia file is not complete. Either the file is being downloaded, or it has been truncated */ + GF_ISOM_INCOMPLETE_FILE(-21), + /** The media in this IsoMedia track is not valid (usually due to a broken stream description) */ + GF_ISOM_INVALID_MEDIA(-22), + /** The requested operation cannot happen in the current opening mode of the IsoMedia file */ + GF_ISOM_INVALID_MODE(-23), + /** This IsoMedia track refers to media outside the file in an unknown way */ + GF_ISOM_UNKNOWN_DATA_REF(-24), + + /** An invalid MPEG-4 Object Descriptor was found */ + GF_ODF_INVALID_DESCRIPTOR(-30), + /** An MPEG-4 Object Descriptor was found or added to a forbidden descriptor */ + GF_ODF_FORBIDDEN_DESCRIPTOR(-31), + /** An invalid MPEG-4 BIFS command was detected */ + GF_ODF_INVALID_COMMAND(-32), + /** The scene has been encoded using an unknown BIFS version */ + GF_BIFS_UNKNOWN_VERSION(-33), + + /** The remote IP address could not be solved */ + GF_IP_ADDRESS_NOT_FOUND(-40), + /** The connection to the remote peer has failed */ + GF_IP_CONNECTION_FAILURE(-41), + /** The network operation has failed */ + GF_IP_NETWORK_FAILURE(-42), + /** The network connection has been closed */ + GF_IP_CONNECTION_CLOSED(-43), + /** The network operation has failed because no data is available */ + GF_IP_NETWORK_EMPTY(-44), + /** The network operation has been discarded because it would be a blocking one */ + GF_IP_SOCK_WOULD_BLOCK(-45), + /** + * UDP connection did not receive any data at all. Signaled by client services to reconfigure network if + * possible + */ + GF_IP_UDP_TIMEOUT(-46), + + /** Authentication with the remote host has failed */ + GF_AUTHENTICATION_FAILURE(-50), + /** Script not ready for playback */ + GF_SCRIPT_NOT_READY(-51), + + /** + * Unknown GPAC Error code + */ + JAVA_UNKNOWN_ERROR(-100); + + int value; + + GF_Err(int x) { + this.value = x; + }; + + /** + * Get a GPAC Error code from its value + * + * @param status The int status corresponding to the error + * @return A {@link GF_Err} object + */ + public static GF_Err getError(int status) { + for (GF_Err x : values()) { + if (x.value == status) + return x; + } + return JAVA_UNKNOWN_ERROR; + } + } + + /** + * Mapping between GPAC Log Modules and Java symbols + * + * @version $Revision: 3371 $ + * + */ + public enum GF_Log_Module implements Comparable { + /** Log message from the core library (init, threads, network calls, etc) */ + GF_LOG_CORE(1), + /** Log message from a raw media parser (BIFS, LASeR, A/V formats) */ + GF_LOG_CODING(1 << 1), + /** Log message from a bitstream parser (IsoMedia, MPEG-2 TS, OGG, ...) */ + GF_LOG_CONTAINER(1 << 2), + /** Log message from the network/service stack (messages & co) */ + GF_LOG_NETWORK(1 << 3), + /** Log message from the RTP/RTCP stack (TS info) and packet structure & hinting (debug) */ + GF_LOG_RTP(1 << 4), + /** Log message from authoring subsystem (file manip, import/export) */ + GF_LOG_AUTHOR(1 << 5), + /** Log message from the sync layer of the terminal */ + GF_LOG_SYNC(1 << 6), + /** Log message from a codec */ + GF_LOG_CODEC(1 << 7), + /** Log message from any XML parser (context loading, etc) */ + GF_LOG_PARSER(1 << 8), + /** Log message from the terminal/compositor, indicating media object state */ + GF_LOG_MEDIA(1 << 9), + /** Log message from the scene graph/scene manager (handling of nodes and attribute modif, DOM core) */ + GF_LOG_SCENE(1 << 10), + /** Log message from the scripting engine */ + GF_LOG_SCRIPT(1 << 11), + /** Log message from event handling */ + GF_LOG_INTERACT(1 << 12), + /** Log message from compositor */ + GF_LOG_COMPOSE(1 << 13), + /** Log for video object cache */ + GF_LOG_CACHE(1 << 14), + /** Log message from multimedia I/O devices (audio/video input/output, ...) */ + GF_LOG_MMIO(1 << 15), + /** Log for runtime info (times, memory, CPU usage) */ + GF_LOG_RTI(1 << 16), + /** Log for SMIL timing and animation */ + GF_LOG_SMIL(1 << 17), + /** Log for memory tracker */ + GF_LOG_MEMORY(1 << 18), + /** Log for audio compositor */ + GF_LOG_AUDIO(1 << 19), + /** generic Log for modules */ + GF_LOG_MODULE(1 << 20), + /** + * Log for GPAC mutexes and threads (Very verbose at DEBUG) + * + */ + GF_LOG_MUTEX(1 << 21), + /** + * Unknown Log subsystem + */ + GF_LOG_UNKNOWN(1 << 30); + + int value; + + /** + * Private Constructor + */ + private GF_Log_Module(int x) { + this.value = x; + }; + + /** + * Finds a module from its module_code + * + * @param module_code + * @return The Module found (never null) + */ + public static GF_Log_Module getModule(int module_code) { + for (GF_Log_Module x : values()) { + if (x.value == module_code) + return x; + } + return GF_LOG_UNKNOWN; + } + } + + /** + * Display a message + * + * @param message + * @param title + * @param errorCode + */ + public void displayMessage(String message, String title, int errorCode); + + /** + * Called when logging + * + * @param level + * @param module + * @param message + */ + public void onLog(int level, int module, String message); + + /** + * Called when progress is set + * + * @param msg + * @param done + * @param total + */ + public void onProgress(String msg, int done, int total); + + /** + * Called when GPAC is ready + */ + public void onGPACReady(); + + /** + * Called when GPAC initialization fails + * + * @param e + */ + public void onGPACError(Throwable e); + + // /** + // * Returns UserName:Password for given site + // * + // * @param siteURL The URL of site requiring authorization + // * @param userName The User Name (may be null if never set) + // * @param password The password (may be null if never set) + // * @return A String formated as username:password + // */ + // public String onGPACAuthorization(String siteURL, String userName, String password); + + /** + * Set the new caption for the application + * + * @param newCaption The new caption to set for application + */ + public void setCaption(String newCaption); + + /** + * Show the virtual keyboard + * + * @param showKeyboard + */ + public void showKeyboard(boolean showKeyboard); +} diff --git a/applications/osmo4_android/src/com/gpac/Osmo4/GpacConfig.java b/applications/osmo4_android/src/com/gpac/Osmo4/GpacConfig.java new file mode 100644 index 0000000..6ab692a --- /dev/null +++ b/applications/osmo4_android/src/com/gpac/Osmo4/GpacConfig.java @@ -0,0 +1,170 @@ +/** + * $URL: http://gpac.svn.sourceforge.net/svnroot/gpac/trunk/gpac/applications/osmo4_android/src/com/gpac/Osmo4/GpacConfig.java $ + * + * $LastChangedBy: enst_devs $ - $LastChangedDate: 2011-07-05 12:35:26 -0400 (Tue, 05 Jul 2011) $ + */ +package com.gpac.Osmo4; + +import java.io.File; +import android.content.Context; +import android.content.pm.PackageManager.NameNotFoundException; +import android.os.Environment; +import android.util.Log; + +/** + * This class handles all GPAC configuration directories + * + * @author Pierre Souchay (VizionR SAS) (last changed by $LastChangedBy: enst_devs $) + * @version $Revision: 3371 $ + * + */ +public class GpacConfig { + + private final static String LOG_GPAC_CONFIG = GpacConfig.class.getSimpleName(); + + /** + * Default Constructor + * + * @param context + */ + public GpacConfig(Context context) { + File rootCfg = Environment.getExternalStorageDirectory(); + File osmo = new File(rootCfg, "osmo"); //$NON-NLS-1$ + gpacConfigDirectory = osmo.getAbsolutePath() + '/'; + Log.v(LOG_GPAC_CONFIG, "Using directory " + gpacConfigDirectory + " for osmo"); //$NON-NLS-1$ //$NON-NLS-2$ + gpacCacheDirectory = new File(osmo, "cache").getAbsolutePath() + '/'; //$NON-NLS-1$ + Log.v(LOG_GPAC_CONFIG, "Using directory " + gpacCacheDirectory + " for cache"); //$NON-NLS-1$ //$NON-NLS-2$ + //gpacModulesDirectory = (new File(Environment.getDataDirectory() + "/data", "com.gpac.Osmo4")).getAbsolutePath() + '/'; //$NON-NLS-1$ //$NON-NLS-2$ + //Log.v(LOG_GPAC_CONFIG, "Using directory " + gpacModulesDirectory + " for modules"); //$NON-NLS-1$ //$NON-NLS-2$ + String dataDir; + try { + if (context == null || context.getPackageManager() == null) { + dataDir = Environment.getDataDirectory() + "/data/com.gpac.Osmo4/"; //$NON-NLS-1$ + Log.e(LOG_GPAC_CONFIG, "Cannot get context or PackageManager, using default directory=" + dataDir); //$NON-NLS-1$ + } else + dataDir = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0).dataDir; + } catch (NameNotFoundException e) { + Log.e(LOG_GPAC_CONFIG, "This is bad, we cannot find ourself : " + context.getPackageName(), e); //$NON-NLS-1$ + throw new RuntimeException("Cannot find package " + context.getPackageName(), e); //$NON-NLS-1$ + } + gpacLibsDirectory = dataDir + "/lib/"; //$NON-NLS-1$ + Log.v(LOG_GPAC_CONFIG, "Using directory " + gpacLibsDirectory + " for libraries"); //$NON-NLS-1$ //$NON-NLS-2$ + + } + + /** + * Ensures all directories are created + * + * @return The {@link GpacConfig} instance itself + */ + public GpacConfig ensureAllDirectoriesExist() { + for (String s : new String[] { gpacConfigDirectory, gpacCacheDirectory }) { + createDirIfNotExist(s); + } + return this; + } + + private final String gpacConfigDirectory; + + /** + * Default directory for GPAC configuration directory, ends with / + * + * @return the gpacConfigDirectory + */ + public String getGpacConfigDirectory() { + return gpacConfigDirectory; + } + + /** + * Directory of Android containing all fonts + * + * @return the gpacFontDirectory + */ + public String getGpacFontDirectory() { + return gpacFontDirectory; + } + + /** + * Default directory for GPAC modules directory, ends with / + * + * @return the gpacModulesDirectory + */ + public String getGpacModulesDirectory() { + // return gpacModulesDirectory; + return gpacLibsDirectory; + } + + /** + * @return the gpacLibsDirectory + */ + public String getGpacLibsDirectory() { + return gpacLibsDirectory; + } + + /** + * Default directory for cached files + * + * @return the gpacCacheDirectory + */ + public String getGpacCacheDirectory() { + return gpacCacheDirectory; + } + + private final String gpacFontDirectory = "/system/fonts/"; //$NON-NLS-1$ + + // private final String gpacModulesDirectory; + + private final String gpacLibsDirectory; + + private final String gpacCacheDirectory; + + /** + * Creates a given directory if it does not exist + * + * @param path + */ + private static boolean createDirIfNotExist(String path) { + File f = new File(path); + if (!f.exists()) { + if (!f.mkdirs()) { + Log.e(LOG_GPAC_CONFIG, "Failed to create directory " + path); //$NON-NLS-1$ + return false; + } else { + Log.i(LOG_GPAC_CONFIG, "Created directory " + path); //$NON-NLS-1$ + } + } + return true; + } + + /** + * Get the GPAC.cfg file + * + * @return the file + */ + public File getGpacConfigFile() { + return new File(getGpacConfigDirectory(), "GPAC.cfg"); //$NON-NLS-1$ + } + + /** + * Get the GPAC.cfg file + * + * @return the file + */ + public File getGpacLastRevFile() { + return new File(getGpacCacheDirectory(), "lastRev.txt"); //$NON-NLS-1$ + } + + /** + * Get the configuration as text + * + * @return a String with newlines representing all the configuration + */ + public String getConfigAsText() { + StringBuilder sb = new StringBuilder(); + sb.append("GpacConfigDirectory=").append(getGpacConfigDirectory()).append('\n'); //$NON-NLS-1$ + sb.append("GpacModulesDirectory=").append(getGpacModulesDirectory()).append('\n'); //$NON-NLS-1$ + sb.append("GpacFontDirectory=").append(getGpacFontDirectory()).append('\n'); //$NON-NLS-1$ + sb.append("GpacCacheDirectory=").append(getGpacCacheDirectory()).append('\n'); //$NON-NLS-1$ + return sb.toString(); + } +} diff --git a/applications/osmo4_android/src/com/gpac/Osmo4/Osmo4.java b/applications/osmo4_android/src/com/gpac/Osmo4/Osmo4.java new file mode 100644 index 0000000..94ba4e3 --- /dev/null +++ b/applications/osmo4_android/src/com/gpac/Osmo4/Osmo4.java @@ -0,0 +1,943 @@ +/** + * Osmo on Android + * Aug/2010 + * NGO Van Luyen + * $Id: Osmo4.java 3371 2011-07-05 16:35:26Z enst_devs $ + * + */ +package com.gpac.Osmo4; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.ProgressDialog; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.DialogInterface.OnClickListener; +import android.content.res.Configuration; +import android.net.Uri; +import android.os.Bundle; +import android.os.PowerManager; +import android.os.PowerManager.WakeLock; +import android.text.InputType; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.Window; +import android.view.WindowManager; +import android.view.inputmethod.InputMethodManager; +import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; +import android.widget.Toast; +import com.gpac.Osmo4.extra.FileChooserActivity; +import com.gpac.Osmo4.logs.GpacLogger; + +/** + * The main Osmo4 activity, used to launch everything + * + * @version $Revision: 3371 $ + * + */ +public class Osmo4 extends Activity implements GpacCallback { + + // private String[] m_modules_list; + + private boolean shouldDeleteGpacConfig = false; + + /** + * @return the shouldDeleteGpacConfig + */ + public synchronized boolean isShouldDeleteGpacConfig() { + return shouldDeleteGpacConfig; + } + + /** + * @param shouldDeleteGpacConfig the shouldDeleteGpacConfig to set + */ + public synchronized void setShouldDeleteGpacConfig(boolean shouldDeleteGpacConfig) { + this.shouldDeleteGpacConfig = shouldDeleteGpacConfig; + } + + private final static String CFG_STARTUP_CATEGORY = "General"; //$NON-NLS-1$ + + private final static String CFG_STARTUP_NAME = "StartupFile"; //$NON-NLS-1$ + + private boolean keyboardIsVisible = false; + + private final static int DEFAULT_BUFFER_SIZE = 8192; + + private GpacConfig gpacConfig; + + /** + * Activity request ID for picking a file from local file system + */ + public final static int PICK_FILE_REQUEST = 1; + + private final static String LOG_OSMO_TAG = "Osmo4"; //$NON-NLS-1$ + + /** + * List of all extensions recognized by Osmo + */ + public final static String OSMO_REGISTERED_FILE_EXTENSIONS = "*.mp4,*.bt,*.xmt,*.xml,*.ts,*.svg,*.mp3,*.m3u8,*.mpg,*.aac,*.m4a,*.jpg,*.png"; //$NON-NLS-1$ + + private PowerManager.WakeLock wl = null; + + private Osmo4GLSurfaceView mGLView; + + private GpacLogger logger; + + private ProgressDialog startupProgress; + + // --------------------------------------- + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + requestWindowFeature(Window.FEATURE_PROGRESS); + requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); + + final String toOpen; + if (Intent.ACTION_VIEW.equals(getIntent().getAction())) { + Uri uri = getIntent().getData(); + if (uri != null) { + synchronized (this) { + toOpen = uri.toString(); + } + } else + toOpen = null; + } else + toOpen = null; + if (gpacConfig == null) { + gpacConfig = new GpacConfig(this); + if (gpacConfig == null) + Log.e(LOG_OSMO_TAG, "Failed to load GPAC config"); //$NON-NLS-1$ + else + gpacConfig.ensureAllDirectoriesExist(); + } + if (logger == null) + logger = new GpacLogger(gpacConfig); + logger.onCreate(); + if (startupProgress == null) { + startupProgress = new ProgressDialog(this); + startupProgress.setCancelable(false); + } + startupProgress.setMessage(getResources().getText(R.string.osmoLoading)); + startupProgress.setTitle(R.string.osmoLoading); + startupProgress.show(); + if (mGLView != null) { + setContentView(mGLView); + if (toOpen != null) + openURLasync(toOpen); + // OK, it means activity has already been started + return; + } + mGLView = new Osmo4GLSurfaceView(Osmo4.this); + service.submit(new Runnable() { + + @Override + public void run() { + // loadAllModules(); + runOnUiThread(new Runnable() { + + @Override + public void run() { + startupProgress.setIndeterminate(true); + startupProgress.setMessage(getResources().getText(R.string.gpacLoading)); + PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); + WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, LOG_OSMO_TAG); + if (wl != null) + wl.acquire(); + synchronized (Osmo4.this) { + Osmo4.this.wl = wl; + } + + Osmo4Renderer renderer = new Osmo4Renderer(Osmo4.this, gpacConfig, toOpen); + mGLView.setRenderer(renderer); + setContentView(mGLView); + } + }); + + } + }); + + } + + // --------------------------------------- + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.main_menu, menu); + return true; + } + + private String getRecentURLsFile() { + return gpacConfig.getGpacConfigDirectory() + "recentURLs.txt"; //$NON-NLS-1$ + } + + private boolean openURL() { + Future res = service.submit(new Callable() { + + @Override + public String[] call() throws Exception { + BufferedReader reader = null; + try { + reader = new BufferedReader(new InputStreamReader(new FileInputStream(getRecentURLsFile()), + DEFAULT_ENCODING), DEFAULT_BUFFER_SIZE); + + String s = null; + Set results = new HashSet(); + while (null != (s = reader.readLine())) { + results.add(s); + } + addAllRecentURLs(results); + return results.toArray(new String[0]); + } finally { + if (reader != null) + reader.close(); + } + } + }); + AlertDialog.Builder builder = new AlertDialog.Builder(this); + final AutoCompleteTextView textView = new AutoCompleteTextView(this); + textView.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI); + + builder.setMessage("Please enter an URL to connect to...") //$NON-NLS-1$ + .setCancelable(true) + .setPositiveButton("Open URL", new DialogInterface.OnClickListener() { //$NON-NLS-1$ + + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + final String newURL = textView.getText().toString(); + openURLasync(newURL); + service.execute(new Runnable() { + + @Override + public void run() { + addAllRecentURLs(Collections.singleton(newURL)); + File tmp = new File(getRecentURLsFile() + ".tmp"); //$NON-NLS-1$ + BufferedWriter w = null; + try { + w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tmp), + DEFAULT_ENCODING), + DEFAULT_BUFFER_SIZE); + Collection toWrite = getAllRecentURLs(); + for (String s : toWrite) { + w.write(s); + w.write("\n"); //$NON-NLS-1$ + } + w.close(); + w = null; + if (tmp.renameTo(new File(getRecentURLsFile()))) + Log.e(LOG_OSMO_TAG, + "Failed to rename " + tmp + " to " + getRecentURLsFile()); //$NON-NLS-1$//$NON-NLS-2$ + + } catch (IOException e) { + Log.e(LOG_OSMO_TAG, "Failed to write recent URLs to " + tmp, e); //$NON-NLS-1$ + try { + if (w != null) + w.close(); + } catch (IOException ex) { + Log.e(LOG_OSMO_TAG, "Failed to close stream " + tmp, ex); //$NON-NLS-1$ + } + } + + } + }); + } + }) + .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { //$NON-NLS-1$ + + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + } + }); + + textView.setText("http://"); //$NON-NLS-1$ + builder.setView(textView); + + builder.show(); + ArrayAdapter adapter; + try { + adapter = new ArrayAdapter(this, + android.R.layout.simple_dropdown_item_1line, + res.get(1, TimeUnit.SECONDS)); + textView.setAdapter(adapter); + } catch (ExecutionException e) { + // Ignored + Log.e(LOG_OSMO_TAG, "Error while parsing recent URLs", e); //$NON-NLS-1$ + } catch (TimeoutException e) { + Log.e(LOG_OSMO_TAG, "It took too long to parse recent URLs", e); //$NON-NLS-1$ + } catch (InterruptedException e) { + Log.e(LOG_OSMO_TAG, "Interrupted while parsing recent URLs", e); //$NON-NLS-1$ + } + + return true; + } + + private final ExecutorService service = Executors.newSingleThreadExecutor(); + + private final Set allRecentURLs = new HashSet(); + + private synchronized void addAllRecentURLs(Collection urlsToAdd) { + allRecentURLs.addAll(urlsToAdd); + } + + private synchronized Collection getAllRecentURLs() { + return new ArrayList(allRecentURLs); + } + + private final static Charset DEFAULT_ENCODING = Charset.forName("UTF-8"); //$NON-NLS-1$ + + /** + * Opens a new activity to select a file + * + * @return true if activity has been selected + */ + private boolean openFileDialog() { + String title = getResources().getString(R.string.pleaseSelectAFile); + Uri uriDefaultDir = Uri.fromFile(new File(gpacConfig.getGpacConfigDirectory())); + Intent intent = new Intent(); + intent.setAction(Intent.ACTION_PICK); + // Files and directories + intent.setDataAndType(uriDefaultDir, "vnd.android.cursor.dir/lysesoft.andexplorer.file"); //$NON-NLS-1$ + // Optional filtering on file extension. + intent.putExtra("browser_filter_extension_whitelist", OSMO_REGISTERED_FILE_EXTENSIONS); //$NON-NLS-1$ + // Title + intent.putExtra("explorer_title", title); //$NON-NLS-1$ + + try { + startActivityForResult(intent, PICK_FILE_REQUEST); + return true; + } catch (ActivityNotFoundException e) { + // OK, lets try with another one... (it includes out bundled one) + intent = new Intent("org.openintents.action.PICK_FILE"); //$NON-NLS-1$ + intent.setData(uriDefaultDir); + intent.putExtra(FileChooserActivity.TITLE_PARAMETER, title); + intent.putExtra("browser_filter_extension_whitelist", OSMO_REGISTERED_FILE_EXTENSIONS); //$NON-NLS-1$ + try { + startActivityForResult(intent, PICK_FILE_REQUEST); + return true; + } catch (ActivityNotFoundException ex) { + // Not found neither... We build our own dialog to display error + // Note that this should happen only if we did not embed out own intent + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setMessage("Impossible to find an Intent to choose a file... Cannot open file !") //$NON-NLS-1$ + .setCancelable(true) + .setPositiveButton("Close", new DialogInterface.OnClickListener() { //$NON-NLS-1$ + + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + } + }); + AlertDialog alert = builder.create(); + alert.show(); + return false; + } + } + } + + // --------------------------------------- + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent intent) { + if (requestCode == PICK_FILE_REQUEST) { + if (resultCode == RESULT_OK) { + Uri uri = intent.getData(); + if (uri != null) { + String url = uri.toString(); + String file = "file://"; //$NON-NLS-1$ + if (url.startsWith(file)) { + url = uri.getPath(); + } + Log.i(LOG_OSMO_TAG, "Requesting opening local file " + url); //$NON-NLS-1$ + openURLasync(url); + } + } + } + } + + private String currentURL; + + private void openURLasync(final String url) { + service.execute(new Runnable() { + + @Override + public void run() { + mGLView.connect(url); + currentURL = url; + runOnUiThread(new Runnable() { + + @Override + public void run() { + setTitle(getResources().getString(R.string.titleWithURL, url)); + } + }); + } + }); + } + + // --------------------------------------- + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + } + + // --------------------------------------- + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle item selection + switch (item.getItemId()) { + case R.id.open_url: + return openURL(); + case R.id.open_file: + // newGame(); + return openFileDialog(); + case R.id.cleanCache: + return cleanCache(); + case R.id.showVirtualKeyboard: + showKeyboard(true); + return true; + case R.id.setAsStartupFile: { + AlertDialog.Builder b = new AlertDialog.Builder(this); + b.setTitle(R.string.setAsStartupFileTitle); + if (currentURL != null) { + b.setMessage(getResources().getString(R.string.setAsStartupFileMessage, currentURL)); + b.setPositiveButton(R.string.setAsStartupFileYes, new OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + mGLView.setGpacPreference(CFG_STARTUP_CATEGORY, CFG_STARTUP_NAME, currentURL); + } + }); + } else { + b.setMessage(getResources().getString(R.string.setAsStartupFileMessageNoURL)); + } + b.setNegativeButton(R.string.setAsStartupFileNo, new OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + b.setNeutralButton(R.string.setAsStartupFileNull, new OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + mGLView.setGpacPreference(CFG_STARTUP_CATEGORY, CFG_STARTUP_NAME, null); + } + }); + b.show(); + return true; + } + case R.id.resetGpacConfig: { + AlertDialog.Builder b = new AlertDialog.Builder(this); + b.setCancelable(true); + b.setTitle(R.string.resetGpacConfig); + b.setMessage(R.string.resetGpacConfigMessage); + b.setNegativeButton(R.string.cancel_button, new OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }); + b.setPositiveButton(R.string.ok_button, new OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + setShouldDeleteGpacConfig(true); + deleteConfigIfNeeded(); + } + }); + b.show(); + return true; + } + case R.id.about: { + Dialog d = new Dialog(this); + d.setTitle(R.string.aboutTitle); + d.setCancelable(true); + d.setContentView(R.layout.about_dialog); + d.show(); + } + return true; + case R.id.quit: + this.finish(); + mGLView.destroy(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + protected boolean cleanCache() { + final CharSequence oldTitle = getTitle(); + runOnUiThread(new Runnable() { + + @Override + public void run() { + startupProgress.setTitle(R.string.cleaningCache); + startupProgress.setMessage(getResources().getString(R.string.cleaningCache, + gpacConfig.getGpacCacheDirectory())); + startupProgress.setProgress(0); + startupProgress.setIndeterminate(false); + startupProgress.show(); + } + }); + service.submit(new Runnable() { + + @Override + public void run() { + File dir = new File(gpacConfig.getGpacCacheDirectory()); + if (!dir.exists() || !dir.canRead() || !dir.canWrite() || !dir.isDirectory()) { + return; + } + File files[] = dir.listFiles(); + int i = 0; + for (File f : files) { + if (f.isFile()) + if (!f.delete()) { + Log.w(LOG_OSMO_TAG, "Failed to delete file " + f); //$NON-NLS-1$ + } else { + Log.v(LOG_OSMO_TAG, f + " has been deleted"); //$NON-NLS-1$ + } + final int percent = (++i) * 100 / files.length; + runOnUiThread(new Runnable() { + + @Override + public void run() { + startupProgress.setProgress(percent); + } + }); + } + runOnUiThread(new Runnable() { + + @Override + public void run() { + startupProgress.setProgress(100); + startupProgress.setTitle(oldTitle); + startupProgress.dismiss(); + } + }); + } + }); + return true; + } + + private void deleteConfigIfNeeded() { + if (isShouldDeleteGpacConfig()) { + Log.i(LOG_OSMO_TAG, "Deleting GPAC config file..."); //$NON-NLS-1$ + File f = gpacConfig.getGpacConfigFile(); + if (f.exists() && !f.delete()) { + Log.e(LOG_OSMO_TAG, "Failed to delete " + f.getAbsolutePath()); //$NON-NLS-1$ + } + f = gpacConfig.getGpacLastRevFile(); + if (f.exists() && !f.delete()) { + Log.e(LOG_OSMO_TAG, "Failed to delete " + f.getAbsolutePath()); //$NON-NLS-1$ + } + } + } + + // --------------------------------------- + @Override + protected void onDestroy() { + deleteConfigIfNeeded(); + service.shutdown(); + logger.onDestroy(); + synchronized (this) { + if (wl != null) + wl.release(); + } + Log.d(LOG_OSMO_TAG, "Disconnecting instance..."); //$NON-NLS-1$ + mGLView.disconnect(); + Log.d(LOG_OSMO_TAG, "Destroying GPAC instance..."); //$NON-NLS-1$ + mGLView.destroy(); + // Deleteing is done two times if GPAC fails to shutdown by crashing... + deleteConfigIfNeeded(); + super.onDestroy(); + } + + // --------------------------------------- + // private void loadAllModules() { + // Log.i(LOG_OSMO_TAG, "Start loading all modules..."); //$NON-NLS-1$ + // long start = System.currentTimeMillis(); + // byte buffer[] = new byte[1024]; + // int[] ids = getAllRawResources(); + // String currentRevision = "$Revision: 3371 $"; //$NON-NLS-1$ + // File revisionFile = gpacConfig.getGpacLastRevFile(); + // boolean fastStartup = false; + // // We check if we already copied all the modules once without error... + // if (revisionFile.exists() && revisionFile.canRead()) { + // BufferedReader r = null; + // try { + // r = new BufferedReader(new InputStreamReader(new FileInputStream(revisionFile), DEFAULT_ENCODING), + // DEFAULT_BUFFER_SIZE); + // String rev = r.readLine(); + // if (currentRevision.equals(rev)) { + // fastStartup = true; + // } + // } catch (IOException ignored) { + // } finally { + // // Exception or not, always close the stream... + // if (r != null) + // try { + // r.close(); + // } catch (IOException ignored) { + // } + // } + // } + // boolean noErrors = true; + // final StringBuilder errorsMsg = new StringBuilder(); + // for (int i = 0; i < ids.length; i++) { + // OutputStream fos = null; + // InputStream ins = null; + // String fn = gpacConfig.getGpacModulesDirectory() + m_modules_list[i] + ".so"; //$NON-NLS-1$ + // File finalFile = new File(fn); + // // If file has already been copied, not need to do it again + // if (fastStartup && finalFile.exists() && finalFile.canRead()) { + // Log.i(LOG_OSMO_TAG, "Skipping " + finalFile); //$NON-NLS-1$ + // continue; + // } + // try { + // final String msg = getResources().getString(R.string.copying_native_libs, + // finalFile.getName(), + // finalFile.getParent()); + // runOnUiThread(new Runnable() { + // + // @Override + // public void run() { + // startupProgress.setIndeterminate(false); + // startupProgress.setMessage(msg); + // } + // }); + // Log.i(LOG_OSMO_TAG, "Copying resource " + ids[i] + " to " //$NON-NLS-1$//$NON-NLS-2$ + // + finalFile.getAbsolutePath()); + // File tmpFile = new File(fn + ".tmp"); //$NON-NLS-1$ + // int read; + // ins = new BufferedInputStream(getResources().openRawResource(ids[i]), DEFAULT_BUFFER_SIZE); + // fos = new BufferedOutputStream(new FileOutputStream(tmpFile), DEFAULT_BUFFER_SIZE); + // while (0 < (read = ins.read(buffer))) { + // fos.write(buffer, 0, read); + // } + // ins.close(); + // ins = null; + // fos.close(); + // fos = null; + // if (!tmpFile.renameTo(finalFile)) { + // if (finalFile.exists() && finalFile.delete() && !tmpFile.renameTo(finalFile)) + // Log.e(LOG_OSMO_TAG, "Failed to rename " + tmpFile.getAbsolutePath() + " to " //$NON-NLS-1$//$NON-NLS-2$ + // + finalFile.getAbsolutePath()); + // } + // final int percent = i * 10000 / ids.length; + // runOnUiThread(new Runnable() { + // + // @Override + // public void run() { + // startupProgress.setProgress(percent); + // } + // }); + // } catch (IOException e) { + // noErrors = false; + // String msg = "IOException for resource : " + ids[i]; //$NON-NLS-1$ + // errorsMsg.append(msg).append('\n').append(finalFile.getAbsolutePath()).append('\n'); + // errorsMsg.append(e.getLocalizedMessage()); + // Log.e(LOG_OSMO_TAG, msg, e); + // } finally { + // if (ins != null) { + // try { + // ins.close(); + // } catch (IOException e) { + // Log.e(LOG_OSMO_TAG, "Error while closing read stream", e); //$NON-NLS-1$ + // } + // } + // if (fos != null) { + // try { + // fos.close(); + // } catch (IOException e) { + // Log.e(LOG_OSMO_TAG, "Error while closing write stream", e); //$NON-NLS-1$ + // } + // } + // } + // } + // // If no error during copy, fast startup will be enabled for next time + // if (noErrors && !fastStartup) { + // BufferedWriter w = null; + // try { + // w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(revisionFile), DEFAULT_ENCODING), + // DEFAULT_BUFFER_SIZE); + // w.write(currentRevision); + // w.write('\n'); + // // We add the date as second line to ease debug in case of problem + // w.write(String.valueOf(new Date())); + // } catch (IOException ignored) { + // } finally { + // if (w != null) + // try { + // w.close(); + // } catch (IOException ignored) { + // } + // } + // } else { + // if (!noErrors) { + // setShouldDeleteGpacConfig(true); + // displayMessage(errorsMsg.toString(), "Errors while copying modules !", GF_Err.GF_IO_ERR.value); //$NON-NLS-1$ + // } + // } + // Log.i(LOG_OSMO_TAG, "Done loading all modules, took " + (System.currentTimeMillis() - start) + "ms."); //$NON-NLS-1$ //$NON-NLS-2$ + // startupProgress.setProgress(100); + // startupProgress.setIndeterminate(true); + // runOnUiThread(new Runnable() { + // + // @Override + // public void run() { + // setTitle(LOG_OSMO_TAG); + // } + // }); + // } + + // private int[] getAllRawResources() throws RuntimeException { + // R.raw r = new R.raw(); + // + // java.lang.reflect.Field fields[] = R.raw.class.getDeclaredFields(); + // final int ids[] = new int[fields.length]; + // m_modules_list = new String[fields.length]; + // + // try { + // for (int i = 0; i < fields.length; i++) { + // java.lang.reflect.Field f = fields[i]; + // ids[i] = f.getInt(r); + // m_modules_list[i] = f.getName(); + // Log.i(LOG_OSMO_TAG, "R.raw." + f.getName() + " = 0x" + Integer.toHexString(ids[i])); //$NON-NLS-1$ //$NON-NLS-2$ + // } + // } catch (IllegalArgumentException e) { + // throw new RuntimeException(e); + // } catch (IllegalAccessException e) { + // throw new RuntimeException(e); + // } + // + // return ids; + // } + + // --------------------------------------- + + private String lastDisplayedMessage; + + private void displayPopup(CharSequence message, CharSequence title) { + final String fullMsg = getResources().getString(R.string.displayPopupFormat, title, message); + synchronized (this) { + if (fullMsg.equals(lastDisplayedMessage)) + return; + lastDisplayedMessage = fullMsg; + } + runOnUiThread(new Runnable() { + + @Override + public void run() { + Toast toast = Toast.makeText(Osmo4.this, fullMsg, Toast.LENGTH_SHORT); + toast.show(); + } + }); + + } + + /** + * @see com.gpac.Osmo4.GpacCallback#displayMessage(String, String, int) + */ + @Override + public void displayMessage(final String message, final String title, final int status) { + if (status == GF_Err.GF_OK.value) + displayPopup(message, title); + else { + runOnUiThread(new Runnable() { + + @Override + public void run() { + StringBuilder sb = new StringBuilder(); + sb.append(GF_Err.getError(status)); + sb.append(' '); + sb.append(title); + AlertDialog.Builder builder = new AlertDialog.Builder(Osmo4.this); + builder.setTitle(sb.toString()); + sb.append('\n'); + sb.append(message); + builder.setMessage(sb.toString()); + builder.setCancelable(true); + builder.setPositiveButton(R.string.ok_button, new OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.cancel(); + } + }); + try { + builder.create().show(); + } catch (WindowManager.BadTokenException e) { + // May happen when we close the window and there are still somes messages + Log.e(LOG_OSMO_TAG, "Failed to display Message " + sb.toString(), e); //$NON-NLS-1$ + } + } + }); + } + } + + /** + * @see com.gpac.Osmo4.GpacCallback#onLog(int, int, String) + */ + @Override + public void onLog(int level, int module, String message) { + logger.onLog(level, module, message); + } + + /** + * @see com.gpac.Osmo4.GpacCallback#onProgress(java.lang.String, int, int) + */ + @Override + public void onProgress(final String msg, final int done, final int total) { + if (Log.isLoggable(LOG_OSMO_TAG, Log.DEBUG)) + Log.d(LOG_OSMO_TAG, "Setting progress to " + done + "/" + total + ", message=" + msg); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + runOnUiThread(new Runnable() { + + @Override + public void run() { + // GPAC sometimes return total = 0 + if (total < 1) { + setProgressBarIndeterminate(true); + } else { + int progress = done * 10000 / (total < 1 ? 1 : total); + if (progress > 9900) + progress = 10000; + setProgressBarIndeterminate(false); + setProgress(progress); + } + } + }); + } + + /** + * @see com.gpac.Osmo4.GpacCallback#onGPACReady() + */ + @Override + public void onGPACReady() { + startupProgress.dismiss(); + Log.i(LOG_OSMO_TAG, "GPAC is ready"); //$NON-NLS-1$ + } + + /** + * @see com.gpac.Osmo4.GpacCallback#onGPACError(java.lang.Throwable) + */ + @Override + public void onGPACError(final Throwable e) { + startupProgress.dismiss(); + Log.e(LOG_OSMO_TAG, "GPAC Error", e); //$NON-NLS-1$ + runOnUiThread(new Runnable() { + + @Override + public void run() { + // In such case, we force GPAC Configuration file deletion + setShouldDeleteGpacConfig(true); + StringBuilder sb = new StringBuilder(); + sb.append("Failed to init GPAC due to "); //$NON-NLS-1$ + sb.append(e.getClass().getSimpleName()); + AlertDialog.Builder builder = new AlertDialog.Builder(Osmo4.this); + builder.setTitle(sb.toString()); + sb.append('\n'); + sb.append("Description: "); //$NON-NLS-1$ + sb.append(e.getLocalizedMessage()); + sb.append('\n'); + sb.append("Revision: $Revision: 3371 $"); //$NON-NLS-1$ + sb.append("\nConfiguration information :\n") //$NON-NLS-1$ + .append(gpacConfig.getConfigAsText()); + builder.setMessage(sb.toString()); + builder.setCancelable(true); + builder.setPositiveButton(R.string.ok_button, new OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.cancel(); + } + }); + builder.create().show(); + } + }); + } + + @Override + protected void onPause() { + super.onPause(); + if (mGLView != null) + mGLView.onPause(); + } + + @Override + protected void onResume() { + super.onResume(); + if (mGLView != null) + mGLView.onResume(); + } + + /** + * @see com.gpac.Osmo4.GpacCallback#setCaption(java.lang.String) + */ + @Override + public void setCaption(final String newCaption) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + setTitle(newCaption); + } + }); + } + + /** + * @see android.app.Activity#onStop() + */ + @Override + protected void onStop() { + Log.i(LOG_OSMO_TAG, "onStop called on activity"); //$NON-NLS-1$ + super.onStop(); + } + + /** + * @see com.gpac.Osmo4.GpacCallback#showKeyboard(boolean) + */ + @Override + public void showKeyboard(boolean showKeyboard) { + if (keyboardIsVisible == showKeyboard == true) + return; + InputMethodManager mgr = ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE)); + this.keyboardIsVisible = showKeyboard; + if (showKeyboard) + mgr.showSoftInput(mGLView, 0); + else + mgr.hideSoftInputFromInputMethod(mGLView.getWindowToken(), 0); + + } +} diff --git a/applications/osmo4_android/src/com/gpac/Osmo4/Osmo4GLSurfaceView.java b/applications/osmo4_android/src/com/gpac/Osmo4/Osmo4GLSurfaceView.java new file mode 100644 index 0000000..005d83b --- /dev/null +++ b/applications/osmo4_android/src/com/gpac/Osmo4/Osmo4GLSurfaceView.java @@ -0,0 +1,204 @@ +package com.gpac.Osmo4; + +import android.content.Context; +import android.opengl.GLSurfaceView; +import android.util.Log; +import android.view.KeyEvent; +import android.view.MotionEvent; + +/** + * The view represented the blitted contents by libgpac + * + * @version $Revision: 3371 $ + * + */ +public class Osmo4GLSurfaceView extends GLSurfaceView implements GPACInstanceInterface { + + private final static String LOG_GL_SURFACE = Osmo4GLSurfaceView.class.getSimpleName(); + + /** + * Constructor + * + * @param context + */ + public Osmo4GLSurfaceView(Context context) { + super(context); + setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS); + setFocusable(true); + setFocusableInTouchMode(true); + } + + private Osmo4Renderer gpacRenderer; + + /** + * Set the renderer + * + * @param renderer + */ + public void setRenderer(Osmo4Renderer renderer) { + synchronized (this) { + this.gpacRenderer = renderer; + } + super.setRenderer(renderer); + setRenderMode(RENDERMODE_CONTINUOUSLY); + } + + private synchronized Osmo4Renderer getGpacRenderer() { + return gpacRenderer; + } + + private GPACInstance getInstance() { + Osmo4Renderer r = getGpacRenderer(); + if (r == null) + return null; + return r.getInstance(); + } + + // ------------------------------------ + @Override + public boolean onTouchEvent(final MotionEvent event) { + queueEvent(new Runnable() { + + @Override + public void run() { + GPACInstance instance = getInstance(); + if (instance != null) + instance.motionEvent(event); + } + }); + return true; + } + + /** + * Should we handle this key in GPAC ? + * + * @param keyCode + * @param event + * @return + */ + private static boolean handleInGPAC(int keyCode, KeyEvent event) { + if (event.isSystem()) + return false; + switch (keyCode) { + case KeyEvent.KEYCODE_MEDIA_STOP: + case KeyEvent.KEYCODE_MENU: + case KeyEvent.KEYCODE_BACK: + return false; + default: + return true; + } + } + + @Override + public boolean onKeyDown(final int keyCode, final KeyEvent event) { + if (handleInGPAC(keyCode, event)) { + Log.d(LOG_GL_SURFACE, "onKeyDown = " + keyCode); //$NON-NLS-1$ + queueEvent(new Runnable() { + + @Override + public void run() { + GPACInstance instance = getInstance(); + if (instance != null) + instance.eventKey(keyCode, event, true, event.getUnicodeChar()); + } + }); + return true; + } + return false; + } + + // ------------------------------------ + @Override + public boolean onKeyUp(final int keyCode, final KeyEvent event) { + if (handleInGPAC(keyCode, event)) { + Log.d(LOG_GL_SURFACE, "onKeyUp =" + keyCode); //$NON-NLS-1$ + queueEvent(new Runnable() { + + @Override + public void run() { + GPACInstance instance = getInstance(); + if (instance != null) + instance.eventKey(keyCode, event, false, event.getUnicodeChar()); + } + }); + return true; + } + return false; + } + + @Override + public void onResume() { + if (getInstance() != null) + super.onResume(); + } + + @Override + public void onPause() { + if (getInstance() != null) + super.onPause(); + } + + /** + * @see com.gpac.Osmo4.GPACInstanceInterface#connect(java.lang.String) + */ + @Override + public void connect(final String url) { + queueEvent(new Runnable() { + + @Override + public void run() { + GPACInstance instance = getInstance(); + if (instance != null) + instance.connect(url); + } + }); + } + + /** + * @see com.gpac.Osmo4.GPACInstanceInterface#disconnect() + */ + @Override + public void disconnect() { + queueEvent(new Runnable() { + + @Override + public void run() { + GPACInstance instance = getInstance(); + if (instance != null) + instance.disconnect(); + } + }); + } + + /** + * @see com.gpac.Osmo4.GPACInstanceInterface#destroy() + */ + @Override + public void destroy() { + queueEvent(new Runnable() { + + @Override + public void run() { + GPACInstance instance = getInstance(); + if (instance != null) + instance.destroy(); + } + }); + } + + /** + * @see com.gpac.Osmo4.GPACInstanceInterface#setGpacPreference(String, String, String) + */ + @Override + public void setGpacPreference(final String category, final String name, final String value) { + queueEvent(new Runnable() { + + @Override + public void run() { + GPACInstance instance = getInstance(); + if (instance != null) + instance.setGpacPreference(category, name, value); + } + }); + } +} diff --git a/applications/osmo4_android/src/com/gpac/Osmo4/Osmo4Renderer.java b/applications/osmo4_android/src/com/gpac/Osmo4/Osmo4Renderer.java new file mode 100644 index 0000000..9938457 --- /dev/null +++ b/applications/osmo4_android/src/com/gpac/Osmo4/Osmo4Renderer.java @@ -0,0 +1,97 @@ +package com.gpac.Osmo4; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; +import android.opengl.GLSurfaceView; +import android.util.Log; + +/** + * The renderer + * + * @version $Revision: 3371 $ + * + */ +public class Osmo4Renderer implements GLSurfaceView.Renderer { + + private final GpacConfig gpacConfig; + + private final static String LOG_RENDERER = Osmo4Renderer.class.getSimpleName(); + + @Override + public void onSurfaceCreated(GL10 gl, EGLConfig config) { + if (instance == null) { + try { + Log.i(LOG_RENDERER, "Creating instance from thread " + Thread.currentThread()); //$NON-NLS-1$ + instance = new GPACInstance(callback, 320, 430, gpacConfig, urlToLoad); + } catch (com.gpac.Osmo4.GPACInstanceInterface.GpacInstanceException e) { + Log.e(LOG_RENDERER, "Failed to create new GPAC instance !"); //$NON-NLS-1$ + instance = null; + callback.onGPACError(e); + return; + } + if (callback != null) + callback.onGPACReady(); + } + } + + private GPACInstance instance = null; + + private final String urlToLoad; + + /** + * @return the urlToLoad + */ + public synchronized String getUrlToLoad() { + return urlToLoad; + } + + /** + * Constructor + * + * @param callback + * @param gpacConfig + * @param urlToLoad The URL to load at startup, can be null + */ + public Osmo4Renderer(GpacCallback callback, GpacConfig gpacConfig, String urlToLoad) { + this.callback = callback; + this.urlToLoad = urlToLoad; + this.gpacConfig = gpacConfig; + } + + private final GpacCallback callback; + + @Override + public void onSurfaceChanged(GL10 gl, int w, int h) { + // gl.glViewport(0, 0, w, h); + if (instance != null) { + Log.i(LOG_RENDERER, "Surface changed from thread " + Thread.currentThread()); //$NON-NLS-1$ + instance.resize(w, h); + } + } + + private int frames; + + private long startFrame = System.currentTimeMillis(); + + @Override + public void onDrawFrame(GL10 gl) { + if (instance != null) { + frames++; + if (frames % 1000 == 0) { + long now = System.currentTimeMillis(); + Log.i(LOG_RENDERER, "Frames Per Second = " + ((now - startFrame) / 1000) + " fps"); //$NON-NLS-1$//$NON-NLS-2$ + this.startFrame = now; + } + instance.render(); + } + } + + /** + * Get the current GPAC Instance + * + * @return the instance + */ + synchronized GPACInstance getInstance() { + return instance; + } +} diff --git a/applications/osmo4_android/src/com/gpac/Osmo4/extra/FileArrayAdapter.java b/applications/osmo4_android/src/com/gpac/Osmo4/extra/FileArrayAdapter.java new file mode 100644 index 0000000..4d421e9 --- /dev/null +++ b/applications/osmo4_android/src/com/gpac/Osmo4/extra/FileArrayAdapter.java @@ -0,0 +1,76 @@ +/** + * $URL: http://gpac.svn.sourceforge.net/svnroot/gpac/trunk/gpac/applications/osmo4_android/src/com/gpac/Osmo4/extra/FileArrayAdapter.java $ + * + * $LastChangedBy: enst_devs $ - $LastChangedDate: 2011-07-05 12:35:26 -0400 (Tue, 05 Jul 2011) $ + */ +package com.gpac.Osmo4.extra; + +import java.io.File; +import java.util.List; +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.TextView; +import com.gpac.Osmo4.R; + +/** + * Class that contains the list of file for given directory + * + * @version $Revision: 3371 $ + * + */ +public class FileArrayAdapter extends ArrayAdapter { + + private final Context context; + + private final int id; + + private final List items; + + /** + * Constructor + * + * @param context + * @param textViewResourceId + * @param objects + */ + public FileArrayAdapter(Context context, int textViewResourceId, List objects) { + super(context, textViewResourceId, objects); + this.context = context; + id = textViewResourceId; + items = objects; + } + + @Override + public FileEntry getItem(int i) { + return items.get(i); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View v = convertView; + if (v == null) { + LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + v = vi.inflate(id, null); + } + final FileEntry o = items.get(position); + if (o != null) { + TextView t1 = (TextView) v.findViewById(R.id.TextView01); + TextView t2 = (TextView) v.findViewById(R.id.TextView02); + + if (t1 != null) + t1.setText(o.getName()); + if (t2 != null) { + File f = o.getFile(); + if (f.isDirectory()) + t2.setText(context.getString(R.string.directory)); + else + t2.setText(context.getString(R.string.fileSize, f.length())); + } + } + return v; + } + +} diff --git a/applications/osmo4_android/src/com/gpac/Osmo4/extra/FileChooserActivity.java b/applications/osmo4_android/src/com/gpac/Osmo4/extra/FileChooserActivity.java new file mode 100644 index 0000000..bae7171 --- /dev/null +++ b/applications/osmo4_android/src/com/gpac/Osmo4/extra/FileChooserActivity.java @@ -0,0 +1,97 @@ +/** + * $URL: http://gpac.svn.sourceforge.net/svnroot/gpac/trunk/gpac/applications/osmo4_android/src/com/gpac/Osmo4/extra/FileChooserActivity.java $ + * + * $LastChangedBy: enst_devs $ - $LastChangedDate: 2011-07-05 12:35:26 -0400 (Tue, 05 Jul 2011) $ + */ +package com.gpac.Osmo4.extra; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import android.app.ListActivity; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.view.View; +import android.widget.ListView; +import com.gpac.Osmo4.R; + +/** + * @version $Revision: 3371 $ + * + */ +public class FileChooserActivity extends ListActivity { + + private File currentDir; + + private FileArrayAdapter adapter; + + /** + * The parameter name to use to search for title + */ + public final static String TITLE_PARAMETER = "org.openintents.extra.TITLE"; //$NON-NLS-1$ + + private String customTitle; + + private void updateTitle(File currentPath) { + setTitle(getResources().getString(R.string.selectFileTitlePattern, customTitle, currentPath.getAbsolutePath())); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Intent intent = getIntent(); + currentDir = new File("/"); //$NON-NLS-1$ + this.customTitle = getResources().getString(R.string.selectFileDefaultTitle); + if (intent != null) { + if (intent.getData() != null) { + File f = new File(intent.getData().getPath()); + if (f.exists() && f.isDirectory() && f.canRead()) + currentDir = f; + } + String title = intent.getExtras().getString(TITLE_PARAMETER); + if (title != null) + this.customTitle = title; + } + fillList(currentDir); + } + + private void fillList(File f) { + File[] dirs = f.listFiles(); + updateTitle(f); + List dir = new ArrayList(); + List fls = new ArrayList(); + if (dirs != null) { + for (File ff : dirs) { + dir.add(new FileEntry(ff.getAbsoluteFile())); + } + Collections.sort(dir); + Collections.sort(fls); + dir.addAll(fls); + } + if (f.getParentFile() != null) + dir.add(0, new FileEntry(f.getParentFile(), getResources().getString(R.string.parentDirectory))); + adapter = new FileArrayAdapter(this, R.layout.file_view, dir); + this.setListAdapter(adapter); + } + + @Override + protected void onListItemClick(ListView l, View v, int position, long id) { + super.onListItemClick(l, v, position, id); + FileEntry o = adapter.getItem(position); + if (o.getFile().isDirectory()) { + fillList(o.getFile()); + } else { + onFileClick(o); + } + } + + private void onFileClick(FileEntry o) { + Intent data = new Intent(); + data.setData(Uri.fromFile(o.getFile())); + setResult(RESULT_OK, data); + finish(); + } + +} diff --git a/applications/osmo4_android/src/com/gpac/Osmo4/extra/FileEntry.java b/applications/osmo4_android/src/com/gpac/Osmo4/extra/FileEntry.java new file mode 100644 index 0000000..ca0b2c1 --- /dev/null +++ b/applications/osmo4_android/src/com/gpac/Osmo4/extra/FileEntry.java @@ -0,0 +1,61 @@ +/** + * $URL: http://gpac.svn.sourceforge.net/svnroot/gpac/trunk/gpac/applications/osmo4_android/src/com/gpac/Osmo4/extra/FileEntry.java $ + * + * $LastChangedBy: enst_devs $ - $LastChangedDate: 2011-07-05 12:35:26 -0400 (Tue, 05 Jul 2011) $ + */ +package com.gpac.Osmo4.extra; + +import java.io.File; + +/** + * @version $Revision: 3371 $ + * + */ +public class FileEntry implements Comparable { + + private final File file; + + private final String name; + + /** + * Constructor + * + * @param f + */ + public FileEntry(File f) { + this.file = f; + this.name = f.getName(); + } + + /** + * Constructor + * + * @param f + * @param name The name to use + */ + public FileEntry(File f, String name) { + this.file = f.getAbsoluteFile(); + this.name = name; + } + + /** + * Get the name of option + * + * @return The name of option + */ + public String getName() { + return name; + } + + @Override + public int compareTo(FileEntry o) { + return getName().toLowerCase().compareTo(o.getName()); + } + + /** + * @return the file + */ + public File getFile() { + return file; + } +} \ No newline at end of file diff --git a/applications/osmo4_android/src/com/gpac/Osmo4/logs/GpacLogger.java b/applications/osmo4_android/src/com/gpac/Osmo4/logs/GpacLogger.java new file mode 100644 index 0000000..d879b80 --- /dev/null +++ b/applications/osmo4_android/src/com/gpac/Osmo4/logs/GpacLogger.java @@ -0,0 +1,157 @@ +/** + * $URL: http://gpac.svn.sourceforge.net/svnroot/gpac/trunk/gpac/applications/osmo4_android/src/com/gpac/Osmo4/logs/GpacLogger.java $ + * + * $LastChangedBy: enst_devs $ - $LastChangedDate: 2011-07-05 12:35:26 -0400 (Tue, 05 Jul 2011) $ + */ +package com.gpac.Osmo4.logs; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.util.Date; +import java.util.SortedSet; +import java.util.TreeSet; +import android.util.Log; +import com.gpac.Osmo4.GpacConfig; +import com.gpac.Osmo4.GpacCallback.GF_Log_Module; + +/** + * This class handles logging. + * + * It will be extended soon to be configurable and enable saving files on disk + * + * @version $Revision: 3371 $ + * + */ +public class GpacLogger { + + /** + * Default Constructor + * + * @param gpacConfig + */ + public GpacLogger(GpacConfig gpacConfig) { + loggedModules.add(GF_Log_Module.GF_LOG_AUDIO); + loggedModules.add(GF_Log_Module.GF_LOG_MEDIA); + loggedModules.add(GF_Log_Module.GF_LOG_MODULE); + loggedModules.add(GF_Log_Module.GF_LOG_CORE); + logger = new File(gpacConfig.getGpacCacheDirectory(), "gpac.log"); //$NON-NLS-1$ + } + + private boolean enableLogOnDisk = false; + + /** + * @return the enableLogOnDisk + */ + public synchronized boolean isEnableLogOnDisk() { + return enableLogOnDisk; + } + + /** + * @param enableLogOnDisk the enableLogOnDisk to set + */ + public synchronized void setEnableLogOnDisk(boolean enableLogOnDisk) { + this.enableLogOnDisk = enableLogOnDisk; + } + + private final File logger; + + /** + * Called when creating logger + */ + public void onCreate() { + if (!enableLogOnDisk) + return; + if (writer == null) { + try { + writer = new PrintStream(new BufferedOutputStream(new FileOutputStream(logger), 128), true, "UTF-8"); //$NON-NLS-1$ + } catch (Exception e) { + Log.e(GpacLogger.class.getSimpleName(), "Failed to create writer", e); //$NON-NLS-1$ + } + } + if (writer != null) + writer.println("New log $Revision: 3371 $ at " + new Date()); //$NON-NLS-1$ + } + + /** + * Called when stopping logger + */ + public void onDestroy() { + if (!enableLogOnDisk) + return; + PrintStream w = this.writer; + writer = null; + if (w != null) { + w.println("Closing log file at " + new Date()); //$NON-NLS-1$ + w.close(); + } + } + + /** + * Logs from C-code + * + * @param level + * @param module + * @param message + */ + public void onLog(int level, int module, String message) { + GF_Log_Module gModule = GF_Log_Module.getModule(module); + if (loggedModules.contains(gModule)) { + if (loggedLevel <= level) + doLog(gModule, level, message); + } else if (defaultLoggedLevel <= level) { + doLog(gModule, level, message); + } + } + + private void doLog(GF_Log_Module module, int level, String message) { + Log.println(level, module.name(), message); + if (enableLogOnDisk) { + PrintStream s = writer; + if (s != null) { + s.println(module.name() + "\t" + message); //$NON-NLS-1$ + s.flush(); + } + } + } + + private final SortedSet loggedModules = new TreeSet(); + + // The log level used by GPAC modules that are part of loggedModules collection + private int loggedLevel = Log.DEBUG; + + // The log level used by GPAC modules not part of loggedModules collection + private int defaultLoggedLevel = Log.INFO; + + /** + * @return the loggedLevel + */ + public synchronized int getLoggedLevel() { + return loggedLevel; + } + + /** + * @param loggedLevel the loggedLevel to set + */ + public synchronized void setLoggedLevel(int loggedLevel) { + this.loggedLevel = loggedLevel; + } + + /** + * @return the defaultLoggedLevel + */ + public synchronized int getDefaultLoggedLevel() { + return defaultLoggedLevel; + } + + /** + * @param defaultLoggedLevel the defaultLoggedLevel to set + */ + public synchronized void setDefaultLoggedLevel(int defaultLoggedLevel) { + this.defaultLoggedLevel = defaultLoggedLevel; + } + + private volatile PrintStream writer; + +}; diff --git a/applications/osmo4_ios/Resources/icon.png b/applications/osmo4_ios/Resources/icon.png new file mode 100644 index 0000000..13f1dee Binary files /dev/null and b/applications/osmo4_ios/Resources/icon.png differ diff --git a/applications/osmo4_ios/Resources/osmo.icns b/applications/osmo4_ios/Resources/osmo.icns new file mode 100644 index 0000000..da7226f Binary files /dev/null and b/applications/osmo4_ios/Resources/osmo.icns differ diff --git a/applications/osmo4_ios/main.c b/applications/osmo4_ios/main.c index b6e1492..75955cd 100644 --- a/applications/osmo4_ios/main.c +++ b/applications/osmo4_ios/main.c @@ -73,7 +73,7 @@ int (*AVI_write_frame)(avi_t *AVI, char *data, long bytes, int keyframe); void (*gf_cfg_del)(GF_Config *iniFile); Bool (*gf_term_get_channel_net_info)(GF_Terminal *term, GF_ObjectManager *odm, u32 *d_enum, u32 *chid, NetStatCommand *netcom, GF_Err *ret_code); void (*gf_term_process_shortcut)(GF_Terminal *term, GF_Event *ev); -GF_Config *(*gf_cfg_new)(const char *filePath, const char *fileName); +GF_Config *(*gf_cfg_init)(const char *fileName, Bool *is_new); Bool (*gf_term_get_download_info)(GF_Terminal *term, GF_ObjectManager *odm, u32 *d_enum, const char **server, const char **path, u32 *bytes_done, u32 *total_bytes, u32 *bytes_per_sec); u32 (*gf_sys_clock)(); GF_ObjectManager *(*gf_term_get_object)(GF_Terminal *term, GF_ObjectManager *scene_od, u32 index); @@ -318,131 +318,6 @@ void PrintHelp() ); } -GF_Config *create_default_config(char *file_path, char *file_name) -{ - GF_Config *cfg; - char szPath[GF_MAX_PATH]; - -#ifdef WIN32 - FILE *f; - Bool write_access = 0; - - /*following code is highly inspired by Osmo4*/ - /*do we have the write privileges on this dir ? if not, use user local data directory*/ - strcpy(szPath, file_path); - strcat(szPath, "GPAC.cfg"); - f = gf_f64_open(szPath, "wb"); - if (f != NULL) { - fclose(f); - write_access = 1; - } else { - write_access = 0; - } - strcpy(szPath, file_path); - - /*get GPAC.cfg path*/ - if (!write_access) { - char szPath2[GF_MAX_PATH]; - SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, file_path); - if (file_path[strlen((char *) file_path)-1] != '\\') strcat(file_path, "\\"); - strcat(file_path, "GPAC\\"); - /*create GPAC dir*/ - _mkdir(file_path); - strcpy(szPath2, file_path); - strcat(szPath2, "GPAC.cfg"); - f = gf_f64_open(szPath2, "wb"); - assert(f); - if (!f) return NULL; - fclose(f); - } -#else - FILE *f; - sprintf(szPath, "%s%c%s", file_path, GF_PATH_SEPARATOR, file_name); - f = gf_f64_open(szPath, "wt"); - fprintf(stdout, "create %s: %s\n", szPath, (f==NULL) ? "Error" : "OK"); - if (!f) return NULL; - fclose(f); -#endif - - cfg = gf_cfg_new(file_path, file_name); - if (!cfg) return NULL; - -#ifdef GPAC_MODULES_PATH - fprintf(stdout, "Using module directory %s \n", GPAC_MODULES_PATH); - strcpy(szPath, GPAC_MODULES_PATH); -#elif defined(WIN32) - //szPath still contains the executable directory -#else -#if 0 - fprintf(stdout, "Please enter full path to GPAC modules directory:\n"); - scanf("%s", szPath); -#endif - strcpy(szPath, "/Applications/osmo4ios.app/"); -#endif - gf_cfg_set_key(cfg, "General", "ModulesDirectory", szPath); - gf_cfg_set_key(cfg, "Audio", "ForceConfig", "yes"); - gf_cfg_set_key(cfg, "Audio", "NumBuffers", "2"); - gf_cfg_set_key(cfg, "Audio", "TotalDuration", "120"); - gf_cfg_set_key(cfg, "Audio", "DisableNotification", "no"); - gf_cfg_set_key(cfg, "FontEngine", "FontReader", "ft_font"); - -#ifdef WIN32 - GetWindowsDirectory((char*)szPath, MAX_PATH); - if (szPath[strlen((char*)szPath)-1] != '\\') strcat((char*)szPath, "\\"); - strcat((char *)szPath, "Fonts"); -#elif defined(__DARWIN__) || defined(__APPLE__) - fprintf(stdout, "Please enter full path to a TrueType font directory (.ttf, .ttc) - enter to default:\n"); - //scanf("%s", szPath); -#else - strcpy(szPath, "/usr/share/fonts/truetype/"); -#endif - strcpy(szPath, "/System/Library/Fonts/Cache"), /*iOS*/ - fprintf(stdout, "Using default font directory %s\n", szPath); - gf_cfg_set_key(cfg, "FontEngine", "FontDirectory", szPath); - -#ifdef WIN32 -/* fprintf(stdout, "Please enter full path to a cache directory for HTTP downloads:\n"); - scanf("%s", szPath); -*/ - GetWindowsDirectory((char*)szPath, MAX_PATH); - if (szPath[strlen((char*)szPath)-1] != '\\') strcat((char*)szPath, "\\"); - strcat((char *)szPath, "Temp"); - - gf_cfg_set_key(cfg, "General", "CacheDirectory", szPath); - fprintf(stdout, "Using default cache directory %s\n", szPath); -#else - fprintf(stdout, "Using /tmp as a cache directory for HTTP downloads:\n"); - gf_cfg_set_key(cfg, "General", "CacheDirectory", "/tmp"); -#endif - - gf_cfg_set_key(cfg, "Downloader", "CleanCache", "yes"); - gf_cfg_set_key(cfg, "Compositor", "AntiAlias", "All"); - gf_cfg_set_key(cfg, "Compositor", "FrameRate", "30"); - /*use power-of-2 emulation*/ - gf_cfg_set_key(cfg, "Compositor", "EmulatePOW2", "yes"); -#ifdef WIN32 - gf_cfg_set_key(cfg, "Compositor", "ScalableZoom", "yes"); - gf_cfg_set_key(cfg, "Video", "DriverName", "DirectX Video Output"); -#elif defined(__DARWIN__) - gf_cfg_set_key(cfg, "Video", "DriverName", "SDL Video Output"); - /*SDL not so fast with scalable zoom*/ - gf_cfg_set_key(cfg, "Compositor", "ScalableZoom", "no"); -#else - gf_cfg_set_key(cfg, "Video", "DriverName", "X11 Video Output"); - /*x11 only supports scalable zoom*/ - gf_cfg_set_key(cfg, "Compositor", "ScalableZoom", "yes"); - gf_cfg_set_key(cfg, "Audio", "DriverName", "SDL Audio Output"); -#endif - - gf_cfg_set_key(cfg, "Video", "SwitchResolution", "no"); - gf_cfg_set_key(cfg, "Network", "AutoReconfigUDP", "yes"); - gf_cfg_set_key(cfg, "Network", "UDPTimeout", "10000"); - gf_cfg_set_key(cfg, "Network", "BufferLength", "3000"); - - /*store and reload*/ - gf_cfg_del(cfg); - return gf_cfg_new(file_path, file_name); -} static void PrintTime(u64 time) { @@ -831,64 +706,6 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) return 0; } -GF_Config *loadconfigfile(char *filepath) -{ - GF_Config *cfg = NULL; - char *cfg_dir; - char szPath[GF_MAX_PATH]; - - if (filepath) { - strcpy(szPath, filepath); - cfg_dir = strrchr(szPath, '\\'); - if (!cfg_dir) cfg_dir = strrchr(szPath, '/'); - if (cfg_dir) { - char c = cfg_dir[0]; - cfg_dir[0] = 0; - cfg = gf_cfg_new(cfg_dir, cfg_dir+1); - cfg_dir[0] = c; - if (cfg) goto success; - } else { - cfg = gf_cfg_new(".", filepath); - if (cfg) goto success; - } - } - -#ifdef WIN32 - GetModuleFileNameA(NULL, szPath, GF_MAX_PATH); - cfg_dir = strrchr(szPath, '\\'); - if (cfg_dir) cfg_dir[1] = 0; - - cfg = gf_cfg_new(szPath, "GPAC.cfg"); - if (cfg) goto success; - strcpy(szPath, "."); - cfg = gf_cfg_new(szPath, "GPAC.cfg"); - if (cfg) goto success; - strcpy(szPath, "."); - cfg = gf_cfg_new(szPath, "GPAC.cfg"); - if (cfg) goto success; - - GetModuleFileNameA(NULL, szPath, GF_MAX_PATH); - cfg_dir = strrchr(szPath, '\\'); - if (cfg_dir) cfg_dir[1] = 0; - cfg = create_default_config(szPath, "GPAC.cfg"); -#else - /*linux*/ - cfg_dir = getenv("HOME"); - fprintf(stderr, "WARNING: HOME env var not set - using current directory for config file\n"); - strcpy(szPath, "/Applications/Documents"); - cfg = gf_cfg_new(szPath, ".gpacrc"); - if (cfg) goto success; - fprintf(stderr, "GPAC config file not found in %s - creating new file\n", szPath); - cfg = create_default_config(szPath, ".gpacrc"); -#endif - if (!cfg) { - fprintf(stderr, "cannot create config file in %s directory\n", szPath); - return NULL; - } - success: - fprintf(stderr, "Using config file in %s directory\n", szPath); - return cfg; -} void list_modules(GF_ModuleManager *modules) { @@ -901,6 +718,7 @@ void list_modules(GF_ModuleManager *modules) fprintf(stderr, "\n"); } + void set_navigation() { GF_Err e; @@ -1044,7 +862,7 @@ int main (int argc, char *argv[]) int *libgpac_so = NULL; libgpac_so = dlopen("/Applications/osmo4ios.app/libgpac_dynamic.dylib", RTLD_LAZY); - fprintf(stderr, "dlopen libgpac_so: 0x%p\n", libgpac_so); + fprintf(stderr, "dlopen libgpac_so: %p\n", libgpac_so); fprintf(stderr, "dlsym: %p gf_log_lt\n", gf_log_lt = dlsym(libgpac_so, "gf_log_lt")); fprintf(stderr, "dlsym: %p AVI_close\n", AVI_close = dlsym(libgpac_so, "AVI_close")); fprintf(stderr, "dlsym: %p gf_sleep\n", gf_sleep = dlsym(libgpac_so, "gf_sleep")); @@ -1093,7 +911,7 @@ int main (int argc, char *argv[]) fprintf(stderr, "dlsym: %p gf_cfg_del\n", gf_cfg_del = dlsym(libgpac_so, "gf_cfg_del")); fprintf(stderr, "dlsym: %p gf_term_get_channel_net_info\n", gf_term_get_channel_net_info = dlsym(libgpac_so, "gf_term_get_channel_net_info")); fprintf(stderr, "dlsym: %p gf_term_process_shortcut\n", gf_term_process_shortcut = dlsym(libgpac_so, "gf_term_process_shortcut")); - fprintf(stderr, "dlsym: %p gf_cfg_new\n", gf_cfg_new = dlsym(libgpac_so, "gf_cfg_new")); + fprintf(stderr, "dlsym: %p gf_cfg_init\n", gf_cfg_init = dlsym(libgpac_so, "gf_cfg_init")); fprintf(stderr, "dlsym: %p gf_term_get_download_info\n", gf_term_get_download_info = dlsym(libgpac_so, "gf_term_get_download_info")); fprintf(stderr, "dlsym: %p gf_sys_clock\n", gf_sys_clock = dlsym(libgpac_so, "gf_sys_clock")); fprintf(stderr, "dlsym: %p gf_term_get_object\n", gf_term_get_object = dlsym(libgpac_so, "gf_term_get_object")); @@ -1159,7 +977,7 @@ int main (int argc, char *argv[]) gf_iphone_set_sdl_video_module(SDL_NewVideo); gf_iphone_set_sdl_audio_module(SDL_NewAudio); - cfg_file = loadconfigfile(the_cfg); + cfg_file = gf_cfg_init(the_cfg, NULL); if (!cfg_file) { fprintf(stdout, "Error: Configuration File \"GPAC.cfg\" not found\n"); if (logfile) fclose(logfile); @@ -1167,15 +985,10 @@ int main (int argc, char *argv[]) } { - const char *str; logs_set = 1; - str = gf_cfg_get_key(cfg_file, "General", "LogLevel"); - if (str) - gf_log_set_level(gf_log_parse_level(str)); - str = gf_cfg_get_key(cfg_file, "General", "LogTools"); - if (str) - gf_log_set_tools(gf_log_parse_tools(str)); + gf_log_set_level( gf_log_parse_level( gf_cfg_get_key(cfg_file, "General", "LogLevel") ) ); + gf_log_set_tools( gf_log_parse_tools( gf_cfg_get_key(cfg_file, "General", "LogTools") ) ); } for (i=1; i<(u32) argc; i++) { diff --git a/applications/osmo4_ios/osmo4ios-Info.plist b/applications/osmo4_ios/osmo4ios-Info.plist index af9a1ca..2c7f467 100644 --- a/applications/osmo4_ios/osmo4ios-Info.plist +++ b/applications/osmo4_ios/osmo4ios-Info.plist @@ -7,14 +7,18 @@ CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier - com.yourcompany.${PRODUCT_NAME:identifier} + com.gpac.${PRODUCT_NAME:identifier} CFBundleInfoDictionaryVersion 6.0 + CFBundleName + Osmo4 CFBundlePackageType APPL + CFBundleShortVersionString + 9.9.9 CFBundleSignature - ???? + gpac CFBundleVersion - 1.0 + 9999 diff --git a/applications/osmo4_sym/osmo4_view.cpp b/applications/osmo4_sym/osmo4_view.cpp index e6064b6..eb1c751 100644 --- a/applications/osmo4_sym/osmo4_view.cpp +++ b/applications/osmo4_sym/osmo4_view.cpp @@ -260,7 +260,8 @@ void COsmo4AppView::SetupLogs() fclose(logs); do_log = 1; gf_log_set_level(GF_LOG_DEBUG); - gf_log_set_tools(0xFFFFFFFF); + u32 lt = gf_log_parse_tools( gf_cfg_get_key(m_user.config, "General", "LogLevel") ); + gf_log_set_tools(lt ? lt : 0xFFFFFFFF); } } if (!do_log) { @@ -323,65 +324,12 @@ void COsmo4AppView::ConstructL( const TRect& aRect ) m_mx = gf_mx_new("Osmo4"); //load config file - m_user.config = gf_cfg_new(GPAC_CFG_DIR, "GPAC.cfg"); + m_user.config = gf_cfg_init(NULL, &first_launch); if (!m_user.config) { - first_launch = 1; - FILE *ft = fopen(GPAC_CFG_DIR"GPAC.cfg", "wt"); - if (!ft) { - MessageBox("Cannot create GPAC Config file", "Fatal Error"); - User::Leave(KErrGeneral); - } else { - fclose(ft); - } - m_user.config = gf_cfg_new(GPAC_CFG_DIR, "GPAC.cfg"); - if (!m_user.config) { - MessageBox("GPAC Configuration file not found", "Fatal Error"); - User::Leave(KErrGeneral); - } + MessageBox("Cannot create GPAC Config file", "Fatal Error"); + User::Leave(KErrGeneral); } - - SetupLogs(); - gf_set_progress_callback(this, Osmo4_progress_cbk); - - opt = gf_cfg_get_key(m_user.config, "General", "ModulesDirectory"); - if (!opt) first_launch = 2; - if (first_launch) { - FILE *t; - /*hardcode module directory*/ - gf_cfg_set_key(m_user.config, "General", "ModulesDirectory", GPAC_MODULES_DIR); - /*hardcode cache directory*/ - gf_cfg_set_key(m_user.config, "General", "CacheDirectory", GPAC_CFG_DIR"cache"); - gf_cfg_set_key(m_user.config, "Downloader", "CleanCache", "yes"); - /*startup file*/ - t = fopen(GPAC_CFG_DIR"gui/gui.bt", "rt"); - if (t) { - fclose(t); - gf_cfg_set_key(m_user.config, "General", "StartupFile", GPAC_CFG_DIR"gui/gui.bt"); - } else { - t = fopen(GPAC_CFG_DIR"gpac.mp4", "rt"); - if (t) { - fclose(t); - gf_cfg_set_key(m_user.config, "General", "StartupFile", GPAC_CFG_DIR"gpac.mp4"); - } - } - /*setup UDP traffic autodetect*/ - gf_cfg_set_key(m_user.config, "Network", "AutoReconfigUDP", "yes"); - gf_cfg_set_key(m_user.config, "Network", "UDPTimeout", "10000"); - gf_cfg_set_key(m_user.config, "Network", "BufferLength", "3000"); - - gf_cfg_set_key(m_user.config, "Compositor", "TextureTextMode", "Default"); - - - /*save cfg and reload*/ - gf_cfg_del(m_user.config); - m_user.config = gf_cfg_new(GPAC_CFG_DIR, "GPAC.cfg"); - if (!m_user.config) { - MessageBox("Cannot save initial GPAC Config file", "Fatal Error"); - User::Leave(KErrGeneral); - } - - MessageBox("Osmo4", "Thank you for Installing"); } diff --git a/applications/osmo4_w32/Options.cpp b/applications/osmo4_w32/Options.cpp index 2558d81..974bc35 100644 --- a/applications/osmo4_w32/Options.cpp +++ b/applications/osmo4_w32/Options.cpp @@ -12,6 +12,7 @@ #include #include +#include "Options.h" #ifdef _DEBUG #define new DEBUG_NEW @@ -1146,7 +1147,7 @@ void COptHTTP::DoDataExchange(CDataExchange* pDX) DDX_Control(pDX, IDC_HTTP_USE_PROXY, m_useProxy); DDX_Control(pDX, IDC_SAX_DELAY, m_SAXDuration); DDX_Control(pDX, IDC_SAX_PROGRESSIVE, m_Progressive); - DDX_Control(pDX, IDC_RESTART_CACHE, m_RestartFile); + DDX_Control(pDX, IDC_RESTART_CACHE, m_DisableCache); DDX_Control(pDX, IDC_CLEAN_CACHE, m_CleanCache); DDX_Control(pDX, IDC_BROWSE_CACHE, m_CacheDir); //}}AFX_DATA_MAP @@ -1159,6 +1160,7 @@ BEGIN_MESSAGE_MAP(COptHTTP, CDialog) ON_BN_CLICKED(IDC_SAX_PROGRESSIVE, OnSaxProgressive) ON_BN_CLICKED(IDC_HTTP_USE_PROXY, OnUseProxy) //}}AFX_MSG_MAP + ON_BN_CLICKED(IDC_RESTART_CACHE, &COptHTTP::OnBnClickedRestartCache) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// @@ -1208,8 +1210,8 @@ BOOL COptHTTP::OnInitDialog() sOpt = gf_cfg_get_key(gpac->m_user.config, "Downloader", "CleanCache"); m_CleanCache.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); - sOpt = gf_cfg_get_key(gpac->m_user.config, "Downloader", "RestartFiles"); - m_RestartFile.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + sOpt = gf_cfg_get_key(gpac->m_user.config, "Downloader", "DisableCache"); + m_DisableCache.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); sOpt = gf_cfg_get_key(gpac->m_user.config, "SAXLoader", "Progressive"); m_Progressive.SetCheck((sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); @@ -1264,7 +1266,7 @@ void COptHTTP::SaveOptions() Osmo4 *gpac = GetApp(); gf_cfg_set_key(gpac->m_user.config, "Downloader", "CleanCache", m_CleanCache.GetCheck() ? "yes" : "no"); - gf_cfg_set_key(gpac->m_user.config, "Downloader", "RestartFiles", m_RestartFile.GetCheck() ? "yes" : "no"); + gf_cfg_set_key(gpac->m_user.config, "Downloader", "DisableCache", m_DisableCache.GetCheck() ? "yes" : "no"); gf_cfg_set_key(gpac->m_user.config, "SAXLoader", "Progressive", m_Progressive.GetCheck() ? "yes" : "no"); m_SAXDuration.GetWindowText(szCacheDir, MAX_PATH); @@ -1980,3 +1982,8 @@ void COptLogs::SaveOptions() gpac->m_log_tools = flags; gf_log_set_tools(gpac->m_log_tools); } + +void COptHTTP::OnBnClickedRestartCache() +{ + // TODO : ajoutez ici le code de votre gestionnaire de notification de contrôle +} diff --git a/applications/osmo4_w32/Options.h b/applications/osmo4_w32/Options.h index b9e3df8..2e26e73 100644 --- a/applications/osmo4_w32/Options.h +++ b/applications/osmo4_w32/Options.h @@ -215,7 +215,7 @@ public: CButton m_useProxy; CEdit m_SAXDuration; CButton m_Progressive; - CButton m_RestartFile; + CButton m_DisableCache; CButton m_CleanCache; CButton m_CacheDir; //}}AFX_DATA @@ -241,6 +241,8 @@ protected: afx_msg void OnUseProxy(); //}}AFX_MSG DECLARE_MESSAGE_MAP() +public: + afx_msg void OnBnClickedRestartCache(); }; diff --git a/applications/osmo4_w32/Osmo4.cpp b/applications/osmo4_w32/Osmo4.cpp index 544abba..41f434e 100644 --- a/applications/osmo4_w32/Osmo4.cpp +++ b/applications/osmo4_w32/Osmo4.cpp @@ -273,6 +273,14 @@ Bool Osmo4_EventProc(void *priv, GF_Event *evt) case GF_KEY_MEDIAPREVIOUSTRACK: pFrame->m_pPlayList->PlayPrev(); break; + case GF_KEY_H: + if ((evt->key.flags & GF_KEY_MOD_CTRL) && gpac->m_isopen) + gf_term_switch_quality(gpac->m_term, 1); + break; + case GF_KEY_L: + if ((evt->key.flags & GF_KEY_MOD_CTRL) && gpac->m_isopen) + gf_term_switch_quality(gpac->m_term, 0); + break; } break; case GF_EVENT_NAVIGATE: @@ -298,7 +306,6 @@ Bool Osmo4_EventProc(void *priv, GF_Event *evt) UserPassDialog passdlg; return passdlg.GetPassword(evt->auth.site_url, evt->auth.user, evt->auth.password); } - } return 0; } @@ -326,9 +333,6 @@ static void osmo4_do_log(void *cbk, u32 level, u32 tool, const char *fmt, va_lis BOOL Osmo4::InitInstance() { - char config_file[MAX_PATH]; - FILE *ft; - Bool write_access; CCommandLineInfo cmdInfo; m_logs = NULL; @@ -342,29 +346,6 @@ BOOL Osmo4::InitInstance() while (szApplicationPath[strlen((char *) szApplicationPath)-1] != '\\') szApplicationPath[strlen((char *) szApplicationPath)-1] = 0; if (szApplicationPath[strlen((char *) szApplicationPath)-1] != '\\') strcat(szApplicationPath, "\\"); - /*do we have the write privileges on this dir ? if no, use Documents and Settings*/ - strcpy(config_file, szApplicationPath); - strcat(config_file, "test.txt"); - ft = gf_f64_open(config_file, "wb"); - if (ft != NULL) { - fclose(ft); - gf_delete_file(config_file); - write_access = 1; - } else { - write_access = 0; - } - - /*get GPAC.cfg path*/ - if (write_access) { - strcat(szUserPath, szApplicationPath); - } else { - SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, szUserPath); - if (szUserPath[strlen((char *) szUserPath)-1] != '\\') strcat(szUserPath, "\\"); - strcat(szUserPath, "GPAC\\"); - /*create GPAC dir*/ - _mkdir(szUserPath); - } - gf_sys_init(0); /*setup user*/ @@ -372,27 +353,19 @@ BOOL Osmo4::InitInstance() Bool first_launch = 0; /*init config and modules*/ - m_user.config = gf_cfg_new((const char *) szUserPath, "GPAC.cfg"); + m_user.config = gf_cfg_init(NULL, &first_launch); if (!m_user.config) { - first_launch = 1; - /*create blank config file in the exe dir*/ - char config_file[MAX_PATH]; - - strcpy(config_file, szUserPath); - /*create GPAC cache dir*/ - strcat(config_file, "cache"); - _mkdir(config_file); - - strcpy((char *) config_file, (const char *) szUserPath); - strcat((char *) config_file, "GPAC.cfg"); - ft = gf_f64_open((const char *) config_file, "wt"); - fclose(ft); - m_user.config = gf_cfg_new((const char *) szUserPath, "GPAC.cfg"); - if (!m_user.config) { - MessageBox(NULL, "GPAC Configuration file not found", "Fatal Error", MB_OK); - m_pMainWnd->PostMessage(WM_CLOSE); - } + MessageBox(NULL, "GPAC Configuration file not found", "Fatal Error", MB_OK); + m_pMainWnd->PostMessage(WM_CLOSE); } + + char *name = gf_cfg_get_filename(m_user.config); + char *sep = strrchr(name, '\\'); + if (sep) sep[0] = 0; + strcpy(szUserPath, name); + if (sep) sep[0] = '\\'; + gf_free(name); + const char *opt = gf_cfg_get_key(m_user.config, "General", "SingleInstance"); m_SingleInstance = (opt && !stricmp(opt, "yes")) ? 1 : 0; @@ -463,62 +436,21 @@ BOOL Osmo4::InitInstance() const char *str = gf_cfg_get_key(m_user.config, "General", "ModulesDirectory"); m_user.modules = gf_modules_new(str, m_user.config); - if (!m_user.modules) { - const char *sOpt; - /*inital launch*/ - m_user.modules = gf_modules_new(szApplicationPath, m_user.config); - if (m_user.modules) { - FILE *t; - unsigned char str_path[MAX_PATH]; - gf_cfg_set_key(m_user.config, "General", "ModulesDirectory", (const char *) szApplicationPath); - - sOpt = gf_cfg_get_key(m_user.config, "Compositor", "Raster2D"); - if (!sOpt) gf_cfg_set_key(m_user.config, "Compositor", "Raster2D", "GPAC 2D Raster"); - - sOpt = gf_cfg_get_key(m_user.config, "General", "CacheDirectory"); - if (!sOpt) { - sprintf((char *) str_path, "%scache", szUserPath); - gf_cfg_set_key(m_user.config, "General", "CacheDirectory", (const char *) str_path); - } - /*setup UDP traffic autodetect*/ - gf_cfg_set_key(m_user.config, "Network", "AutoReconfigUDP", "yes"); - gf_cfg_set_key(m_user.config, "Network", "UDPTimeout", "10000"); - gf_cfg_set_key(m_user.config, "Network", "BufferLength", "3000"); - - /*first launch, register all files ext*/ - u32 i; - for (i=0; iCanHandleURL(ifce, "test.test"); - gf_modules_close_interface((GF_BaseInterface *)ifce); - } - } - - sprintf((char *) str_path, "%sgui/gui.bt", szApplicationPath); - t = gf_f64_open((char *) str_path, "rt"); - if (!t) { - sprintf((char *) str_path, "%sgpac.mp4", szApplicationPath); - t = gf_f64_open((char *) str_path, "rt"); - } - if (t) { - gf_cfg_set_key(m_user.config, "General", "StartupFile", (const char *) str_path); - fclose(t); + if (!m_user.modules || ! gf_modules_get_count(m_user.modules) ) { + MessageBox(NULL, "No modules available - system cannot work", "Fatal Error", MB_OK); + m_pMainWnd->PostMessage(WM_CLOSE); + } + else if (first_launch) { + /*first launch, register all files ext*/ + u32 i; + for (i=0; iCanHandleURL(ifce, "test.test"); + gf_modules_close_interface((GF_BaseInterface *)ifce); } } - - /*check audio config on windows, force config*/ - sOpt = gf_cfg_get_key(m_user.config, "Audio", "ForceConfig"); - if (!sOpt) { - gf_cfg_set_key(m_user.config, "Audio", "ForceConfig", "yes"); - gf_cfg_set_key(m_user.config, "Audio", "NumBuffers", "2"); - gf_cfg_set_key(m_user.config, "Audio", "TotalDuration", "120"); - } - - /*by default use GDIplus, much faster than freetype on font loading*/ - gf_cfg_set_key(m_user.config, "FontEngine", "FontReader", "gm_soft_raster"); - /*set some shortcuts*/ gf_cfg_set_key(m_user.config, "Shortcuts", "VolumeUp", "ctrl+Up"); gf_cfg_set_key(m_user.config, "Shortcuts", "VolumeDown", "ctrl+Down"); @@ -526,26 +458,6 @@ BOOL Osmo4::InitInstance() gf_cfg_set_key(m_user.config, "Shortcuts", "FastForward", "ctrl+Right"); gf_cfg_set_key(m_user.config, "Shortcuts", "Play", "ctrl+ "); } - if (! gf_modules_get_count(m_user.modules) ) { - MessageBox(NULL, "No modules available - system cannot work", "Fatal Error", MB_OK); - m_pMainWnd->PostMessage(WM_CLOSE); - } - - /*setup font dir*/ - str = gf_cfg_get_key(m_user.config, "FontEngine", "FontDirectory"); - if (!str) { - char szFtPath[MAX_PATH]; - ::GetWindowsDirectory((char*)szFtPath, MAX_PATH); - if (szFtPath[strlen((char*)szFtPath)-1] != '\\') strcat((char*)szFtPath, "\\"); - strcat((char *)szFtPath, "Fonts"); - gf_cfg_set_key(m_user.config, "FontEngine", "FontDirectory", (const char *) szFtPath); - } - - /*check video driver, if none or raw_out use dx_hw by default*/ - str = gf_cfg_get_key(m_user.config, "Video", "DriverName"); - if (!str || !stricmp(str, "raw_out")) { - gf_cfg_set_key(m_user.config, "Video", "DriverName", "DirectX Video Output"); - } /*check log file*/ str = gf_cfg_get_key(m_user.config, "General", "LogFile"); @@ -556,49 +468,13 @@ BOOL Osmo4::InitInstance() else m_logs = NULL; /*set log level*/ - m_log_level = 0; - str = gf_cfg_get_key(m_user.config, "General", "LogLevel"); - if (str) { - if (!stricmp(str, "debug")) m_log_level = GF_LOG_DEBUG; - else if (!stricmp(str, "info")) m_log_level = GF_LOG_INFO; - else if (!stricmp(str, "warning")) m_log_level = GF_LOG_WARNING; - else if (!stricmp(str, "error")) m_log_level = GF_LOG_ERROR; - gf_log_set_level(m_log_level); - } + m_log_level = gf_log_parse_level(gf_cfg_get_key(m_user.config, "General", "LogLevel")); + gf_log_set_level(m_log_level); /*set log tools*/ - m_log_tools = 0; - str = gf_cfg_get_key(m_user.config, "General", "LogTools"); - if (str) { - char *sep; - char *val = (char *) str; - while (val) { - sep = strchr(val, ':'); - if (sep) sep[0] = 0; - if (!stricmp(val, "core")) m_log_tools |= GF_LOG_CODING; - else if (!stricmp(val, "coding")) m_log_tools |= GF_LOG_CODING; - else if (!stricmp(val, "container")) m_log_tools |= GF_LOG_CONTAINER; - else if (!stricmp(val, "network")) m_log_tools |= GF_LOG_NETWORK; - else if (!stricmp(val, "rtp")) m_log_tools |= GF_LOG_RTP; - else if (!stricmp(val, "author")) m_log_tools |= GF_LOG_AUTHOR; - else if (!stricmp(val, "sync")) m_log_tools |= GF_LOG_SYNC; - else if (!stricmp(val, "codec")) m_log_tools |= GF_LOG_CODEC; - else if (!stricmp(val, "parser")) m_log_tools |= GF_LOG_PARSER; - else if (!stricmp(val, "media")) m_log_tools |= GF_LOG_MEDIA; - else if (!stricmp(val, "scene")) m_log_tools |= GF_LOG_SCENE; - else if (!stricmp(val, "script")) m_log_tools |= GF_LOG_SCRIPT; - else if (!stricmp(val, "interact")) m_log_tools |= GF_LOG_INTERACT; - else if (!stricmp(val, "compose")) m_log_tools |= GF_LOG_COMPOSE; - else if (!stricmp(val, "mmio")) m_log_tools |= GF_LOG_MMIO; - else if (!stricmp(val, "none")) m_log_tools = 0; - else if (!stricmp(val, "all")) m_log_tools = 0xFFFFFFFF; - if (!sep) break; - sep[0] = ':'; - val = sep+1; - } - gf_log_set_tools(m_log_tools); - } - + m_log_tools = gf_log_parse_tools(gf_cfg_get_key(m_user.config, "General", "LogTools")); + gf_log_set_tools(m_log_tools); + m_user.opaque = this; m_user.os_window_handler = pFrame->m_pWndView->m_hWnd; m_user.EventProc = Osmo4_EventProc; diff --git a/applications/osmo4_w32/Osmo4.rc b/applications/osmo4_w32/Osmo4.rc index 1c65b6f..2241bfe 100644 --- a/applications/osmo4_w32/Osmo4.rc +++ b/applications/osmo4_w32/Osmo4.rc @@ -1,880 +1,872 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Anglais (États-Unis) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -IDR_MAINFRAME MENU -BEGIN - POPUP "&File" - BEGIN - MENUITEM "&Open File\tCtrl+O", ID_FILEOPEN - MENUITEM "Open &URL\tCtrl+U", ID_OPEN_URL - MENUITEM SEPARATOR - MENUITEM "File Propert&ies\tCtrl+I", ID_FILE_PROP - POPUP "Streaming Cache" - BEGIN - MENUITEM "&Enable", ID_REC_ENABLE - MENUITEM "&Stop and Save", ID_REC_STOP - MENUITEM "&Abort", ID_REC_ABORT - END - MENUITEM SEPARATOR - MENUITEM "Copy", ID_FILE_COPY - MENUITEM "Paste", ID_FILE_PASTE - MENUITEM SEPARATOR - MENUITEM "Exit", ID_FILE_EXIT - END - POPUP "View" - BEGIN - POPUP "Viewpoint" - BEGIN - MENUITEM "", ID_VIEWPORT_EMPTY - END - POPUP "&Navigation" - BEGIN - MENUITEM "Headlight", ID_HEADLIGHT - MENUITEM SEPARATOR - MENUITEM "&None", ID_NAVIGATE_NONE - MENUITEM "&Walk", ID_NAVIGATE_WALK - MENUITEM "&Fly", ID_NAVIGATE_FLY - MENUITEM "&Examine", ID_NAVIGATE_EXAM - MENUITEM "&Pan", ID_NAVIGATE_PAN - MENUITEM "&Slide", ID_NAVIGATE_SLIDE - MENUITEM "&Orbit", ID_NAVIGATE_ORBIT - MENUITEM "&VR", ID_NAVIGATE_VR - MENUITEM "&Game", ID_NAVIGATE_GAME - MENUITEM SEPARATOR - POPUP "Collision" - BEGIN - MENUITEM "Off", ID_COLLIDE_NONE - MENUITEM "Regular", ID_COLLIDE_REG - MENUITEM "Displacement", ID_COLLIDE_DISP - END - MENUITEM "Gravity", ID_GRAVITY - MENUITEM SEPARATOR - MENUITEM "&Reset", ID_NAV_RESET - END - MENUITEM SEPARATOR - MENUITEM "&Fullscreen", ID_VIEW_FULLSCREEN - MENUITEM "Original &Aspect", ID_VIEW_ORIGINAL - POPUP "Aspect &Ratio" - BEGIN - MENUITEM "&Keep Original", ID_AR_KEEP - MENUITEM "&Fill Screen", ID_AR_FILL - MENUITEM "Ratio 4/3", ID_AR_43 - MENUITEM "Ratio 16/9", ID_AR_169 - END - MENUITEM SEPARATOR - MENUITEM "Resource Usage", ID_VIEW_CPU - MENUITEM SEPARATOR - MENUITEM "&Options", IDD_CONFIGURE - END - POPUP "Play" - BEGIN - POPUP "Stream &Selection" - BEGIN - POPUP "Audio" - BEGIN - MENUITEM "", ID_AUDIO_EMPTY - END - POPUP "Video" - BEGIN - MENUITEM "", ID_VIDEO_EMPTY - END - POPUP "Subtitle" - BEGIN - MENUITEM "", ID_SUBS_EMPTY - END - MENUITEM SEPARATOR - MENUITEM "Add Subtitle", ID_ADD_SUBTITLE - END - POPUP "&Chapters" - BEGIN - MENUITEM "", ID_SETCHAP_FIRST - END - MENUITEM SEPARATOR - MENUITEM "Playlist\tCtrl+L", ID_VIEW_PL, CHECKED - MENUITEM "&Loop Playlist", ID_PLAYLIST_LOOP - MENUITEM SEPARATOR - MENUITEM "Play/Pause\tCtrl+P", ID_FILE_PLAY - MENUITEM "Step-by-Step\tCtrl+S", ID_FILE_STEP - MENUITEM "Stop", ID_FILE_STOP - MENUITEM SEPARATOR - MENUITEM "Reload File\tCtrl+R", ID_FILE_RELOAD - MENUITEM SEPARATOR - MENUITEM "Clear History", ID_CLEAR_NAV - MENUITEM "Reload Config", ID_CONFIG_RELOAD - END - POPUP "?" - BEGIN - MENUITEM "Shortcut List", ID_SHORTCUTS - MENUITEM "Navigation Keys", ID_NAV_INFO - MENUITEM SEPARATOR - MENUITEM "&About ...", ID_H_ABOUT - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Accelerator -// - - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_ABOUTBOX DIALOGEX 0, 0, 209, 137 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_CLIENTEDGE -CAPTION "Osmo4 / GPAC version X.X.X" -FONT 8, "MS Sans Serif", 0, 0, 0x1 -BEGIN - ICON IDR_MAINFRAME,IDC_STATIC,8,4,20,20 - CTEXT "Osmo4 Player - GPAC Multimedia Framework",IDC_STATIC,31,10,150,10,SS_NOPREFIX - CTEXT "(c) Jean Le Feuvre 2000-2005 - (c) ENST 2005-200X\nAll Rights Reserved",IDC_STATIC,4,64,201,18 - CTEXT "This program is free software and may be distributed according to the terms of the GNU Lesser General Public License",IDC_STATIC,4,26,200,18 - PUSHBUTTON "http://gpac.sourceforge.net",IDC_GOGPAC,43,47,121,13,BS_FLAT,WS_EX_STATICEDGE - GROUPBOX "With Many Thanks To:",IDC_STATIC,3,82,203,53 - CTEXT "The FreeType Project\nMozilla SpiderMonkey (JavaScript support)\n\nZLIB, the PNG Group, the I.J.G.\nFFMPEG, FAAD, XVID, MAD",IDC_STATIC,9,92,189,41 -END - -IDD_PASSWD DIALOG 0, 0, 134, 71 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Enter user name and password" -FONT 8, "MS Sans Serif" -BEGIN - DEFPUSHBUTTON "OK",IDOK,4,56,50,12 - PUSHBUTTON "Cancel",IDCANCEL,80,56,50,12 - LTEXT "Static__________________________",IDC_TXT_SITE,25,4,105,8 - LTEXT "Login",IDC_STATIC,7,21,18,8 - LTEXT "Password",IDC_STATIC,7,37,32,8 - EDITTEXT IDC_EDIT_USER,47,18,55,14,ES_AUTOHSCROLL - EDITTEXT IDC_EDIT_PASSWORD,47,34,55,14,ES_PASSWORD | ES_AUTOHSCROLL - LTEXT "Site",IDC_STATIC,7,4,13,8 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,1 - PRODUCTVERSION 1,0,0,1 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "FileDescription", "Osmo4-GPAC" - VALUE "FileVersion", "0.4.5" - VALUE "InternalName", "Osmo4" - VALUE "LegalCopyright", "Copyright (C) 2005" - VALUE "OriginalFilename", "Osmo4.EXE" - VALUE "ProductName", "Osmo4-GPAC" - VALUE "ProductVersion", "0.4.5" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_ABOUTBOX, DIALOG - BEGIN - BOTTOMMARGIN, 136 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Toolbar -// - -IDR_MAINTOOLS TOOLBAR 16, 15 -BEGIN - BUTTON ID_FILEOPEN - BUTTON ID_NAV_PREV - BUTTON ID_NAV_NEXT - BUTTON ID_FILE_PLAY - BUTTON ID_FILE_PLAY - BUTTON ID_FILE_STEP - BUTTON ID_FILE_STOP - BUTTON ID_FILE_PROPS - BUTTON IDD_CONFIGURE - BUTTON ID_SWITCH_RENDER - BUTTON ID_SWITCH_RENDER -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Bitmap -// - -IDR_MAINTOOLS BITMAP "res\\maintool.bmp" - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE -BEGIN - IDR_MAINFRAME "Osmo4" -END - -STRINGTABLE -BEGIN - AFX_IDS_APP_TITLE "Osmo4" - AFX_IDS_IDLEMESSAGE "Ready" -END - -STRINGTABLE -BEGIN - ID_FILE_EXIT "Quit the application; prompts to save documents\nExit" - ID_H_ABOUT "Display program information, version number and copyright\nAbout" - ID_PLAYLIST_LOOP "Restarts playlist from begining when playlist is over" - ID_FILEOPEN "Opens local file" - ID_VIEW_ORIGINAL "restore Original Aspect of presentation" -END - -STRINGTABLE -BEGIN - ID_VIEW_STATUS_BAR "Show or hide the status bar\nToggle StatusBar" -END - -STRINGTABLE -BEGIN - AFX_IDS_SCSIZE "Change the window size" - AFX_IDS_SCMOVE "Change the window position" - AFX_IDS_SCMINIMIZE "Reduce the window to an icon" - AFX_IDS_SCMAXIMIZE "Enlarge the window to full size" - AFX_IDS_SCNEXTWINDOW "Switch to the next document window" - AFX_IDS_SCPREVWINDOW "Switch to the previous document window" - AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents" -END - -STRINGTABLE -BEGIN - AFX_IDS_SCRESTORE "Restore the window to normal size" - AFX_IDS_SCTASKLIST "Activate Task List" -END - -STRINGTABLE -BEGIN - ID_FILE_STOP "Stops current presentation" - ID_SWITCH_RENDER "Switch between 2D and 3D renderers" - ID_COLLIDE_NONE "Turns collision detection off" - ID_COLLIDE_REG "Turns collision detection on" - ID_COLLIDE_DISP "Collision with camera displacement" - ID_HEADLIGHT "Turns headlight on/off" -END - -STRINGTABLE -BEGIN - ID_CLEAR_NAV "Clears navigation history" - ID_TIMER " " - ID_FPS " " - ID_VIEW_PL "View navigation history as a playlist" -END - -STRINGTABLE -BEGIN - ID_VIEW_FULLSCREEN "Move to Full Screen mode (Esc to exit)" - ID_AR_KEEP "Keep Aspect Ratio of presentation" - ID_SHORTCUTS "List of available shortcuts" - ID_FILE_PROP "Show presentation properties" - ID_FILE_STEP "Step one frame into presentation" - IDD_CONFIGURE "Configure Player" - ID_VIEW_SCALABLE "Uses vectorial zooming when resizing the window" - ID_OPEN_URL "Open remote presentation" - ID_FILE_RELOAD "Reload current presentation" - ID_FILE_PLAY "Play/Pause presentation" - ID_NAVIGATE_NONE "Disable navigation" -END - -STRINGTABLE -BEGIN - ID_NAVIGATE_WALK "Turn walk navigation on" - ID_AR_FILL "Ignores Aspect Ratio and always fill screen" - ID_AR_43 "Forces Aspect Ratio of 4/3" - ID_AR_169 "Forces Aspect Ratio of 16/9" - ID_NAV_RESET "Restore last viewpoint" -END - -STRINGTABLE -BEGIN - ID_NAVIGATE_VR "QT-VR like navigation" - ID_REC_ENABLE "Enable recording of streaming data" - ID_REC_STOP "Stops recording and save to file" - ID_REC_ABORT "Stops recording and discard data" -END - -STRINGTABLE -BEGIN - ID_FILE_COPY "Copy selected text to clipboard" - ID_FILE_PASTE "Paste clipboard" -END - -#endif // Anglais (États-Unis) resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// Français (France) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA) -#ifdef _WIN32 -LANGUAGE LANG_FRENCH, SUBLANG_FRENCH -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_OPENFILE DIALOG 0, 0, 301, 23 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Select Location" -FONT 8, "MS Sans Serif" -BEGIN - COMBOBOX IDC_COMBOURL,3,5,273,67,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP - DEFPUSHBUTTON "OK",IDC_BUTGO,279,5,19,13 -END - -IDD_OPTIONS DIALOG 0, 0, 174, 106 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Osmo4 Options" -FONT 8, "MS Sans Serif" -BEGIN - PUSHBUTTON "Apply",IDC_SAVEOPT,147,2,26,12 - COMBOBOX IDC_SELECT,42,2,99,173,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Category",IDC_STATIC,7,4,29,8 -END - -IDD_OPT_GEN DIALOG 0, 20, 169, 76 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD -FONT 8, "MS Sans Serif" -BEGIN - CONTROL "Loop At End",IDC_LOOP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,4,55,10 - CONTROL "Look for subtitles",IDC_LOOKFORSUB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,42,69,10 - CONTROL "Disable console messages",IDC_NO_CONSOLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,17,99,10 - CONTROL "View Graph in XMT-A format",IDC_DUMP_XMT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,30,105,10 - CONTROL "Single Instance",IDC_SINGLE_INSTANCE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,54,65,10 -END - -IDD_OPT_RENDER DIALOG 0, 20, 169, 76 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD -FONT 8, "MS Sans Serif" -BEGIN - LTEXT "Rendering Frame Rate",IDC_STATIC,5,4,72,8 - COMBOBOX IDC_BIFS_RATE,81,2,84,55,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Fast Rendering",IDC_FAST_RENDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,49,64,10 - CONTROL "Force Scene Size",IDC_FORCE_SIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,96,49,72,10 - LTEXT "Anti-Aliasing Level",IDC_STATIC,7,20,58,8 - COMBOBOX IDC_AA_LIST,81,17,84,46,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Use 3D Renderer",IDC_USE_RENDER3D,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,63,71,10 - LTEXT "2D Rasterizer",IDC_STATIC,7,35,44,8 - COMBOBOX IDC_GD_LIST,81,33,84,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_DRAW_BOUNDS,109,60,56,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Bounds",IDC_STATIC,82,64,25,8 -END - -IDD_OPT_AUDIO DIALOG 0, 20, 169, 76 -STYLE DS_SETFONT | DS_CONTROL | WS_CHILD | WS_THICKFRAME -FONT 8, "MS Sans Serif" -BEGIN - CONTROL "Spin1",IDC_SPIN_AUDIO,"msctls_updown32",UDS_SETBUDDYINT | UDS_ARROWKEYS,27,15,11,14 - EDITTEXT IDC_EDIT_AUDIO,5,15,19,14,ES_READONLY | ES_NUMBER - CONTROL "Force Audio Config",IDC_FORCE_AUDIO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,3,73,10 - LTEXT "buffers",IDC_STATIC,43,18,23,8 - CONTROL "Spin1",IDC_SPIN_FPS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ARROWKEYS,104,15,11,14 - EDITTEXT IDC_AUDIO_FPS,77,15,24,14,ES_NUMBER - LTEXT "Audio Driver",IDC_STATIC,7,63,40,8 - CONTROL "No Resynchronization",IDC_AUDIO_RESYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,46,82,10 - COMBOBOX IDC_DRIVER_LIST,63,60,103,62,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Disable Notifications",IDC_AUDIO_NOTIFS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,47,79,10 - CONTROL "Disable Multichannel",IDC_AUDIO_MULTICH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,34,81,10 - LTEXT "ms total length",IDC_STATIC,118,18,49,8 -END - -IDD_OPT_VIDEO DIALOG 0, 20, 169, 76 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD -FONT 8, "MS Sans Serif" -BEGIN - LTEXT "Video Driver",IDC_STATIC,6,7,40,8 - COMBOBOX IDC_VIDEO_LIST,55,5,111,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Change video resolution in fullscreen",IDC_SWITCH_RES, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,29,131,10 - CONTROL "Use Hardware Video Memory in 2D mode",IDC_HWMEMORY, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,44,143,10 -END - -IDD_OPT_HTTP DIALOG 0, 20, 169, 76 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD -FONT 8, "MS Sans Serif" -BEGIN - PUSHBUTTON "...",IDC_BROWSE_CACHE,57,4,109,12 - CONTROL "Clean cache at exit",IDC_CLEAN_CACHE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,19,77,10 - CONTROL "Always redownload incomplete cached files",IDC_RESTART_CACHE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,30,153,10 - LTEXT "Cache Directory",IDC_STATIC,5,5,52,8 - CONTROL "XML progressive load",IDC_SAX_PROGRESSIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,42,84,10 - EDITTEXT IDC_SAX_DELAY,142,41,22,12,ES_CENTER | ES_AUTOHSCROLL | ES_NUMBER - LTEXT "TimeSlice (ms)",IDC_STATIC,91,43,46,8 - EDITTEXT IDC_HTTP_PROXY,54,58,111,12,ES_AUTOHSCROLL - CONTROL "Use proxy",IDC_HTTP_USE_PROXY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,59,47,10 -END - -IDD_OPT_FONT DIALOG 0, 20, 169, 76 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD -FONT 8, "MS Sans Serif" -BEGIN - LTEXT "Font Engine",IDC_STATIC,6,11,39,8 - COMBOBOX IDC_FONT_LIST,60,8,105,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "...",IDC_BROWSE_FONT,2,40,164,12 - LTEXT "System Font Directory",IDC_STATIC,46,29,70,8 - COMBOBOX IDC_TEXTURE_MODE,101,58,64,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Text Texturing Mode",IDC_STATIC,7,60,69,8 -END - -IDD_OPT_SYSTEMS DIALOG 0, 20, 169, 76 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD -FONT 8, "MS Sans Serif" -BEGIN - COMBOBOX IDC_LANG,75,4,92,58,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Prefered Language for stream selection",IDC_STATIC,3,3,61,17 - LTEXT "Decoder Threading",IDC_STATIC,4,28,62,8 - COMBOBOX IDC_DEC_THREAD,75,25,92,57,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Always draw late BIFS frames",IDC_BIFSDROP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,43,109,10 - CONTROL "Force Single Timeline",IDC_FORCE_DURATION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,58,83,10 -END - -IDD_OPT_STREAM DIALOG 0, 20, 169, 76 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD -FONT 8, "MS Sans Serif" -BEGIN - LTEXT "Default Port",IDC_STATIC,6,6,40,8 - COMBOBOX IDC_PORT,52,3,113,61,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP - CONTROL "RTP over RTSP",IDC_RTSP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,19,68,10 - CONTROL "use RTP reordering",IDC_REORDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,81,19,76,10 - LTEXT "milliseconds before control timeout",IDC_STATIC,38,34,108,8 - EDITTEXT IDC_TIMEOUT,3,32,30,12,ES_CENTER | ES_AUTOHSCROLL | ES_NUMBER - LTEXT "milliseconds of Media Buffering ",IDC_STATIC,38,48,100,8 - EDITTEXT IDC_BUFFER,3,47,30,12,ES_CENTER | ES_AUTOHSCROLL | ES_NUMBER - EDITTEXT IDC_REBUFFER_LEN,83,60,30,12,ES_CENTER | ES_AUTOHSCROLL | ES_NUMBER - CONTROL "Rebuffer if less than",IDC_REBUFFER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,63,79,10 - LTEXT "milliseconds",IDC_STATIC,117,63,41,8 -END - -IDD_PROPERTIES DIALOGEX 0, 0, 338, 150 -STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Presentation Properties" -FONT 8, "MS Sans Serif", 0, 0, 0x1 -BEGIN - CONTROL "Tree1",IDC_ODTREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | TVS_TRACKSELECT | WS_BORDER | WS_TABSTOP | 0x400,2,2,120,114 - EDITTEXT IDC_ODINFO,123,17,213,130,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_NOHIDESEL | ES_OEMCONVERT | ES_READONLY | WS_VSCROLL | WS_HSCROLL,WS_EX_DLGMODALFRAME | WS_EX_STATICEDGE - PUSHBUTTON "Get World Info",IDC_WORLD,2,118,119,13 - PUSHBUTTON "View Scene Graph",IDC_VIEWSG,2,134,119,13 - CONTROL "Tab1",IDC_VIEWSEL,"SysTabControl32",TCS_BUTTONS,124,2,208,14 -END - -IDD_OPT_DECODER DIALOG 0, 20, 169, 76 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD -FONT 8, "MS Sans Serif" -BEGIN - LTEXT "Prefered Audio Module",-1,46,5,69,8 - COMBOBOX IDC_AUDEC_LIST,26,17,111,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Prefered Video Module",-1,48,40,69,8 - COMBOBOX IDC_VIDEC_LIST,25,52,113,55,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP -END - -IDD_OPT_RENDER2D DIALOG 0, 20, 169, 76 -STYLE DS_SETFONT | DS_MODALFRAME | WS_CHILD -FONT 8, "MS Sans Serif" -BEGIN - CONTROL "Disable YUV Hardware",IDC_YUV,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,54,89,10 - LTEXT "Static",IDC_FORMAT_YUV,97,57,67,8 - CONTROL "Direct Rendering",IDC_DIRECTRENDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,32,72,10 - CONTROL "Scalable Zoom",IDC_ZOOM_SCALABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,10,77,10 -END - -IDD_OPT_RENDER3D DIALOG 0, 20, 169, 76 -STYLE DS_SETFONT | DS_MODALFRAME | WS_CHILD -FONT 8, "MS Sans Serif" -BEGIN - CONTROL "Use OpenGL Outlines",IDC_RASTER_OUTLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,2,84,10 - CONTROL "Emulate power-of-two textures for video",IDC_EMUL_POW2, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,45,140,10 - CONTROL "Polygon Anti-Aliasing",IDC_DISABLE_POLY_AA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,90,2,78,10 - CONTROL "Disable rectangular texture extensions",IDC_DISABLE_TX_RECT, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,55,135,10 - CONTROL "Bitmap node uses direct pixel copy",IDC_BITMAP_USE_PIXEL, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,65,125,10 - LTEXT "Draw Normals",IDC_STATIC,4,17,45,8 - COMBOBOX IDC_DRAW_NORMALS,4,25,48,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Backface Cull",IDC_STATIC,57,17,55,8 - COMBOBOX IDC_BACK_CULL,57,25,47,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Draw Mode",IDC_STATIC,113,17,55,8 - COMBOBOX IDC_DRAW_MODE,111,25,53,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP -END - -IDD_SLIDERS DIALOG 0, 0, 218, 18 -STYLE DS_SETFONT | WS_CHILD -FONT 8, "MS Sans Serif" -BEGIN - CONTROL "Slider1",ID_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,0,3,185,12 - CONTROL "Slider1",ID_AUDIO_VOL,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_BORDER | WS_TABSTOP,187,3,30,13 -END - -IDD_NAVBAR DIALOGEX 0, 0, 279, 15 -STYLE DS_SETFONT | WS_CHILD -FONT 8, "MS Sans Serif", 0, 0, 0x1 -BEGIN - COMBOBOX IDC_ADDRESS,29,1,130,196,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP,WS_EX_ACCEPTFILES - LTEXT "Address",IDC_DUMTXT,1,4,26,8 -END - -IDD_PLAYLIST DIALOGEX 0, 0, 186, 54 -STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME -EXSTYLE WS_EX_TOOLWINDOW -CAPTION "Osmo4 Playlist" -FONT 8, "MS Sans Serif", 0, 0, 0x1 -BEGIN - CONTROL "List4",IDC_FILELIST,"SysListView32",LVS_REPORT | WS_BORDER | WS_TABSTOP,1,0,182,51 -END - -IDD_OPT_MCACHE DIALOG 0, 20, 169, 76 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD -FONT 8, "MS Sans Serif" -BEGIN - PUSHBUTTON "...",IDC_BROWSE_MCACHE,41,2,126,12 - CONTROL "Overwrite existing files",IDC_MCACHE_OVERWRITE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,18,85,10 - CONTROL "Use filename",IDC_MCACHE_USENAME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,31,57,10 - LTEXT "Record To",IDC_STATIC,4,4,35,8 - EDITTEXT IDC_BASEPRES,81,31,82,12,ES_CENTER | ES_AUTOHSCROLL | ES_NUMBER -END - -IDD_OPT_FILETYPES DIALOG 0, 20, 169, 76 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD -FONT 8, "MS Sans Serif" -BEGIN - COMBOBOX IDC_FILELIST,59,6,108,61,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Supported Files",IDC_STATIC,6,8,50,8 - LTEXT "Extension",IDC_FILES_EXT,7,25,154,8 - LTEXT "Mime Type",IDC_FILES_MIMES,7,37,156,8 - CONTROL "Associate with Osmo4",IDC_ASSOCIATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,60,84,10 - LTEXT "Plugin",IDC_FILES_PLUG,8,49,154,8 -END - -IDD_OPT_LOGS DIALOG 0, 20, 169, 76 -STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD -FONT 8, "MS Sans Serif" -BEGIN - LTEXT "Level",IDC_STATIC,6,7,18,8 - COMBOBOX IDC_LOG_LEVEL,30,4,64,74,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "core",IDC_TOOL_CORE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,23,30,10 - CONTROL "coding",IDC_TOOL_CODING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,33,37,10 - CONTROL "container",IDC_TOOL_CONTAINER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,43,45,10 - CONTROL "network",IDC_TOOL_NET,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,53,41,10 - CONTROL "rtp",IDC_TOOL_RTP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,63,24,10 - CONTROL "author",IDC_TOOL_AUTHOR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,48,24,36,10 - CONTROL "sync",IDC_TOOL_SYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,48,34,31,10 - CONTROL "codec",IDC_TOOL_CODEC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,48,44,36,10 - CONTROL "parser",IDC_TOOL_PARSER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,48,54,35,10 - CONTROL "media",IDC_TOOL_MEDIA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,48,64,35,10 - CONTROL "scene",IDC_TOOL_SCENE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,86,24,35,10 - CONTROL "script",IDC_TOOL_SCRIPT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,86,34,33,10 - CONTROL "compose",IDC_TOOL_COMPOSE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,86,44,45,10 - CONTROL "render",IDC_TOOL_RENDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,86,54,36,10 - CONTROL "mmio",IDC_TOOL_MMIO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,86,64,32,10 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_OPT_VIDEO, DIALOG - BEGIN - RIGHTMARGIN, 168 - END - - IDD_OPT_FONT, DIALOG - BEGIN - LEFTMARGIN, 1 - RIGHTMARGIN, 168 - BOTTOMMARGIN, 74 - END - - IDD_OPT_SYSTEMS, DIALOG - BEGIN - RIGHTMARGIN, 167 - TOPMARGIN, 1 - BOTTOMMARGIN, 75 - END - - IDD_OPT_STREAM, DIALOG - BEGIN - LEFTMARGIN, 1 - RIGHTMARGIN, 167 - TOPMARGIN, 1 - END - - IDD_PROPERTIES, DIALOG - BEGIN - RIGHTMARGIN, 335 - TOPMARGIN, 1 - END - - IDD_OPT_DECODER, DIALOG - BEGIN - RIGHTMARGIN, 168 - END - - IDD_OPT_RENDER3D, DIALOG - BEGIN - RIGHTMARGIN, 168 - END - - IDD_NAVBAR, DIALOG - BEGIN - RIGHTMARGIN, 167 - END - - IDD_OPT_FILETYPES, DIALOG - BEGIN - RIGHTMARGIN, 168 - END - - IDD_OPT_LOGS, DIALOG - BEGIN - RIGHTMARGIN, 168 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Toolbar -// - -IDR_PLAYLIST TOOLBAR 16, 15 -BEGIN - BUTTON ID_PL_OPEN - BUTTON ID_PL_SAVE - BUTTON ID_PL_ADD_FILE - BUTTON ID_PL_REM_FILE - BUTTON ID_PL_UP - BUTTON ID_PL_DOWN - BUTTON ID_PL_SORT_FILE -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Bitmap -// - -IDR_PLAYLIST BITMAP "res\\playlist.bmp" - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "#define _AFX_NO_SPLITTER_RESOURCES\r\n" - "#define _AFX_NO_OLE_RESOURCES\r\n" - "#define _AFX_NO_TRACKER_RESOURCES\r\n" - "#define _AFX_NO_PROPERTY_RESOURCES\r\n" - "\r\n" - "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n" - "#ifdef _WIN32\r\n" - "LANGUAGE 9, 1\r\n" - "#pragma code_page(1252)\r\n" - "#endif //_WIN32\r\n" - "#include ""res\\Osmo4.rc2"" // non-Microsoft Visual C++ edited resources\r\n" - "#include ""afxres.rc"" // Standard components\r\n" - "#endif\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDR_MAINFRAME ICON "..\\..\\doc\\osmo4.ico" -IDI_PLAY ICON "res\\play.ico" -IDI_STOP ICON "res\\stop.ico" -IDI_PAUSE ICON "res\\pause.ico" -IDI_MESSAGE ICON "res\\message.ico" -IDI_ERR ICON "res\\error.ico" - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog Info -// - -IDD_OPT_RENDER DLGINIT -BEGIN - IDC_BIFS_RATE, 0x403, 4, 0 -0x2e35, 0x0030, - IDC_BIFS_RATE, 0x403, 4, 0 -0x2e37, 0x0035, - IDC_BIFS_RATE, 0x403, 5, 0 -0x3031, 0x302e, "\000" - IDC_BIFS_RATE, 0x403, 5, 0 -0x3231, 0x352e, "\000" - IDC_BIFS_RATE, 0x403, 5, 0 -0x3531, 0x302e, "\000" - IDC_BIFS_RATE, 0x403, 5, 0 -0x3432, 0x302e, "\000" - IDC_BIFS_RATE, 0x403, 5, 0 -0x3532, 0x302e, "\000" - IDC_BIFS_RATE, 0x403, 5, 0 -0x3033, 0x302e, "\000" - 0 -END - -IDD_OPT_SYSTEMS DLGINIT -BEGIN - IDC_LANG, 0x403, 8, 0 -0x6e45, 0x6c67, 0x7369, 0x0068, - IDC_LANG, 0x403, 7, 0 -0x7246, 0x6e65, 0x6863, "\000" - IDC_LANG, 0x403, 7, 0 -0x6547, 0x6d72, 0x6e61, "\000" - IDC_LANG, 0x403, 8, 0 -0x7449, 0x6c61, 0x6169, 0x006e, - IDC_LANG, 0x403, 8, 0 -0x7053, 0x6e61, 0x7369, 0x0068, - IDC_LANG, 0x403, 9, 0 -0x6843, 0x6e69, 0x6565, 0x6573, "\000" - IDC_LANG, 0x403, 10, 0 -0x614a, 0x6170, 0x656e, 0x7365, 0x0065, - IDC_DEC_THREAD, 0x403, 14, 0 -0x6953, 0x676e, 0x656c, 0x5420, 0x7268, 0x6165, 0x0064, - IDC_DEC_THREAD, 0x403, 13, 0 -0x754d, 0x6c74, 0x2069, 0x6854, 0x6572, 0x6461, "\000" - IDC_DEC_THREAD, 0x403, 5, 0 -0x7246, 0x6565, "\000" - 0 -END - -IDD_OPT_LOGS DLGINIT -BEGIN - IDC_LOG_LEVEL, 0x403, 9, 0 -0x6944, 0x6173, 0x6c62, 0x6465, "\000" - IDC_LOG_LEVEL, 0x403, 6, 0 -0x7245, 0x6f72, 0x0072, - IDC_LOG_LEVEL, 0x403, 8, 0 -0x6157, 0x6e72, 0x6e69, 0x0067, - IDC_LOG_LEVEL, 0x403, 5, 0 -0x6e49, 0x6f66, "\000" - IDC_LOG_LEVEL, 0x403, 6, 0 -0x6544, 0x7562, 0x0067, - 0 -END - -#endif // Français (France) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// -#define _AFX_NO_SPLITTER_RESOURCES -#define _AFX_NO_OLE_RESOURCES -#define _AFX_NO_TRACKER_RESOURCES -#define _AFX_NO_PROPERTY_RESOURCES - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE 9, 1 -#pragma code_page(1252) -#endif //_WIN32 -#include "res\Osmo4.rc2" // non-Microsoft Visual C++ edited resources -#include "afxres.rc" // Standard components -#endif - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Anglais (États-Unis) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MAINFRAME MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&Open File\tCtrl+O", ID_FILEOPEN + MENUITEM "Open &URL\tCtrl+U", ID_OPEN_URL + MENUITEM SEPARATOR + MENUITEM "File Propert&ies\tCtrl+I", ID_FILE_PROP + POPUP "Streaming Cache" + BEGIN + MENUITEM "&Enable", ID_REC_ENABLE + MENUITEM "&Stop and Save", ID_REC_STOP + MENUITEM "&Abort", ID_REC_ABORT + END + MENUITEM SEPARATOR + MENUITEM "Copy", ID_FILE_COPY + MENUITEM "Paste", ID_FILE_PASTE + MENUITEM SEPARATOR + MENUITEM "Exit", ID_FILE_EXIT + END + POPUP "View" + BEGIN + POPUP "Viewpoint" + BEGIN + MENUITEM "", ID_VIEWPORT_EMPTY + END + POPUP "&Navigation" + BEGIN + MENUITEM "Headlight", ID_HEADLIGHT + MENUITEM SEPARATOR + MENUITEM "&None", ID_NAVIGATE_NONE + MENUITEM "&Walk", ID_NAVIGATE_WALK + MENUITEM "&Fly", ID_NAVIGATE_FLY + MENUITEM "&Examine", ID_NAVIGATE_EXAM + MENUITEM "&Pan", ID_NAVIGATE_PAN + MENUITEM "&Slide", ID_NAVIGATE_SLIDE + MENUITEM "&Orbit", ID_NAVIGATE_ORBIT + MENUITEM "&VR", ID_NAVIGATE_VR + MENUITEM "&Game", ID_NAVIGATE_GAME + MENUITEM SEPARATOR + POPUP "Collision" + BEGIN + MENUITEM "Off", ID_COLLIDE_NONE + MENUITEM "Regular", ID_COLLIDE_REG + MENUITEM "Displacement", ID_COLLIDE_DISP + END + MENUITEM "Gravity", ID_GRAVITY + MENUITEM SEPARATOR + MENUITEM "&Reset", ID_NAV_RESET + END + MENUITEM SEPARATOR + MENUITEM "&Fullscreen", ID_VIEW_FULLSCREEN + MENUITEM "Original &Aspect", ID_VIEW_ORIGINAL + POPUP "Aspect &Ratio" + BEGIN + MENUITEM "&Keep Original", ID_AR_KEEP + MENUITEM "&Fill Screen", ID_AR_FILL + MENUITEM "Ratio 4/3", ID_AR_43 + MENUITEM "Ratio 16/9", ID_AR_169 + END + MENUITEM SEPARATOR + MENUITEM "Resource Usage", ID_VIEW_CPU + MENUITEM SEPARATOR + MENUITEM "&Options", IDD_CONFIGURE + END + POPUP "Play" + BEGIN + POPUP "Stream &Selection" + BEGIN + POPUP "Audio" + BEGIN + MENUITEM "", ID_AUDIO_EMPTY + END + POPUP "Video" + BEGIN + MENUITEM "", ID_VIDEO_EMPTY + END + POPUP "Subtitle" + BEGIN + MENUITEM "", ID_SUBS_EMPTY + END + MENUITEM SEPARATOR + MENUITEM "Add Subtitle", ID_ADD_SUBTITLE + END + POPUP "&Chapters" + BEGIN + MENUITEM "", ID_SETCHAP_FIRST + END + MENUITEM SEPARATOR + MENUITEM "Playlist\tCtrl+L", ID_VIEW_PL, CHECKED + MENUITEM "&Loop Playlist", ID_PLAYLIST_LOOP + MENUITEM SEPARATOR + MENUITEM "Play/Pause\tCtrl+P", ID_FILE_PLAY + MENUITEM "Step-by-Step\tCtrl+S", ID_FILE_STEP + MENUITEM "Stop", ID_FILE_STOP + MENUITEM SEPARATOR + MENUITEM "Reload File\tCtrl+R", ID_FILE_RELOAD + MENUITEM SEPARATOR + MENUITEM "Clear History", ID_CLEAR_NAV + MENUITEM "Reload Config", ID_CONFIG_RELOAD + END + POPUP "?" + BEGIN + MENUITEM "Shortcut List", ID_SHORTCUTS + MENUITEM "Navigation Keys", ID_NAV_INFO + MENUITEM SEPARATOR + MENUITEM "&About ...", ID_H_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOGEX 0, 0, 209, 137 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_CLIENTEDGE +CAPTION "Osmo4 / GPAC version X.X.X" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + ICON IDR_MAINFRAME,IDC_STATIC,8,4,20,20 + CTEXT "Osmo4 Player - GPAC Multimedia Framework",IDC_STATIC,31,10,150,10,SS_NOPREFIX + CTEXT "(c) Jean Le Feuvre 2000-2005 - (c) ENST 2005-200X\nAll Rights Reserved",IDC_STATIC,4,64,201,18 + CTEXT "This program is free software and may be distributed according to the terms of the GNU Lesser General Public License",IDC_STATIC,4,26,200,18 + PUSHBUTTON "http://gpac.sourceforge.net",IDC_GOGPAC,43,47,121,13,BS_FLAT,WS_EX_STATICEDGE + GROUPBOX "With Many Thanks To:",IDC_STATIC,3,82,203,53 + CTEXT "The FreeType Project\nMozilla SpiderMonkey (JavaScript support)\n\nZLIB, the PNG Group, the I.J.G.\nFFMPEG, FAAD, XVID, MAD",IDC_STATIC,9,92,189,41 +END + +IDD_PASSWD DIALOG 0, 0, 134, 71 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Enter user name and password" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,4,56,50,12 + PUSHBUTTON "Cancel",IDCANCEL,80,56,50,12 + LTEXT "Static__________________________",IDC_TXT_SITE,25,4,105,8 + LTEXT "Login",IDC_STATIC,7,21,18,8 + LTEXT "Password",IDC_STATIC,7,37,32,8 + EDITTEXT IDC_EDIT_USER,47,18,55,14,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_PASSWORD,47,34,55,14,ES_PASSWORD | ES_AUTOHSCROLL + LTEXT "Site",IDC_STATIC,7,4,13,8 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "Osmo4-GPAC" + VALUE "FileVersion", "0.4.5" + VALUE "InternalName", "Osmo4" + VALUE "LegalCopyright", "Copyright (C) 2005" + VALUE "OriginalFilename", "Osmo4.EXE" + VALUE "ProductName", "Osmo4-GPAC" + VALUE "ProductVersion", "0.4.5" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_ABOUTBOX, DIALOG + BEGIN + BOTTOMMARGIN, 136 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Toolbar +// + +IDR_MAINTOOLS TOOLBAR 16, 15 +BEGIN + BUTTON ID_FILEOPEN + BUTTON ID_NAV_PREV + BUTTON ID_NAV_NEXT + BUTTON ID_FILE_PLAY + BUTTON ID_FILE_PLAY + BUTTON ID_FILE_STEP + BUTTON ID_FILE_STOP + BUTTON ID_FILE_PROPS + BUTTON IDD_CONFIGURE + BUTTON ID_SWITCH_RENDER + BUTTON ID_SWITCH_RENDER +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDR_MAINTOOLS BITMAP "res\\maintool.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDR_MAINFRAME "Osmo4" +END + +STRINGTABLE +BEGIN + AFX_IDS_APP_TITLE "Osmo4" + AFX_IDS_IDLEMESSAGE "Ready" +END + +STRINGTABLE +BEGIN + ID_FILE_EXIT "Quit the application; prompts to save documents\nExit" + ID_H_ABOUT "Display program information, version number and copyright\nAbout" + ID_PLAYLIST_LOOP "Restarts playlist from begining when playlist is over" + ID_FILEOPEN "Opens local file" + ID_VIEW_ORIGINAL "restore Original Aspect of presentation" +END + +STRINGTABLE +BEGIN + ID_VIEW_STATUS_BAR "Show or hide the status bar\nToggle StatusBar" +END + +STRINGTABLE +BEGIN + AFX_IDS_SCSIZE "Change the window size" + AFX_IDS_SCMOVE "Change the window position" + AFX_IDS_SCMINIMIZE "Reduce the window to an icon" + AFX_IDS_SCMAXIMIZE "Enlarge the window to full size" + AFX_IDS_SCNEXTWINDOW "Switch to the next document window" + AFX_IDS_SCPREVWINDOW "Switch to the previous document window" + AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents" +END + +STRINGTABLE +BEGIN + AFX_IDS_SCRESTORE "Restore the window to normal size" + AFX_IDS_SCTASKLIST "Activate Task List" +END + +STRINGTABLE +BEGIN + ID_FILE_STOP "Stops current presentation" + ID_SWITCH_RENDER "Switch between 2D and 3D renderers" + ID_COLLIDE_NONE "Turns collision detection off" + ID_COLLIDE_REG "Turns collision detection on" + ID_COLLIDE_DISP "Collision with camera displacement" + ID_HEADLIGHT "Turns headlight on/off" +END + +STRINGTABLE +BEGIN + ID_CLEAR_NAV "Clears navigation history" + ID_TIMER " " + ID_FPS " " + ID_VIEW_PL "View navigation history as a playlist" +END + +STRINGTABLE +BEGIN + ID_VIEW_FULLSCREEN "Move to Full Screen mode (Esc to exit)" + ID_AR_KEEP "Keep Aspect Ratio of presentation" + ID_SHORTCUTS "List of available shortcuts" + ID_FILE_PROP "Show presentation properties" + ID_FILE_STEP "Step one frame into presentation" + IDD_CONFIGURE "Configure Player" + ID_VIEW_SCALABLE "Uses vectorial zooming when resizing the window" + ID_OPEN_URL "Open remote presentation" + ID_FILE_RELOAD "Reload current presentation" + ID_FILE_PLAY "Play/Pause presentation" + ID_NAVIGATE_NONE "Disable navigation" +END + +STRINGTABLE +BEGIN + ID_NAVIGATE_WALK "Turn walk navigation on" + ID_AR_FILL "Ignores Aspect Ratio and always fill screen" + ID_AR_43 "Forces Aspect Ratio of 4/3" + ID_AR_169 "Forces Aspect Ratio of 16/9" + ID_NAV_RESET "Restore last viewpoint" +END + +STRINGTABLE +BEGIN + ID_NAVIGATE_VR "QT-VR like navigation" + ID_REC_ENABLE "Enable recording of streaming data" + ID_REC_STOP "Stops recording and save to file" + ID_REC_ABORT "Stops recording and discard data" +END + +STRINGTABLE +BEGIN + ID_FILE_COPY "Copy selected text to clipboard" + ID_FILE_PASTE "Paste clipboard" +END + +#endif // Anglais (États-Unis) resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// Français (France) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA) +#ifdef _WIN32 +LANGUAGE LANG_FRENCH, SUBLANG_FRENCH +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_OPENFILE DIALOG 0, 0, 301, 23 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Select Location" +FONT 8, "MS Sans Serif" +BEGIN + COMBOBOX IDC_COMBOURL,3,5,273,67,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "OK",IDC_BUTGO,279,5,19,13 +END + +IDD_OPTIONS DIALOG 0, 0, 174, 106 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Osmo4 Options" +FONT 8, "MS Sans Serif" +BEGIN + PUSHBUTTON "Apply",IDC_SAVEOPT,147,2,26,12 + COMBOBOX IDC_SELECT,42,2,99,173,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Category",IDC_STATIC,7,4,29,8 +END + +IDD_OPT_GEN DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "Loop At End",IDC_LOOP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,4,55,10 + CONTROL "Look for subtitles",IDC_LOOKFORSUB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,42,69,10 + CONTROL "Disable console messages",IDC_NO_CONSOLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,17,99,10 + CONTROL "View Graph in XMT-A format",IDC_DUMP_XMT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,30,105,10 + CONTROL "Single Instance",IDC_SINGLE_INSTANCE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,54,65,10 +END + +IDD_OPT_RENDER DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "Rendering Frame Rate",IDC_STATIC,5,4,72,8 + COMBOBOX IDC_BIFS_RATE,81,2,84,55,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Fast Rendering",IDC_FAST_RENDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,49,64,10 + CONTROL "Force Scene Size",IDC_FORCE_SIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,96,49,72,10 + LTEXT "Anti-Aliasing Level",IDC_STATIC,7,20,58,8 + COMBOBOX IDC_AA_LIST,81,17,84,46,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Use 3D Renderer",IDC_USE_RENDER3D,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,63,71,10 + LTEXT "2D Rasterizer",IDC_STATIC,7,35,44,8 + COMBOBOX IDC_GD_LIST,81,33,84,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_DRAW_BOUNDS,109,60,56,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Bounds",IDC_STATIC,82,64,25,8 +END + +IDD_OPT_AUDIO DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_CONTROL | WS_CHILD | WS_THICKFRAME +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "Spin1",IDC_SPIN_AUDIO,"msctls_updown32",UDS_SETBUDDYINT | UDS_ARROWKEYS,27,15,11,14 + EDITTEXT IDC_EDIT_AUDIO,5,15,19,14,ES_READONLY | ES_NUMBER + CONTROL "Force Audio Config",IDC_FORCE_AUDIO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,3,73,10 + LTEXT "buffers",IDC_STATIC,43,18,23,8 + CONTROL "Spin1",IDC_SPIN_FPS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ARROWKEYS,104,15,11,14 + EDITTEXT IDC_AUDIO_FPS,77,15,24,14,ES_NUMBER + LTEXT "Audio Driver",IDC_STATIC,7,63,40,8 + CONTROL "No Resynchronization",IDC_AUDIO_RESYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,46,82,10 + COMBOBOX IDC_DRIVER_LIST,63,60,103,62,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Disable Notifications",IDC_AUDIO_NOTIFS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,47,79,10 + CONTROL "Disable Multichannel",IDC_AUDIO_MULTICH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,34,81,10 + LTEXT "ms total length",IDC_STATIC,118,18,49,8 +END + +IDD_OPT_VIDEO DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "Video Driver",IDC_STATIC,6,7,40,8 + COMBOBOX IDC_VIDEO_LIST,55,5,111,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Change video resolution in fullscreen",IDC_SWITCH_RES, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,29,131,10 + CONTROL "Use Hardware Video Memory in 2D mode",IDC_HWMEMORY, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,44,143,10 +END + +IDD_OPT_HTTP DIALOGEX 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + PUSHBUTTON "...",IDC_BROWSE_CACHE,57,4,109,12 + CONTROL "Clean cache at exit",IDC_CLEAN_CACHE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,87,23,77,10 + CONTROL "Disable Cache",IDC_RESTART_CACHE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,22,62,10 + LTEXT "Cache Directory",IDC_STATIC,5,5,52,8 + CONTROL "XML progressive load",IDC_SAX_PROGRESSIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,42,84,10 + EDITTEXT IDC_SAX_DELAY,142,41,22,12,ES_CENTER | ES_AUTOHSCROLL | ES_NUMBER + LTEXT "TimeSlice (ms)",IDC_STATIC,91,43,46,8 + EDITTEXT IDC_HTTP_PROXY,54,58,111,12,ES_AUTOHSCROLL + CONTROL "Use proxy",IDC_HTTP_USE_PROXY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,59,47,10 +END + +IDD_OPT_FONT DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "Font Engine",IDC_STATIC,6,11,39,8 + COMBOBOX IDC_FONT_LIST,60,8,105,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "...",IDC_BROWSE_FONT,2,40,164,12 + LTEXT "System Font Directory",IDC_STATIC,46,29,70,8 + COMBOBOX IDC_TEXTURE_MODE,101,58,64,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Text Texturing Mode",IDC_STATIC,7,60,69,8 +END + +IDD_OPT_SYSTEMS DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + COMBOBOX IDC_LANG,75,4,92,58,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Prefered Language for stream selection",IDC_STATIC,3,3,61,17 + LTEXT "Decoder Threading",IDC_STATIC,4,28,62,8 + COMBOBOX IDC_DEC_THREAD,75,25,92,57,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Always draw late BIFS frames",IDC_BIFSDROP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,43,109,10 + CONTROL "Force Single Timeline",IDC_FORCE_DURATION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,58,83,10 +END + +IDD_OPT_STREAM DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "Default Port",IDC_STATIC,6,6,40,8 + COMBOBOX IDC_PORT,52,3,113,61,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "RTP over RTSP",IDC_RTSP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,19,68,10 + CONTROL "use RTP reordering",IDC_REORDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,81,19,76,10 + LTEXT "milliseconds before control timeout",IDC_STATIC,38,34,108,8 + EDITTEXT IDC_TIMEOUT,3,32,30,12,ES_CENTER | ES_AUTOHSCROLL | ES_NUMBER + LTEXT "milliseconds of Media Buffering ",IDC_STATIC,38,48,100,8 + EDITTEXT IDC_BUFFER,3,47,30,12,ES_CENTER | ES_AUTOHSCROLL | ES_NUMBER + EDITTEXT IDC_REBUFFER_LEN,83,60,30,12,ES_CENTER | ES_AUTOHSCROLL | ES_NUMBER + CONTROL "Rebuffer if less than",IDC_REBUFFER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,63,79,10 + LTEXT "milliseconds",IDC_STATIC,117,63,41,8 +END + +IDD_PROPERTIES DIALOGEX 0, 0, 338, 150 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Presentation Properties" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + CONTROL "Tree1",IDC_ODTREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | TVS_TRACKSELECT | WS_BORDER | WS_TABSTOP | 0x400,2,2,120,114 + EDITTEXT IDC_ODINFO,123,17,213,130,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_NOHIDESEL | ES_OEMCONVERT | ES_READONLY | WS_VSCROLL | WS_HSCROLL,WS_EX_DLGMODALFRAME | WS_EX_STATICEDGE + PUSHBUTTON "Get World Info",IDC_WORLD,2,118,119,13 + PUSHBUTTON "View Scene Graph",IDC_VIEWSG,2,134,119,13 + CONTROL "Tab1",IDC_VIEWSEL,"SysTabControl32",TCS_BUTTONS,124,2,208,14 +END + +IDD_OPT_DECODER DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "Prefered Audio Module",-1,46,5,69,8 + COMBOBOX IDC_AUDEC_LIST,26,17,111,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Prefered Video Module",-1,48,40,69,8 + COMBOBOX IDC_VIDEC_LIST,25,52,113,55,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP +END + +IDD_OPT_RENDER2D DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "Disable YUV Hardware",IDC_YUV,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,54,89,10 + LTEXT "Static",IDC_FORMAT_YUV,97,57,67,8 + CONTROL "Direct Rendering",IDC_DIRECTRENDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,32,72,10 + CONTROL "Scalable Zoom",IDC_ZOOM_SCALABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,10,77,10 +END + +IDD_OPT_RENDER3D DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "Use OpenGL Outlines",IDC_RASTER_OUTLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,2,84,10 + CONTROL "Emulate power-of-two textures for video",IDC_EMUL_POW2, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,45,140,10 + CONTROL "Polygon Anti-Aliasing",IDC_DISABLE_POLY_AA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,90,2,78,10 + CONTROL "Disable rectangular texture extensions",IDC_DISABLE_TX_RECT, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,55,135,10 + CONTROL "Bitmap node uses direct pixel copy",IDC_BITMAP_USE_PIXEL, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,65,125,10 + LTEXT "Draw Normals",IDC_STATIC,4,17,45,8 + COMBOBOX IDC_DRAW_NORMALS,4,25,48,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Backface Cull",IDC_STATIC,57,17,55,8 + COMBOBOX IDC_BACK_CULL,57,25,47,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Draw Mode",IDC_STATIC,113,17,55,8 + COMBOBOX IDC_DRAW_MODE,111,25,53,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP +END + +IDD_SLIDERS DIALOG 0, 0, 218, 18 +STYLE DS_SETFONT | WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "Slider1",ID_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,0,3,185,12 + CONTROL "Slider1",ID_AUDIO_VOL,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_BORDER | WS_TABSTOP,187,3,30,13 +END + +IDD_NAVBAR DIALOGEX 0, 0, 279, 15 +STYLE DS_SETFONT | WS_CHILD +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + COMBOBOX IDC_ADDRESS,29,1,130,196,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP,WS_EX_ACCEPTFILES + LTEXT "Address",IDC_DUMTXT,1,4,26,8 +END + +IDD_PLAYLIST DIALOGEX 0, 0, 186, 54 +STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_TOOLWINDOW +CAPTION "Osmo4 Playlist" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + CONTROL "List4",IDC_FILELIST,"SysListView32",LVS_REPORT | WS_BORDER | WS_TABSTOP,1,0,182,51 +END + +IDD_OPT_MCACHE DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + PUSHBUTTON "...",IDC_BROWSE_MCACHE,41,2,126,12 + CONTROL "Overwrite existing files",IDC_MCACHE_OVERWRITE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,18,85,10 + CONTROL "Use filename",IDC_MCACHE_USENAME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,31,57,10 + LTEXT "Record To",IDC_STATIC,4,4,35,8 + EDITTEXT IDC_BASEPRES,81,31,82,12,ES_CENTER | ES_AUTOHSCROLL | ES_NUMBER +END + +IDD_OPT_FILETYPES DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + COMBOBOX IDC_FILELIST,59,6,108,61,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Supported Files",IDC_STATIC,6,8,50,8 + LTEXT "Extension",IDC_FILES_EXT,7,25,154,8 + LTEXT "Mime Type",IDC_FILES_MIMES,7,37,156,8 + CONTROL "Associate with Osmo4",IDC_ASSOCIATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,60,84,10 + LTEXT "Plugin",IDC_FILES_PLUG,8,49,154,8 +END + +IDD_OPT_LOGS DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "Level",IDC_STATIC,6,7,18,8 + COMBOBOX IDC_LOG_LEVEL,30,4,64,74,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "core",IDC_TOOL_CORE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,23,30,10 + CONTROL "coding",IDC_TOOL_CODING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,33,37,10 + CONTROL "container",IDC_TOOL_CONTAINER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,43,45,10 + CONTROL "network",IDC_TOOL_NET,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,53,41,10 + CONTROL "rtp",IDC_TOOL_RTP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,63,24,10 + CONTROL "author",IDC_TOOL_AUTHOR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,48,24,36,10 + CONTROL "sync",IDC_TOOL_SYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,48,34,31,10 + CONTROL "codec",IDC_TOOL_CODEC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,48,44,36,10 + CONTROL "parser",IDC_TOOL_PARSER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,48,54,35,10 + CONTROL "media",IDC_TOOL_MEDIA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,48,64,35,10 + CONTROL "scene",IDC_TOOL_SCENE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,86,24,35,10 + CONTROL "script",IDC_TOOL_SCRIPT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,86,34,33,10 + CONTROL "compose",IDC_TOOL_COMPOSE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,86,44,45,10 + CONTROL "render",IDC_TOOL_RENDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,86,54,36,10 + CONTROL "mmio",IDC_TOOL_MMIO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,86,64,32,10 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_OPT_VIDEO, DIALOG + BEGIN + RIGHTMARGIN, 168 + END + + IDD_OPT_FONT, DIALOG + BEGIN + LEFTMARGIN, 1 + RIGHTMARGIN, 168 + BOTTOMMARGIN, 74 + END + + IDD_OPT_SYSTEMS, DIALOG + BEGIN + RIGHTMARGIN, 167 + TOPMARGIN, 1 + BOTTOMMARGIN, 75 + END + + IDD_OPT_STREAM, DIALOG + BEGIN + LEFTMARGIN, 1 + RIGHTMARGIN, 167 + TOPMARGIN, 1 + END + + IDD_PROPERTIES, DIALOG + BEGIN + RIGHTMARGIN, 335 + TOPMARGIN, 1 + END + + IDD_OPT_DECODER, DIALOG + BEGIN + RIGHTMARGIN, 168 + END + + IDD_OPT_RENDER3D, DIALOG + BEGIN + RIGHTMARGIN, 168 + END + + IDD_NAVBAR, DIALOG + BEGIN + RIGHTMARGIN, 167 + END + + IDD_OPT_FILETYPES, DIALOG + BEGIN + RIGHTMARGIN, 168 + END + + IDD_OPT_LOGS, DIALOG + BEGIN + RIGHTMARGIN, 168 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Toolbar +// + +IDR_PLAYLIST TOOLBAR 16, 15 +BEGIN + BUTTON ID_PL_OPEN + BUTTON ID_PL_SAVE + BUTTON ID_PL_ADD_FILE + BUTTON ID_PL_REM_FILE + BUTTON ID_PL_UP + BUTTON ID_PL_DOWN + BUTTON ID_PL_SORT_FILE +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDR_PLAYLIST BITMAP "res\\playlist.bmp" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "#define _AFX_NO_SPLITTER_RESOURCES\r\n" + "#define _AFX_NO_OLE_RESOURCES\r\n" + "#define _AFX_NO_TRACKER_RESOURCES\r\n" + "#define _AFX_NO_PROPERTY_RESOURCES\r\n" + "\r\n" + "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n" + "#ifdef _WIN32\r\n" + "LANGUAGE 9, 1\r\n" + "#pragma code_page(1252)\r\n" + "#endif //_WIN32\r\n" + "#include ""res\\Osmo4.rc2"" // non-Microsoft Visual C++ edited resources\r\n" + "#include ""afxres.rc"" // Standard components\r\n" + "#endif\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDR_MAINFRAME ICON "..\\..\\doc\\osmo4.ico" +IDI_PLAY ICON "res\\play.ico" +IDI_STOP ICON "res\\stop.ico" +IDI_PAUSE ICON "res\\pause.ico" +IDI_MESSAGE ICON "res\\message.ico" +IDI_ERR ICON "res\\error.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog Info +// + +IDD_OPT_RENDER DLGINIT +BEGIN + IDC_BIFS_RATE, 0x403, 4, 0 +0x2e35, 0x0030, + IDC_BIFS_RATE, 0x403, 4, 0 +0x2e37, 0x0035, + IDC_BIFS_RATE, 0x403, 5, 0 +0x3031, 0x302e, "\000" + IDC_BIFS_RATE, 0x403, 5, 0 +0x3231, 0x352e, "\000" + IDC_BIFS_RATE, 0x403, 5, 0 +0x3531, 0x302e, "\000" + IDC_BIFS_RATE, 0x403, 5, 0 +0x3432, 0x302e, "\000" + IDC_BIFS_RATE, 0x403, 5, 0 +0x3532, 0x302e, "\000" + IDC_BIFS_RATE, 0x403, 5, 0 +0x3033, 0x302e, "\000" + 0 +END + +IDD_OPT_SYSTEMS DLGINIT +BEGIN + IDC_LANG, 0x403, 8, 0 +0x6e45, 0x6c67, 0x7369, 0x0068, + IDC_LANG, 0x403, 7, 0 +0x7246, 0x6e65, 0x6863, "\000" + IDC_LANG, 0x403, 7, 0 +0x6547, 0x6d72, 0x6e61, "\000" + IDC_LANG, 0x403, 8, 0 +0x7449, 0x6c61, 0x6169, 0x006e, + IDC_LANG, 0x403, 8, 0 +0x7053, 0x6e61, 0x7369, 0x0068, + IDC_LANG, 0x403, 9, 0 +0x6843, 0x6e69, 0x6565, 0x6573, "\000" + IDC_LANG, 0x403, 10, 0 +0x614a, 0x6170, 0x656e, 0x7365, 0x0065, + IDC_DEC_THREAD, 0x403, 14, 0 +0x6953, 0x676e, 0x656c, 0x5420, 0x7268, 0x6165, 0x0064, + IDC_DEC_THREAD, 0x403, 13, 0 +0x754d, 0x6c74, 0x2069, 0x6854, 0x6572, 0x6461, "\000" + IDC_DEC_THREAD, 0x403, 5, 0 +0x7246, 0x6565, "\000" + 0 +END + +IDD_OPT_LOGS DLGINIT +BEGIN + IDC_LOG_LEVEL, 0x403, 9, 0 +0x6944, 0x6173, 0x6c62, 0x6465, "\000" + IDC_LOG_LEVEL, 0x403, 6, 0 +0x7245, 0x6f72, 0x0072, + IDC_LOG_LEVEL, 0x403, 8, 0 +0x6157, 0x6e72, 0x6e69, 0x0067, + IDC_LOG_LEVEL, 0x403, 5, 0 +0x6e49, 0x6f66, "\000" + IDC_LOG_LEVEL, 0x403, 6, 0 +0x6544, 0x7562, 0x0067, + 0 +END + +#endif // Français (France) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#define _AFX_NO_SPLITTER_RESOURCES +#define _AFX_NO_OLE_RESOURCES +#define _AFX_NO_TRACKER_RESOURCES +#define _AFX_NO_PROPERTY_RESOURCES + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE 9, 1 +#pragma code_page(1252) +#endif //_WIN32 +#include "res\Osmo4.rc2" // non-Microsoft Visual C++ edited resources +#include "afxres.rc" // Standard components +#endif + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/applications/osmo4_wce/Osmo4.cpp b/applications/osmo4_wce/Osmo4.cpp index 40ee9d5..664e158 100644 --- a/applications/osmo4_wce/Osmo4.cpp +++ b/applications/osmo4_wce/Osmo4.cpp @@ -194,6 +194,7 @@ void COsmo4::EnableLogs(Bool turn_on) BOOL COsmo4::InitInstance() { + Bool first_load = 0; if (!AfxSocketInit()) { AfxMessageBox(IDP_SOCKETS_INIT_FAILED); @@ -230,102 +231,36 @@ BOOL COsmo4::InitInstance() memset(&m_user, 0, sizeof(GF_User)); /*init config and plugins*/ - m_user.config = gf_cfg_new((const char *) config_path, "GPAC.cfg"); + m_user.config = gf_cfg_init(NULL, &first_load); if (!m_user.config) { - /*create blank config file in the exe dir*/ - unsigned char config_file[MAX_PATH]; - strcpy((char *) config_file, (const char *) config_path); - strcat((char *) config_file, "GPAC.cfg"); - FILE *ft = fopen((const char *) config_file, "wt"); - fclose(ft); - m_user.config = gf_cfg_new((const char *) config_path, "GPAC.cfg"); - if (!m_user.config) { - MessageBox(NULL, _T("GPAC Configuration file not found"), _T("Fatal Error"), MB_OK); - m_pMainWnd->PostMessage(WM_CLOSE); - } + MessageBox(NULL, _T("GPAC Configuration file not found"), _T("Fatal Error"), MB_OK); + m_pMainWnd->PostMessage(WM_CLOSE); } const char *str = gf_cfg_get_key(m_user.config, "General", "LogLevel"); EnableLogs((str && !strcmp(str, "debug")) ? 1 : 0); - - str = gf_cfg_get_key(m_user.config, "General", "ModulesDirectory"); - m_user.modules = gf_modules_new(str, m_user.config); - if (!m_user.modules) { - unsigned char str_path[MAX_PATH]; - const char *sOpt; - FILE *t; - /*inital launch*/ - m_user.modules = gf_modules_new(config_path, m_user.config); - if (m_user.modules) { - gf_cfg_set_key(m_user.config, "General", "ModulesDirectory", (const char *) config_path); - - sOpt = gf_cfg_get_key(m_user.config, "Compositor", "Raster2D"); - if (!sOpt) gf_cfg_set_key(m_user.config, "Compositor", "Raster2D", "GPAC 2D Raster"); - - - sOpt = gf_cfg_get_key(m_user.config, "General", "CacheDirectory"); - if (!sOpt) { - sprintf((char *) str_path, "%scache", config_path); - gf_cfg_set_key(m_user.config, "General", "CacheDirectory", (const char *) str_path); - } - /*setup UDP traffic autodetect*/ - gf_cfg_set_key(m_user.config, "Network", "AutoReconfigUDP", "yes"); - gf_cfg_set_key(m_user.config, "Network", "UDPTimeout", "10000"); - gf_cfg_set_key(m_user.config, "Network", "BufferLength", "3000"); - - - /*first launch, register all files ext*/ - u32 i; - for (i=0; iCanHandleURL(ifce, "test.test"); - gf_modules_close_interface((GF_BaseInterface *)ifce); - } + if (first_load) { + /*first launch, register all files ext*/ + u32 i; + for (i=0; iCanHandleURL(ifce, "test.test"); + gf_modules_close_interface((GF_BaseInterface *)ifce); } } - - /*check audio config on windows, force config*/ - sOpt = gf_cfg_get_key(m_user.config, "Audio", "ForceConfig"); - if (!sOpt) { - gf_cfg_set_key(m_user.config, "Audio", "ForceConfig", "yes"); - gf_cfg_set_key(m_user.config, "Audio", "NumBuffers", "2"); - gf_cfg_set_key(m_user.config, "Audio", "TotalDuration", "200"); - } - /*by default use GDIplus, much faster than freetype on font loading*/ - gf_cfg_set_key(m_user.config, "FontEngine", "FontReader", "ft_font"); - - sprintf((char *) str_path, "%sgui/gui.bt", config_path); - t = fopen(str_path, "rt"); - if (!t) { - sprintf((char *) str_path, "%sgpac.mp4", config_path); - t = fopen(str_path, "rt"); - } - if (t) { - gf_cfg_set_key(m_user.config, "General", "StartupFile", (const char *) str_path); - fclose(t); - } - ::MessageBox(NULL, _T("Osmo4/GPAC Setup complete"), _T("Initial launch"), MB_OK); - } - if (! gf_modules_get_count(m_user.modules) ) { - MessageBox(NULL, _T("No plugins available - system cannot work"), _T("Fatal Error"), MB_OK); - m_pMainWnd->PostMessage(WM_QUIT); } - /*setup font dir*/ - str = gf_cfg_get_key(m_user.config, "FontEngine", "FontDirectory"); - if (!str || !strlen(str) ) { - strcpy((char *) config_path, "\\Windows"); - gf_cfg_set_key(m_user.config, "FontEngine", "FontDirectory", (const char *) config_path); - } - /*check video driver, if none or raw_out use dx_hw by default*/ - str = gf_cfg_get_key(m_user.config, "Video", "DriverName"); - if (!str || !stricmp(str, "raw_out")) { - gf_cfg_set_key(m_user.config, "Video", "DriverName", "gapi"); + str = gf_cfg_get_key(m_user.config, "General", "ModulesDirectory"); + m_user.modules = gf_modules_new(str, m_user.config); + if (!m_user.modules || ! gf_modules_get_count(m_user.modules) ) { + MessageBox(NULL, _T("No plugins available - system cannot work"), _T("Fatal Error"), MB_OK); + m_pMainWnd->PostMessage(WM_QUIT); + return FALSE; } m_user.config = m_user.config; diff --git a/applications/osmo4_wx/Makefile b/applications/osmo4_wx/Makefile index 4f2b68e..ca72be1 100644 --- a/applications/osmo4_wx/Makefile +++ b/applications/osmo4_wx/Makefile @@ -21,12 +21,6 @@ endif #common obj OBJS= wxOsmo4.o wxGPACControl.o fileprops.o Playlist.o menubtn.o -ifeq ($(BUILD_INSTALL), yes) -INSTALL_FLAGS=-DGPAC_MODULES_PATH=\"$(moddir)\" -else -INSTALL_FLAGS= -endif - ifeq ($(CONFIG_WIN32),yes) EXE=.exe PROG=Osmo4$(EXE) @@ -54,7 +48,7 @@ Osmo4$(EXE): $(OBJS) $(CC) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(WX_LFLAGS) %.o: %.cpp - $(CXX) $(CFLAGS) $(INSTALL_FLAGS) $(WX_CFLAGS) -c -o $@ $< + $(CXX) $(CFLAGS) $(WX_CFLAGS) -c -o $@ $< clean: rm -f $(OBJS) ../../bin/gcc/$(PROG) @@ -74,7 +68,6 @@ ifeq ($(CONFIG_DARWIN),yes) echo -n 'APPLOsm4' > $(DESTDIR)$(mac_apps)/Osmo4.app/Contents/PkgInfo else rm -f wxOsmo4.o - $(MAKE) -override BUILD_INSTALL=yes all mkdir -p $(DESTDIR)$(prefix)/bin install -m 755 $(INSTFLAGS) ../../bin/gcc/Osmo4 "$(DESTDIR)$(prefix)/bin" endif diff --git a/applications/osmo4_wx/wxOsmo4.cpp b/applications/osmo4_wx/wxOsmo4.cpp index 99d2341..5c7767e 100644 --- a/applications/osmo4_wx/wxOsmo4.cpp +++ b/applications/osmo4_wx/wxOsmo4.cpp @@ -534,85 +534,26 @@ Bool wxOsmo4Frame::LoadTerminal() wxPathList pathList; wxString currentDir(wxGetCwd()); wxString abs_gpac_path = wxT(""); - const char *gpac_cfg; + char *gpac_cfg, *sep; ::wxLogMessage(wxT("Looking for GPAC configuration file")); -#if defined(__WXMAC__) && !defined(__DARWIN__) - // On Mac, the current directory is the relevant one when the application starts. - abs_gpac_path = wxGetCwd(); - gpac_cfg = "GPAC.cfg"; -#else - -#ifdef WIN32 - wxOsmo4App &app = wxGetApp(); - gpac_cfg = "GPAC.cfg"; - /*locate exe*/ - if (wxIsAbsolutePath(app.argv[0])) { - abs_gpac_path = wxPathOnly(app.argv[0]); - } else { - if (currentDir.Last() != wxFILE_SEP_PATH) currentDir += wxFILE_SEP_PATH; - abs_gpac_path = currentDir + app.argv[0]; - if (wxFileExists(abs_gpac_path)) { - abs_gpac_path = wxPathOnly(abs_gpac_path); - } else { - abs_gpac_path = wxT(""); - pathList.AddEnvList(wxT("PATH")); - abs_gpac_path = pathList.FindAbsoluteValidPath(app.argv[0]); - if (!abs_gpac_path.IsEmpty()) { - abs_gpac_path = wxPathOnly(abs_gpac_path); - } else { - /*ask user*/ - wxDirDialog dlg(NULL, wxT("Locate GPAC config file directory")); - if ( dlg.ShowModal() != wxID_OK ) return 0; - abs_gpac_path = dlg.GetPath(); - } - } - } -#else - gpac_cfg = ".gpacrc"; - char *cfg_dir = getenv("HOME"); - if (cfg_dir) { - abs_gpac_path = wxString(cfg_dir, wxConvUTF8); - } else { - /*ask user*/ - wxDirDialog dlg(NULL, wxT("Locate GPAC config file directory")); - if ( dlg.ShowModal() != wxID_OK ) return 0; - abs_gpac_path = dlg.GetPath(); - } -#endif - -#endif - /*load config*/ - m_user.config = gf_cfg_new(abs_gpac_path.mb_str(wxConvUTF8), gpac_cfg); + Bool first_launch = 0; + m_user.config = gf_cfg_init(NULL, &first_launch); if (!m_user.config) { - unsigned char config_file[GF_MAX_PATH]; - strcpy((char *) config_file, (const char *) abs_gpac_path.mb_str(wxConvUTF8)); - if (config_file[strlen((char *) config_file)-1] != GF_PATH_SEPARATOR) { - char szSep[2]; - szSep[0] = GF_PATH_SEPARATOR; - szSep[1] = 0; - strcat((char *) config_file, (const char *)szSep); - } - strcat((char *) config_file, gpac_cfg); - FILE *ft = fopen((const char *) config_file, "wt"); - if (!ft) { - wxMessageDialog(NULL, wxT("Cannot create blank config file"), wxT("Init error"), wxOK).ShowModal(); - return 0; - } - fclose(ft); - m_user.config = gf_cfg_new(abs_gpac_path.mb_str(wxConvUTF8), gpac_cfg); - if (!m_user.config) { - wxMessageDialog(NULL, wxT("Cannot open GPAC configuration file"), wxT("Init error"), wxOK); - return 0; - } + wxMessageDialog(NULL, wxT("Cannot open GPAC configuration file"), wxT("Init error"), wxOK); + return 0; } - strcpy(szAppPath, abs_gpac_path.mb_str(wxConvUTF8)); - if (szAppPath[strlen(szAppPath)] != GF_PATH_SEPARATOR) - sprintf(szAppPath, "%s%c", szAppPath, GF_PATH_SEPARATOR); + gpac_cfg = gf_cfg_get_filename(m_user.config); + sep = strrchr(gpac_cfg, '/'); + if (!sep) sep = strrchr(gpac_cfg, '\\'); + if (sep) sep[0] = 0; + strcpy(szAppPath, gpac_cfg); + if (sep) sep[0] = '/'; + gf_free(gpac_cfg); /*check log file*/ const char *str = gf_cfg_get_key(m_user.config, "General", "LogFile"); @@ -620,84 +561,28 @@ Bool wxOsmo4Frame::LoadTerminal() gf_log_set_callback(this, wxOsmo4_do_log); /*set log level*/ - m_log_level = 0; - str = gf_cfg_get_key(m_user.config, "General", "LogLevel"); - if (str) { - if (!stricmp(str, "debug")) m_log_level = GF_LOG_DEBUG; - else if (!stricmp(str, "info")) m_log_level = GF_LOG_INFO; - else if (!stricmp(str, "warning")) m_log_level = GF_LOG_WARNING; - else if (!stricmp(str, "error")) m_log_level = GF_LOG_ERROR; - gf_log_set_level(m_log_level); - } + m_log_level = gf_log_parse_level( gf_cfg_get_key(m_user.config, "General", "LogLevel") ); + gf_log_set_level(m_log_level); /*set log tools*/ - m_log_tools = 0; - str = gf_cfg_get_key(m_user.config, "General", "LogTools"); - if (str) { - char *sep; - char *val = (char *) str; - while (val) { - sep = strchr(val, ':'); - if (sep) sep[0] = 0; - if (!stricmp(val, "core")) m_log_tools |= GF_LOG_CODING; - else if (!stricmp(val, "coding")) m_log_tools |= GF_LOG_CODING; - else if (!stricmp(val, "container")) m_log_tools |= GF_LOG_CONTAINER; - else if (!stricmp(val, "network")) m_log_tools |= GF_LOG_NETWORK; - else if (!stricmp(val, "rtp")) m_log_tools |= GF_LOG_RTP; - else if (!stricmp(val, "author")) m_log_tools |= GF_LOG_AUTHOR; - else if (!stricmp(val, "sync")) m_log_tools |= GF_LOG_SYNC; - else if (!stricmp(val, "codec")) m_log_tools |= GF_LOG_CODEC; - else if (!stricmp(val, "parser")) m_log_tools |= GF_LOG_PARSER; - else if (!stricmp(val, "media")) m_log_tools |= GF_LOG_MEDIA; - else if (!stricmp(val, "scene")) m_log_tools |= GF_LOG_SCENE; - else if (!stricmp(val, "script")) m_log_tools |= GF_LOG_SCRIPT; - else if (!stricmp(val, "interact")) m_log_tools |= GF_LOG_INTERACT; - else if (!stricmp(val, "compose")) m_log_tools |= GF_LOG_COMPOSE; - else if (!stricmp(val, "mmio")) m_log_tools |= GF_LOG_MMIO; - else if (!stricmp(val, "none")) m_log_tools = 0; - else if (!stricmp(val, "all")) m_log_tools = 0xFFFFFFFF; - if (!sep) break; - sep[0] = ':'; - val = sep+1; - } - gf_log_set_tools(m_log_tools); - } + m_log_tools = gf_log_parse_tools( gf_cfg_get_key(m_user.config, "General", "LogTools") ); + gf_log_set_tools(m_log_tools); gf_sys_init(0); ::wxLogMessage(wxT("GPAC configuration file opened - looking for modules")); - str = gf_cfg_get_key(m_user.config, "General", "ModulesDirectory"); - Bool first_launch = 0; - if (!str) { - first_launch = 1; -#ifdef GPAC_MODULES_PATH - str = GPAC_MODULES_PATH; -#else - str = abs_gpac_path.mb_str(wxConvUTF8); -#endif - } - m_user.modules = gf_modules_new(str, m_user.config); /*initial launch*/ - if (first_launch || !gf_modules_get_count(m_user.modules)) { - const char *sOpt; - wxDirDialog dlg(NULL, wxT("Locate GPAC modules directory")); - if (!gf_modules_get_count(m_user.modules)) { - if (m_user.modules) gf_modules_del(m_user.modules); - m_user.modules = NULL; - if ( dlg.ShowModal() != wxID_OK ) return false; - str = dlg.GetPath().mb_str(wxConvUTF8); - - m_user.modules = gf_modules_new(str, m_user.config); - if (!m_user.modules || !gf_modules_get_count(m_user.modules) ) { - wxMessageDialog(NULL, wxT("Cannot find any modules for GPAC"), wxT("Init error"), wxOK); - gf_cfg_del(m_user.config); - m_user.config = NULL; - return 0; - } - } + if (!m_user.modules || !gf_modules_get_count(m_user.modules)) { + wxMessageDialog(NULL, wxT("No modules available - system cannot work"), wxT("Fatal Error"), wxOK).ShowModal(); + if (m_user.modules) gf_modules_del(m_user.modules); + gf_cfg_del(m_user.config); + m_user.config = NULL; + return 0; + } + if (first_launch) { u32 i; for (i=0; iversion = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; -#ifdef XP_MAC - aNPPFuncs->newp = NewNPP_NewProc(Private_New); - aNPPFuncs->destroy = NewNPP_DestroyProc(Private_Destroy); - aNPPFuncs->setwindow = NewNPP_SetWindowProc(Private_SetWindow); - aNPPFuncs->newstream = NewNPP_NewStreamProc(Private_NewStream); - aNPPFuncs->destroystream = NewNPP_DestroyStreamProc(Private_DestroyStream); - aNPPFuncs->asfile = NewNPP_StreamAsFileProc(Private_StreamAsFile); - aNPPFuncs->writeready = NewNPP_WriteReadyProc(Private_WriteReady); - aNPPFuncs->write = NewNPP_WriteProc(Private_Write); - aNPPFuncs->print = NewNPP_PrintProc(Private_Print); - aNPPFuncs->event = NewNPP_HandleEventProc(Private_HandleEvent); - aNPPFuncs->urlnotify = NewNPP_URLNotifyProc(Private_URLNotify); - aNPPFuncs->getvalue = NewNPP_GetValueProc(Private_GetValue); - aNPPFuncs->setvalue = NewNPP_SetValueProc(Private_SetValue); -#else - aNPPFuncs->newp = NPP_New; - aNPPFuncs->destroy = NPP_Destroy; - aNPPFuncs->setwindow = NPP_SetWindow; - aNPPFuncs->newstream = NPP_NewStream; - aNPPFuncs->destroystream = NPP_DestroyStream; - aNPPFuncs->asfile = NPP_StreamAsFile; - aNPPFuncs->writeready = NPP_WriteReady; - aNPPFuncs->write = NPP_Write; - aNPPFuncs->print = NPP_Print; - aNPPFuncs->event = NPP_HandleEvent; - aNPPFuncs->urlnotify = NPP_URLNotify; - aNPPFuncs->getvalue = NPP_GetValue; - aNPPFuncs->setvalue = NPP_SetValue; -#endif -#ifdef OJI - aNPPFuncs->javaClass = NULL; -#endif - - return NPERR_NO_ERROR; -} - -static NPError fillNetscapeFunctionTable(NPNetscapeFuncs* aNPNFuncs) -{ - if(aNPNFuncs == NULL) - return NPERR_INVALID_FUNCTABLE_ERROR; - - if(HIBYTE(aNPNFuncs->version) > NP_VERSION_MAJOR) - return NPERR_INCOMPATIBLE_VERSION_ERROR; - - if(aNPNFuncs->size < sizeof(NPNetscapeFuncs)) - return NPERR_INVALID_FUNCTABLE_ERROR; - - NPNFuncs.size = aNPNFuncs->size; - NPNFuncs.version = aNPNFuncs->version; - NPNFuncs.geturlnotify = aNPNFuncs->geturlnotify; - NPNFuncs.geturl = aNPNFuncs->geturl; - NPNFuncs.posturlnotify = aNPNFuncs->posturlnotify; - NPNFuncs.posturl = aNPNFuncs->posturl; - NPNFuncs.requestread = aNPNFuncs->requestread; - NPNFuncs.newstream = aNPNFuncs->newstream; - NPNFuncs.write = aNPNFuncs->write; - NPNFuncs.destroystream = aNPNFuncs->destroystream; - NPNFuncs.status = aNPNFuncs->status; - NPNFuncs.uagent = aNPNFuncs->uagent; - NPNFuncs.memalloc = aNPNFuncs->memalloc; - NPNFuncs.memfree = aNPNFuncs->memfree; - NPNFuncs.memflush = aNPNFuncs->memflush; - NPNFuncs.reloadplugins = aNPNFuncs->reloadplugins; -#ifdef OJI - NPNFuncs.getJavaEnv = aNPNFuncs->getJavaEnv; - NPNFuncs.getJavaPeer = aNPNFuncs->getJavaPeer; -#endif - NPNFuncs.getvalue = aNPNFuncs->getvalue; - NPNFuncs.setvalue = aNPNFuncs->setvalue; - NPNFuncs.invalidaterect = aNPNFuncs->invalidaterect; - NPNFuncs.invalidateregion = aNPNFuncs->invalidateregion; - NPNFuncs.forceredraw = aNPNFuncs->forceredraw; - - return NPERR_NO_ERROR; -} - -#ifdef XP_WIN - -NPError OSCALL NP_Initialize(NPNetscapeFuncs* aNPNFuncs) -{ - NPError rv = fillNetscapeFunctionTable(aNPNFuncs); - if(rv != NPERR_NO_ERROR) - return rv; - - return NS_PluginInitialize(); -} - -NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* aNPPFuncs) -{ - return fillPluginFunctionTable(aNPPFuncs); -} - -#endif - - -#ifdef XP_UNIX - -NPError OSCALL NP_Initialize(NPNetscapeFuncs* aNPNFuncs, NPPluginFuncs* aNPPFuncs) -{ - NPError rv = fillNetscapeFunctionTable(aNPNFuncs); - if(rv != NPERR_NO_ERROR) - return rv; - - rv = fillPluginFunctionTable(aNPPFuncs); - if(rv != NPERR_NO_ERROR) - return rv; - - return NS_PluginInitialize(); -} - -char * NP_GetMIMEDescription(void) -{ - return NPP_GetMIMEDescription(); -} - -NPError NP_GetValue(void *future, NPPVariable aVariable, void *aValue) -{ - return NS_PluginGetValue(aVariable, aValue); -} - -#endif - - -#ifdef XP_MAC - - -#if !TARGET_API_MAC_CARBON -QDGlobals* gQDPtr; // Pointer to Netscape's QuickDraw globals -#endif - -short gResFile; // Refnum of the plugin's resource file - -NPError Private_Initialize(void) -{ - NPError rv = NS_PluginInitialize(); - return rv; -} - -void Private_Shutdown(void) -{ - NS_PluginShutdown(); - __destroy_global_chain(); -} - -void SetUpQD(void); - -void SetUpQD(void) -{ - ProcessSerialNumber PSN; - FSSpec myFSSpec; - Str63 name; - ProcessInfoRec infoRec; - OSErr result = noErr; - CFragConnectionID connID; - Str255 errName; - - // Memorize the plugin¹s resource file refnum for later use. - gResFile = CurResFile(); - -#if !TARGET_API_MAC_CARBON - // Ask the system if CFM is available. - long response; - OSErr err = Gestalt(gestaltCFMAttr, &response); - Boolean hasCFM = BitTst(&response, 31-gestaltCFMPresent); - - if (hasCFM) { - // GetProcessInformation takes a process serial number and - // will give us back the name and FSSpec of the application. - // See the Process Manager in IM. - infoRec.processInfoLength = sizeof(ProcessInfoRec); - infoRec.processName = name; - infoRec.processAppSpec = &myFSSpec; - - PSN.highLongOfPSN = 0; - PSN.lowLongOfPSN = kCurrentProcess; - - result = GetProcessInformation(&PSN, &infoRec); - } - else - // If no CFM installed, assume it must be a 68K app. - result = -1; - - if (result == noErr) { - // Now that we know the app name and FSSpec, we can call GetDiskFragment - // to get a connID to use in a subsequent call to FindSymbol (it will also - // return the address of ³main² in app, which we ignore). If GetDiskFragment - // returns an error, we assume the app must be 68K. - Ptr mainAddr; - result = GetDiskFragment(infoRec.processAppSpec, 0L, 0L, infoRec.processName, - kReferenceCFrag, &connID, (Ptr*)&mainAddr, errName); - } - - if (result == noErr) { - // The app is a PPC code fragment, so call FindSymbol - // to get the exported ³qd² symbol so we can access its - // QuickDraw globals. - CFragSymbolClass symClass; - result = FindSymbol(connID, "\pqd", (Ptr*)&gQDPtr, &symClass); - } - else { - // The app is 68K, so use its A5 to compute the address - // of its QuickDraw globals. - gQDPtr = (QDGlobals*)(*((long*)SetCurrentA5()) - (sizeof(QDGlobals) - sizeof(GrafPtr))); - } -#endif /* !TARGET_API_MAC_CARBON */ -} - -NPError main(NPNetscapeFuncs* nsTable, NPPluginFuncs* pluginFuncs, NPP_ShutdownUPP* unloadUpp); - -#if !TARGET_API_MAC_CARBON -#pragma export on -#if GENERATINGCFM -RoutineDescriptor mainRD = BUILD_ROUTINE_DESCRIPTOR(uppNPP_MainEntryProcInfo, main); -#endif -#pragma export off -#endif /* !TARGET_API_MAC_CARBON */ - - -NPError main(NPNetscapeFuncs* aNPNFuncs, NPPluginFuncs* aNPPFuncs, NPP_ShutdownUPP* aUnloadUpp) -{ - NPError rv = NPERR_NO_ERROR; - - if (aUnloadUpp == NULL) - rv = NPERR_INVALID_FUNCTABLE_ERROR; - - if (rv == NPERR_NO_ERROR) - rv = fillNetscapeFunctionTable(aNPNFuncs); - - if (rv == NPERR_NO_ERROR) { - // defer static constructors until the global functions are initialized. - __InitCode__(); - rv = fillPluginFunctionTable(aNPPFuncs); - } - - *aUnloadUpp = NewNPP_ShutdownProc(Private_Shutdown); - SetUpQD(); - rv = Private_Initialize(); - - return rv; -} -#endif //XP_MAC diff --git a/applications/osmozilla/npn_gate.cpp b/applications/osmozilla/npn_gate.cpp deleted file mode 100644 index 13a0c7c..0000000 --- a/applications/osmozilla/npn_gate.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: NPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Netscape Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the NPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the NPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - - -//////////////////////////////////////////////////////////// -// -// Implementation of Netscape entry points (NPN_*) -// -#include "npplat.h" - -extern NPNetscapeFuncs NPNFuncs; - -void NPN_Version(int* plugin_major, int* plugin_minor, int* netscape_major, int* netscape_minor) -{ - *plugin_major = NP_VERSION_MAJOR; - *plugin_minor = NP_VERSION_MINOR; - *netscape_major = HIBYTE(NPNFuncs.version); - *netscape_minor = LOBYTE(NPNFuncs.version); -} - -NPError NPN_GetURLNotify(NPP instance, const char *url, const char *target, void* notifyData) -{ - int navMinorVers = NPNFuncs.version & 0xFF; - NPError rv = NPERR_NO_ERROR; - - if( navMinorVers >= NPVERS_HAS_NOTIFICATION ) - rv = CallNPN_GetURLNotifyProc(NPNFuncs.geturlnotify, instance, url, target, notifyData); - else - rv = NPERR_INCOMPATIBLE_VERSION_ERROR; - - return rv; -} - -NPError NPN_GetURL(NPP instance, const char *url, const char *target) -{ - NPError rv = CallNPN_GetURLProc(NPNFuncs.geturl, instance, url, target); - return rv; -} - -NPError NPN_PostURLNotify(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData) -{ - int navMinorVers = NPNFuncs.version & 0xFF; - NPError rv = NPERR_NO_ERROR; - - if( navMinorVers >= NPVERS_HAS_NOTIFICATION ) - rv = CallNPN_PostURLNotifyProc(NPNFuncs.posturlnotify, instance, url, window, len, buf, file, notifyData); - else - rv = NPERR_INCOMPATIBLE_VERSION_ERROR; - - return rv; -} - -NPError NPN_PostURL(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file) -{ - NPError rv = CallNPN_PostURLProc(NPNFuncs.posturl, instance, url, window, len, buf, file); - return rv; -} - -NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList) -{ - NPError rv = CallNPN_RequestReadProc(NPNFuncs.requestread, stream, rangeList); - return rv; -} - -NPError NPN_NewStream(NPP instance, NPMIMEType type, const char* target, NPStream** stream) -{ - int navMinorVersion = NPNFuncs.version & 0xFF; - - NPError rv = NPERR_NO_ERROR; - - if( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) - rv = CallNPN_NewStreamProc(NPNFuncs.newstream, instance, type, target, stream); - else - rv = NPERR_INCOMPATIBLE_VERSION_ERROR; - - return rv; -} - -int32 NPN_Write(NPP instance, NPStream *stream, int32 len, void *buffer) -{ - int navMinorVersion = NPNFuncs.version & 0xFF; - int32 rv = 0; - - if( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) - rv = CallNPN_WriteProc(NPNFuncs.write, instance, stream, len, buffer); - else - rv = -1; - - return rv; -} - -NPError NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason) -{ - int navMinorVersion = NPNFuncs.version & 0xFF; - NPError rv = NPERR_NO_ERROR; - - if( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) - rv = CallNPN_DestroyStreamProc(NPNFuncs.destroystream, instance, stream, reason); - else - rv = NPERR_INCOMPATIBLE_VERSION_ERROR; - - return rv; -} - -void NPN_Status(NPP instance, const char *message) -{ - CallNPN_StatusProc(NPNFuncs.status, instance, message); -} - -const char* NPN_UserAgent(NPP instance) -{ - const char * rv = NULL; - rv = CallNPN_UserAgentProc(NPNFuncs.uagent, instance); - return rv; -} - -void* NPN_MemAlloc(uint32 size) -{ - void * rv = NULL; - rv = CallNPN_MemAllocProc(NPNFuncs.memalloc, size); - return rv; -} - -void NPN_MemFree(void* ptr) -{ - CallNPN_MemFreeProc(NPNFuncs.memfree, ptr); -} - -uint32 NPN_MemFlush(uint32 size) -{ - uint32 rv = CallNPN_MemFlushProc(NPNFuncs.memflush, size); - return rv; -} - -void NPN_ReloadPlugins(NPBool reloadPages) -{ - CallNPN_ReloadPluginsProc(NPNFuncs.reloadplugins, reloadPages); -} - -#ifdef OJI -JRIEnv* NPN_GetJavaEnv(void) -{ - JRIEnv * rv = NULL; - rv = CallNPN_GetJavaEnvProc(NPNFuncs.getJavaEnv); - return rv; -} - -jref NPN_GetJavaPeer(NPP instance) -{ - jref rv; - rv = CallNPN_GetJavaPeerProc(NPNFuncs.getJavaPeer, instance); - return rv; -} -#endif - -NPError NPN_GetValue(NPP instance, NPNVariable variable, void *value) -{ - NPError rv = CallNPN_GetValueProc(NPNFuncs.getvalue, instance, variable, value); - return rv; -} - -NPError NPN_SetValue(NPP instance, NPPVariable variable, void *value) -{ - NPError rv = CallNPN_SetValueProc(NPNFuncs.setvalue, instance, variable, value); - return rv; -} - -void NPN_InvalidateRect(NPP instance, NPRect *invalidRect) -{ - CallNPN_InvalidateRectProc(NPNFuncs.invalidaterect, instance, invalidRect); -} - -void NPN_InvalidateRegion(NPP instance, NPRegion invalidRegion) -{ - CallNPN_InvalidateRegionProc(NPNFuncs.invalidateregion, instance, invalidRegion); -} - -void NPN_ForceRedraw(NPP instance) -{ - CallNPN_ForceRedrawProc(NPNFuncs.forceredraw, instance); -} diff --git a/applications/osmozilla/npp_gate.cpp b/applications/osmozilla/npp_gate.cpp deleted file mode 100644 index 179dba8..0000000 --- a/applications/osmozilla/npp_gate.cpp +++ /dev/null @@ -1,353 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: NPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Netscape Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the NPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the NPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "osmozilla.h" - - -// here the plugin creates a plugin instance object which -// will be associated with this newly created NPP instance and -// will do all the neccessary job -NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved) -{ - if(instance == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - NPError rv = NPERR_NO_ERROR; - - // create a new plugin instance object - // initialization will be done when the associated window is ready - nsPluginCreateData ds; - - ds.instance = instance; - ds.type = pluginType; - ds.mode = mode; - ds.argc = argc; - ds.argn = argn; - ds.argv = argv; - ds.saved = saved; - - nsPluginInstanceBase * plugin = NS_NewPluginInstance(&ds); - if(plugin == NULL) - return NPERR_OUT_OF_MEMORY_ERROR; - - // associate the plugin instance object with NPP instance - instance->pdata = (void *)plugin; - return rv; -} - -// here is the place to clean up and destroy the nsPluginInstance object -NPError NPP_Destroy (NPP instance, NPSavedData** save) -{ - if(instance == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - NPError rv = NPERR_NO_ERROR; - - nsPluginInstanceBase * plugin = (nsPluginInstanceBase *)instance->pdata; - if(plugin != NULL) { - plugin->shut(); - NS_DestroyPluginInstance(plugin); - } - return rv; -} - -// during this call we know when the plugin window is ready or -// is about to be destroyed so we can do some gui specific -// initialization and shutdown -NPError NPP_SetWindow (NPP instance, NPWindow* pNPWindow) -{ - if(instance == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - NPError rv = NPERR_NO_ERROR; - - if(pNPWindow == NULL) - return NPERR_GENERIC_ERROR; - - nsPluginInstanceBase * plugin = (nsPluginInstanceBase *)instance->pdata; - - if(plugin == NULL) - return NPERR_GENERIC_ERROR; - - // window just created - if(!plugin->isInitialized() && (pNPWindow->window != NULL)) { - if(!plugin->init(pNPWindow)) { - NS_DestroyPluginInstance(plugin); - return NPERR_MODULE_LOAD_FAILED_ERROR; - } - } - - // window goes away - if((pNPWindow->window == NULL) && plugin->isInitialized()) - return plugin->SetWindow(pNPWindow); - - // window resized? - if(plugin->isInitialized() && (pNPWindow->window != NULL)) - return plugin->SetWindow(pNPWindow); - - // this should not happen, nothing to do - if((pNPWindow->window == NULL) && !plugin->isInitialized()) - return plugin->SetWindow(pNPWindow); - - return rv; -} - -NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype) -{ - if(instance == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - nsPluginInstanceBase * plugin = (nsPluginInstanceBase *)instance->pdata; - if(plugin == NULL) - return NPERR_GENERIC_ERROR; - - NPError rv = plugin->NewStream(type, stream, seekable, stype); - return rv; -} - -int32 NPP_WriteReady (NPP instance, NPStream *stream) -{ - if(instance == NULL) - return 0x0fffffff; - - nsPluginInstanceBase * plugin = (nsPluginInstanceBase *)instance->pdata; - if(plugin == NULL) - return 0x0fffffff; - - int32 rv = plugin->WriteReady(stream); - return rv; -} - -int32 NPP_Write (NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer) -{ - if(instance == NULL) - return len; - - nsPluginInstanceBase * plugin = (nsPluginInstanceBase *)instance->pdata; - if(plugin == NULL) - return len; - - int32 rv = plugin->Write(stream, offset, len, buffer); - return rv; -} - -NPError NPP_DestroyStream (NPP instance, NPStream *stream, NPError reason) -{ - if(instance == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - nsPluginInstanceBase * plugin = (nsPluginInstanceBase *)instance->pdata; - if(plugin == NULL) - return NPERR_GENERIC_ERROR; - - NPError rv = plugin->DestroyStream(stream, reason); - return rv; -} - -void NPP_StreamAsFile (NPP instance, NPStream* stream, const char* fname) -{ - if(instance == NULL) - return; - - nsPluginInstanceBase * plugin = (nsPluginInstanceBase *)instance->pdata; - if(plugin == NULL) - return; - - plugin->StreamAsFile(stream, fname); -} - -void NPP_Print (NPP instance, NPPrint* printInfo) -{ - if(instance == NULL) - return; - - nsPluginInstanceBase * plugin = (nsPluginInstanceBase *)instance->pdata; - if(plugin == NULL) - return; - plugin->Print(printInfo); -} - -void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData) -{ - if(instance == NULL) - return; - - nsPluginInstanceBase * plugin = (nsPluginInstanceBase *)instance->pdata; - if(plugin == NULL) - return; - - plugin->URLNotify(url, reason, notifyData); -} - -NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) -{ - if(instance == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - nsPluginInstanceBase * plugin = (nsPluginInstanceBase *)instance->pdata; - if(plugin == NULL) - return NPERR_GENERIC_ERROR; - - NPError rv = plugin->GetValue(variable, value); - return rv; -} - -NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value) -{ - if(instance == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - nsPluginInstanceBase * plugin = (nsPluginInstanceBase *)instance->pdata; - if(plugin == NULL) - return NPERR_GENERIC_ERROR; - - NPError rv = plugin->SetValue(variable, value); - return rv; -} - -int16 NPP_HandleEvent(NPP instance, void* event) -{ - if(instance == NULL) - return 0; - - nsPluginInstanceBase * plugin = (nsPluginInstanceBase *)instance->pdata; - if(plugin == NULL) - return 0; - - uint16 rv = plugin->HandleEvent(event); - return rv; -} - -#ifdef OJI -jref NPP_GetJavaClass (void) -{ - return NULL; -} -#endif - -/**************************************************/ -/* */ -/* Mac */ -/* */ -/**************************************************/ - -// Mac needs these wrappers, see npplat.h for more info - -#ifdef XP_MAC - -NPError Private_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved) -{ - NPError rv = NPP_New(pluginType, instance, mode, argc, argn, argv, saved); - return rv; -} - -NPError Private_Destroy(NPP instance, NPSavedData** save) -{ - NPError rv = NPP_Destroy(instance, save); - return rv; -} - -NPError Private_SetWindow(NPP instance, NPWindow* window) -{ - NPError rv = NPP_SetWindow(instance, window); - return rv; -} - -NPError Private_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype) -{ - NPError rv = NPP_NewStream(instance, type, stream, seekable, stype); - return rv; -} - -int32 Private_WriteReady(NPP instance, NPStream* stream) -{ - int32 rv = NPP_WriteReady(instance, stream); - return rv; -} - -int32 Private_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer) -{ - int32 rv = NPP_Write(instance, stream, offset, len, buffer); - return rv; -} - -void Private_StreamAsFile(NPP instance, NPStream* stream, const char* fname) -{ - NPP_StreamAsFile(instance, stream, fname); -} - - -NPError Private_DestroyStream(NPP instance, NPStream* stream, NPError reason) -{ - NPError rv = NPP_DestroyStream(instance, stream, reason); - return rv; -} - -int16 Private_HandleEvent(NPP instance, void* event) -{ - int16 rv = NPP_HandleEvent(instance, event); - return rv; -} - -void Private_Print(NPP instance, NPPrint* platformPrint) -{ - NPP_Print(instance, platformPrint); -} - -void Private_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData) -{ - NPP_URLNotify(instance, url, reason, notifyData); -} - -jref Private_GetJavaClass(void) -{ - return NULL; -} - -NPError Private_GetValue(NPP instance, NPPVariable variable, void *result) -{ - NPError rv = NPP_GetValue(instance, variable, result); - return rv; -} - -NPError Private_SetValue(NPP instance, NPNVariable variable, void *value) -{ - NPError rv = NPP_SetValue(instance, variable, value); - return rv; -} - -#endif //XP_MAC diff --git a/applications/osmozilla/npplat.h b/applications/osmozilla/npplat.h deleted file mode 100644 index d80dd88..0000000 --- a/applications/osmozilla/npplat.h +++ /dev/null @@ -1,151 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: NPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Netscape Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the NPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the NPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef _NPPLAT_H_ -#define _NPPLAT_H_ - -/**************************************************/ -/* */ -/* Windows */ -/* */ -/**************************************************/ - -#ifdef WIN32 -#include -#endif - -#include "npapi.h" -#include "npupp.h" - -/**************************************************/ -/* */ -/* Unix */ -/* */ -/**************************************************/ -#ifdef XP_UNIX -#include -#endif //XP_UNIX - -/**************************************************/ -/* */ -/* Mac */ -/* */ -/**************************************************/ -#ifdef XP_MAC - -#include -#include -#include -#include -#include -#include - -#include "jri.h" - -// The Mixed Mode procInfos defined in npupp.h assume Think C- -// style calling conventions. These conventions are used by -// Metrowerks with the exception of pointer return types, which -// in Metrowerks 68K are returned in A0, instead of the standard -// D0. Thus, since NPN_MemAlloc and NPN_UserAgent return pointers, -// Mixed Mode will return the values to a 68K plugin in D0, but -// a 68K plugin compiled by Metrowerks will expect the result in -// A0. The following pragma forces Metrowerks to use D0 instead. -// -#ifdef __MWERKS__ -#ifndef powerc -#pragma pointers_in_D0 -#endif -#endif - -#ifdef __MWERKS__ -#ifndef powerc -#pragma pointers_in_A0 -#endif -#endif - -// The following fix for static initializers (which fixes a preious -// incompatibility with some parts of PowerPlant, was submitted by -// Jan Ulbrich. -#ifdef __MWERKS__ - #ifdef __cplusplus - extern "C" { - #endif - #ifndef powerc - extern void __InitCode__(void); - #else - extern void __sinit(void); - #define __InitCode__ __sinit - #endif - extern void __destroy_global_chain(void); - #ifdef __cplusplus - } - #endif // __cplusplus -#endif // __MWERKS__ - -// Wrapper functions for all calls from Netscape to the plugin. -// These functions let the plugin developer just create the APIs -// as documented and defined in npapi.h, without needing to -// install those functions in the function table or worry about -// setting up globals for 68K plugins. -NPError Private_Initialize(void); -void Private_Shutdown(void); -NPError Private_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved); -NPError Private_Destroy(NPP instance, NPSavedData** save); -NPError Private_SetWindow(NPP instance, NPWindow* window); -NPError Private_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype); -NPError Private_DestroyStream(NPP instance, NPStream* stream, NPError reason); -int32 Private_WriteReady(NPP instance, NPStream* stream); -int32 Private_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer); -void Private_StreamAsFile(NPP instance, NPStream* stream, const char* fname); -void Private_Print(NPP instance, NPPrint* platformPrint); -int16 Private_HandleEvent(NPP instance, void* event); -void Private_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData); -jref Private_GetJavaClass(void); -NPError Private_GetValue(NPP instance, NPPVariable variable, void *result); -NPError Private_SetValue(NPP instance, NPNVariable variable, void *value); - -#endif //XP_MAC - -#ifndef HIBYTE -#define HIBYTE(i) (i >> 8) -#endif - -#ifndef LOBYTE -#define LOBYTE(i) (i & 0xff) -#endif - -#endif //_NPPLAT_H_ diff --git a/applications/osmozilla/nsIOsmozilla.h b/applications/osmozilla/nsIOsmozilla.h index fdd4ccc..15869d4 100644 --- a/applications/osmozilla/nsIOsmozilla.h +++ b/applications/osmozilla/nsIOsmozilla.h @@ -1,10 +1,13 @@ /* - * DO NOT EDIT. THIS FILE IS GENERATED FROM nsIOsmozilla.idl - */ +* DO NOT EDIT. THIS FILE IS GENERATED FROM nsIOsmozilla.idl +*/ #ifndef __gen_nsIOsmozilla_h__ #define __gen_nsIOsmozilla_h__ +#include "osmo_npapi.h" + +#ifdef GECKO_XPCOM #ifndef __gen_nsISupports_h__ #include "nsISupports.h" @@ -20,47 +23,47 @@ #define NS_IOSMOZILLA_IID \ {0xd2d536a0, 0xb6fc, 0x11d5, \ - { 0x9d, 0x10, 0x00, 0x60, 0xb0, 0xfb, 0xd8, 0x0b }} + { 0x9d, 0x10, 0x00, 0x60, 0xb0, 0xfb, 0xd8, 0x0b }} class NS_NO_VTABLE nsIOsmozilla : public nsISupports { - public: +public: - NS_DEFINE_STATIC_IID_ACCESSOR(NS_IOSMOZILLA_IID) + NS_DEFINE_STATIC_IID_ACCESSOR(NS_IOSMOZILLA_IID) - /* void Pause (); */ - NS_IMETHOD Pause(void) = 0; + /* void Pause (); */ + NS_IMETHOD Pause(void) = 0; - /* void Play (); */ - NS_IMETHOD Play(void) = 0; + /* void Play (); */ + NS_IMETHOD Play(void) = 0; - /* void Stop (); */ - NS_IMETHOD Stop(void) = 0; + /* void Stop (); */ + NS_IMETHOD Stop(void) = 0; - /* void Update (in string type, in string commands); */ - NS_IMETHOD Update(const char *type, const char *commands) = 0; + /* void Update (in string type, in string commands); */ + NS_IMETHOD Update(const char *type, const char *commands) = 0; }; /* Use this macro when declaring classes that implement this interface. */ #define NS_DECL_NSIOSMOZILLA \ - NS_IMETHOD Pause(void); \ - NS_IMETHOD Play(void); \ - NS_IMETHOD Stop(void); \ - NS_IMETHOD Update(const char *type, const char *commands); + NS_IMETHOD Pause(void); \ + NS_IMETHOD Play(void); \ + NS_IMETHOD Stop(void); \ + NS_IMETHOD Update(const char *type, const char *commands); /* Use this macro to declare functions that forward the behavior of this interface to another object. */ #define NS_FORWARD_NSIOSMOZILLA(_to) \ - NS_IMETHOD Pause(void) { return _to Pause(); } \ - NS_IMETHOD Play(void) { return _to Play(); } \ - NS_IMETHOD Stop(void) { return _to Stop(); } \ - NS_IMETHOD Update(const char *type, const char *commands) { return _to Update(type, commands); } + NS_IMETHOD Pause(void) { return _to Pause(); } \ + NS_IMETHOD Play(void) { return _to Play(); } \ + NS_IMETHOD Stop(void) { return _to Stop(); } \ + NS_IMETHOD Update(const char *type, const char *commands) { return _to Update(type, commands); } /* Use this macro to declare functions that forward the behavior of this interface to another object in a safe way. */ #define NS_FORWARD_SAFE_NSIOSMOZILLA(_to) \ - NS_IMETHOD Pause(void) { return !_to ? NS_ERROR_NULL_POINTER : _to->Pause(); } \ - NS_IMETHOD Play(void) { return !_to ? NS_ERROR_NULL_POINTER : _to->Play(); } \ - NS_IMETHOD Stop(void) { return !_to ? NS_ERROR_NULL_POINTER : _to->Stop(); } \ - NS_IMETHOD Update(const char *type, const char *commands) { return !_to ? NS_ERROR_NULL_POINTER : _to->Update(type, commands); } + NS_IMETHOD Pause(void) { return !_to ? NS_ERROR_NULL_POINTER : _to->Pause(); } \ + NS_IMETHOD Play(void) { return !_to ? NS_ERROR_NULL_POINTER : _to->Play(); } \ + NS_IMETHOD Stop(void) { return !_to ? NS_ERROR_NULL_POINTER : _to->Stop(); } \ + NS_IMETHOD Update(const char *type, const char *commands) { return !_to ? NS_ERROR_NULL_POINTER : _to->Update(type, commands); } #if 0 /* Use the code below as a template for the implementation class for this interface. */ @@ -69,12 +72,12 @@ class NS_NO_VTABLE nsIOsmozilla : public nsISupports { class nsOsmozilla : public nsIOsmozilla { public: - NS_DECL_ISUPPORTS - NS_DECL_NSIOSMOZILLA + NS_DECL_ISUPPORTS + NS_DECL_NSIOSMOZILLA - nsOsmozilla(); - virtual ~nsOsmozilla(); - /* additional members */ + nsOsmozilla(); + virtual ~nsOsmozilla(); + /* additional members */ }; /* Implementation file */ @@ -82,40 +85,41 @@ NS_IMPL_ISUPPORTS1(nsOsmozilla, nsIOsmozilla) nsOsmozilla::nsOsmozilla() { - /* member initializers and constructor code */ + /* member initializers and constructor code */ } nsOsmozilla::~nsOsmozilla() { - /* destructor code */ + /* destructor code */ } /* void Pause (); */ NS_IMETHODIMP nsOsmozilla::Pause() { - return NS_ERROR_NOT_IMPLEMENTED; + return NS_ERROR_NOT_IMPLEMENTED; } /* void Play (); */ NS_IMETHODIMP nsOsmozilla::Play() { - return NS_ERROR_NOT_IMPLEMENTED; + return NS_ERROR_NOT_IMPLEMENTED; } /* void Stop (); */ NS_IMETHODIMP nsOsmozilla::Stop() { - return NS_ERROR_NOT_IMPLEMENTED; + return NS_ERROR_NOT_IMPLEMENTED; } /* void Update (in string type, in string commands); */ NS_IMETHODIMP nsOsmozilla::Update(const char *type, const char *commands) { - return NS_ERROR_NOT_IMPLEMENTED; + return NS_ERROR_NOT_IMPLEMENTED; } /* End of implementation class template. */ #endif +#endif //GECKO_XPCOM #endif /* __gen_nsIOsmozilla_h__ */ diff --git a/applications/osmozilla/osmo_npapi.cpp b/applications/osmozilla/osmo_npapi.cpp new file mode 100644 index 0000000..6e11664 --- /dev/null +++ b/applications/osmozilla/osmo_npapi.cpp @@ -0,0 +1,773 @@ +/* +* GPAC - Multimedia Framework C SDK +* +* Copyright (c) ENST 2000-200X +* All rights reserved +* +* This file is part of GPAC / Osmozilla NPAPI plugin +* +* 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. +* +*/ + + +//////////////////////////////////////////////////////////// +// +// Implementation of Netscape entry points (NPN_*) +// +#include "osmo_npapi.h" +#include "osmozilla.h" + +#if defined(XP_UNIX) && !defined(XP_MACOS) +#include +#include +#endif + +NPNetscapeFuncs *sBrowserFunctions = NULL; + +NPError Osmozilla_GetURL(NPP instance, const char *url, const char *target) +{ + if (!sBrowserFunctions) return NPERR_INVALID_FUNCTABLE_ERROR; + return sBrowserFunctions->geturl(instance, url, target); +} + +void Osmozilla_SetStatus(NPP instance, const char *message) +{ + if (!sBrowserFunctions) return; + sBrowserFunctions->status(instance, message); +} + +#ifndef GECKO_XPCOM +void Osmozilla_InitScripting(Osmozilla *osmo); +#endif + +NPError NPOsmozilla_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved) +{ + Osmozilla *osmo; + NPError rv = NPERR_NO_ERROR; + if(instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + + osmo = (Osmozilla *) malloc(sizeof(Osmozilla)); + memset(osmo, 0, sizeof(Osmozilla)); + + osmo->np_instance = instance; + // associate the plugin instance object with NPP instance + instance->pdata = (void *)osmo; + + Osmozilla_Initialize(osmo, argc, argn, argv); + +#ifndef GECKO_XPCOM + Osmozilla_InitScripting(osmo); +#endif + + return rv; +} + +// here is the place to clean up and destroy the nsPluginInstance object +NPError NPOsmozilla_Destroy (NPP instance, NPSavedData** save) +{ + NPError rv = NPERR_NO_ERROR; + Osmozilla *osmozilla; + if(instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + osmozilla = (Osmozilla*)instance->pdata; + if (osmozilla != NULL) { + Osmozilla_Shutdown(osmozilla); +#ifdef GECKO_XPCOM + NPOsmozilla_ShutdownScript(osmozilla); +#else + if (osmozilla->script_obj) sBrowserFunctions->releaseobject(osmozilla->script_obj); + osmozilla->script_obj = NULL; +#endif + + free(osmozilla); + } + instance->pdata = NULL; + return rv; +} + +// during this call we know when the plugin window is ready or +// is about to be destroyed so we can do some gui specific +// initialization and shutdown +NPError NPOsmozilla_SetWindow (NPP instance, NPWindow* pNPWindow) +{ + Osmozilla *osmozilla; + void *os_wnd_handle, *os_wnd_display; + NPError rv = NPERR_NO_ERROR; + + if (!instance || !instance->pdata) return NPERR_INVALID_INSTANCE_ERROR; + if (pNPWindow == NULL) return NPERR_GENERIC_ERROR; + osmozilla = (Osmozilla *)instance->pdata; + + // window just created + if (!osmozilla->window_set) { + if (pNPWindow->window == NULL) return NPERR_GENERIC_ERROR; + +#ifdef XP_WIN + os_wnd_handle = pNPWindow->window; + os_wnd_display = NULL; +#elif defined(XP_MAXOS) + os_wnd_handle = pNPWindow->window; + os_wnd_display = NULL; +#elif defined(XP_UNIX) + os_wnd_handle = pNPWindow->window; + /*HACK - although we don't use the display in the X11 plugin, this is used to signal that + the user is mozilla and prevent some X11 calls crashing the browser in file playing mode + (eg, "firefox myfile.mp4" )*/ + os_wnd_display =((NPSetWindowCallbackStruct *)pNPWindow->ws_info)->display; +#endif + + if (! Osmozilla_SetWindow(osmozilla, os_wnd_handle, os_wnd_display, pNPWindow->width, pNPWindow->height) ) { + return NPERR_MODULE_LOAD_FAILED_ERROR; + } + + } + +#if 0 + // window goes away + if((pNPWindow->window == NULL) && plugin->isInitialized()) + return plugin->SetWindow(pNPWindow); + + // window resized? + if(plugin->isInitialized() && (pNPWindow->window != NULL)) + return plugin->SetWindow(pNPWindow); + + // this should not happen, nothing to do + if((pNPWindow->window == NULL) && !plugin->isInitialized()) + return plugin->SetWindow(pNPWindow); +#endif + + return rv; +} + +NPError NPOsmozilla_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t *stype) +{ + Osmozilla *osmozilla; + if(instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + osmozilla = (Osmozilla *)instance->pdata; + if(osmozilla== NULL) + return NPERR_GENERIC_ERROR; + + Osmozilla_ConnectTo(osmozilla, stream->url); + *stype = NP_SEEK; + return NPERR_NO_ERROR; +} + +NPINT32 NPOsmozilla_WriteReady (NPP instance, NPStream *stream) +{ + return 0x0fffffff; +} + +NPINT32 NPOsmozilla_Write (NPP instance, NPStream *stream, NPINT32 offset, NPINT32 len, void *buffer) +{ + return len; +} + +NPError NPOsmozilla_DestroyStream (NPP instance, NPStream *stream, NPError reason) +{ + return NPERR_NO_ERROR; +} + +void NPOsmozilla_StreamAsFile (NPP instance, NPStream* stream, const char* fname) +{ +} + +void NPOsmozilla_Print (NPP instance, NPPrint* printInfo) +{ + Osmozilla *osmozilla; + if(instance == NULL) + return; + + osmozilla = (Osmozilla *)instance->pdata; + if(osmozilla== NULL) + return; + + Osmozilla_Print(osmozilla, (printInfo->mode == NP_EMBED) ? 1 : 0, printInfo->print.embedPrint.platformPrint, + printInfo->print.embedPrint.window.x, printInfo->print.embedPrint.window.y, + printInfo->print.embedPrint.window.width, printInfo->print.embedPrint.window.height); +} + +void NPOsmozilla_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData) +{ + return; +} + +NPError NPOsmozilla_GetValue(NPP instance, NPPVariable variable, void *value) +{ + NPError rv = NPERR_NO_ERROR; + Osmozilla *osmozilla; + if(instance == NULL) + return NPERR_INVALID_INSTANCE_ERROR; + + osmozilla = (Osmozilla *)instance->pdata; + if(osmozilla== NULL) return NPERR_GENERIC_ERROR; + + switch (variable) { +#ifdef GECKO_XPCOM + case NPPVpluginScriptableInstance: + rv = NPOsmozilla_GetPeer(osmozilla, value); + break; + + case NPPVpluginScriptableIID: + rv = NPOsmozilla_GetPeerIID(osmozilla, value); + break; +#else + + case NPPVpluginScriptableNPObject: + sBrowserFunctions->retainobject(osmozilla->script_obj); + * (void **)value = osmozilla->script_obj; + break; + +#endif + case NPPVpluginNameString : + *(const char**)value = "Osmozilla/GPAC plugin for NPAPI"; + break; + default: + break; + } + + return rv; +} + + + +NPError NPOsmozilla_SetValue(NPP instance, NPNVariable variable, void *value) +{ + return NPERR_NO_ERROR; +} + +int16_t NPOsmozilla_HandleEvent(NPP instance, void* event) +{ + /*we hacked the proc*/ + return 0; +} + + +NPError OSCALL NP_Shutdown() +{ +#ifdef GECKO_XPCOM + NPOsmozilla_ReleaseServiceManager(); +#endif + return NPERR_NO_ERROR; +} + +static NPError fillPluginFunctionTable(NPPluginFuncs* aNPPFuncs) +{ + if(aNPPFuncs == NULL) + return NPERR_INVALID_FUNCTABLE_ERROR; + + // Set up the plugin function table that Netscape will use to + // call us. Netscape needs to know about our version and size + // and have a UniversalProcPointer for every function we implement. + + aNPPFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; + aNPPFuncs->newp = NPOsmozilla_New; + aNPPFuncs->destroy = NPOsmozilla_Destroy; + aNPPFuncs->setwindow = NPOsmozilla_SetWindow; + aNPPFuncs->newstream = NPOsmozilla_NewStream; + aNPPFuncs->destroystream = NPOsmozilla_DestroyStream; + aNPPFuncs->asfile = NPOsmozilla_StreamAsFile; + aNPPFuncs->writeready = NPOsmozilla_WriteReady; + aNPPFuncs->write = NPOsmozilla_Write; + aNPPFuncs->print = NPOsmozilla_Print; + aNPPFuncs->event = NPOsmozilla_HandleEvent; + aNPPFuncs->urlnotify = NPOsmozilla_URLNotify; + aNPPFuncs->getvalue = NPOsmozilla_GetValue; + aNPPFuncs->setvalue = NPOsmozilla_SetValue; + return NPERR_NO_ERROR; +} + + +static NPError NS_PluginInitialize() +{ +#ifdef GECKO_XPCOM + NPOsmozilla_GetServiceManager(); +#endif + return NPERR_NO_ERROR; +} + +// get values per plugin +NPError NS_PluginGetValue(NPPVariable aVariable, void *aValue) +{ + NPError err = NPERR_NO_ERROR; + switch (aVariable) { + case NPPVpluginNameString: + *((char **)aValue) = (char *) "Osmozilla"; + break; + case NPPVpluginDescriptionString: + *((char **)aValue) = Osmozilla_GetVersion(); + break; + default: + err = NPERR_INVALID_PARAM; + break; + } + return err; +} + + + + +#define GPAC_PLUGIN_MIMETYPES \ + "audio/mpeg:mp2,mp3,mpga,mpega:MP3 Music;" \ + "audio/x-mpeg:mp2,mp3,mpga,mpega:MP3 Music;" \ + "audio/amr:amr,awb:AMR Audio;" \ + "audio/mp4:mp4,mpg4,mpeg4,m4a:MPEG-4 Audio;" \ + "audio/aac:aac:MPEG-4 AAC Music;" \ + "audio/aacp:aac:MPEG-4 AACPlus Music;" \ + "audio/basic:snd,au:Basic Audio;" \ + "audio/x-wav:wav:WAV Audio;" \ + "audio/3gpp:3gp,3gpp:3GPP/MMS Music;" \ + "audio/3gpp2:3g2,3gp2:3GPP2/MMS Music;" \ + "video/mpeg:mpg,mpeg,mpe,mpv2:MPEG Video;" \ + "video/x-mpeg:mpg,mpeg,mpe,mpv2:MPEG Video;" \ + "video/mpeg-system:mpg,mpeg,mpe,vob,mpv2:MPEG Video;" \ + "video/x-mpeg-system:mpg,mpeg,mpe,vob,mpv2:MPEG Video;" \ + "video/avi:avi:AVI Video;" \ + "video/quicktime:mov,qt:QuickTime Movies;" \ + "video/x-ms-asf:asf,asx:Windows Media Video;" \ + "video/x-ms-wmv:wmv:Windows Media;" \ + "video/mp4:mp4,mpg4:MPEG-4 Video;" \ + "video/3gpp:3gp,3gpp:3GPP/MMS Video;" \ + "video/3gpp2:3g2,3gp2:3GPP2/MMS Video;" \ + "image/jpeg:jpeg,jpg:JPEG Images;" \ + "image/png:png:PNG Images;" \ + "image/bmp:bmp:MS Bitmap Images;" \ + "image/svg+xml:svg,svg.gz,svgz:SVG Document;" \ + "image/x-svgm:svgm:SVGM Document;" \ + "x-subtitle/srt:srt:SRT SubTitles;" \ + "x-subtitle/sub:sub:SUB SubTitles;" \ + "x-subtitle/ttxt:ttxt:GPAC 3GPP TimedText;" \ + "model/vrml:wrl,wrl.gz:VRML World;" \ + "model/x3d+vrml:x3dv,x3dv.gz,x3dvz:X3D/VRML World;" \ + "model/x3d+xml:x3d,x3d.gz,x3dz:X3D/XML World;" \ + "application/ogg:ogg:Ogg Media;" \ + "application/x-ogg:ogg:Ogg Media;" \ + "application/x-bt:bt,bt.gz,btz:MPEG-4 Text (BT);" \ + "application/x-xmt:xmt,xmt.gz,xmtz:MPEG-4 Text (XMT);" \ + "application/mp4:mp4,mpg4:MPEG-4 Movies;" \ + "application/sdp:sdp:Streaming Media Session;" \ + /* explicit plugin call */ \ + "application/x-gpac::GPAC plugin;" \ + +char * NP_GetMIMEDescription(void) +{ + return (char *) GPAC_PLUGIN_MIMETYPES; +} + + +NPError NP_GetValue(void *future, NPPVariable aVariable, void *aValue) +{ + return NS_PluginGetValue(aVariable, aValue); +} + + +#if defined(XP_WIN) || defined(XP_MACOS) + +NPError OSCALL NP_Initialize(NPNetscapeFuncs* aNPNFuncs) +{ + sBrowserFunctions = aNPNFuncs; + + return NS_PluginInitialize(); +} + +NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* aNPPFuncs) +{ + return fillPluginFunctionTable(aNPPFuncs); +} + + +#elif defined(XP_UNIX) + +NPError OSCALL NP_Initialize(NPNetscapeFuncs* aNPNFuncs, NPPluginFuncs* aNPPFuncs) +{ + NPError rv; + sBrowserFunctions = aNPNFuncs; + rv = fillPluginFunctionTable(aNPPFuncs); + if(rv != NPERR_NO_ERROR) + return rv; + + return NS_PluginInitialize(); +} +#endif + + +#ifdef GECKO_XPCOM + + +#include +#include +#include +#include +#include + +#include "nsIOsmozilla.h" + +#include "osmozilla.h" + + +nsIServiceManager *gServiceManager = NULL; + + +// We must implement nsIClassInfo because it signals the +// Mozilla Security Manager to allow calls from JavaScript. +// helper class to implement all necessary nsIClassInfo method stubs +// and to set flags used by the security system + +class nsClassInfoMixin : public nsIClassInfo +{ + // These flags are used by the DOM and security systems to signal that + // JavaScript callers are allowed to call this object's scritable methods. + NS_IMETHOD GetFlags(PRUint32 *aFlags) + {*aFlags = nsIClassInfo::PLUGIN_OBJECT | nsIClassInfo::DOM_OBJECT; + return NS_OK;} + + NS_IMETHOD GetImplementationLanguage(PRUint32 *aImplementationLanguage) + {*aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; + return NS_OK;} + + // The rest of the methods can safely return error codes... + NS_IMETHOD GetInterfaces(PRUint32 *count, nsIID * **array) + {return NS_ERROR_NOT_IMPLEMENTED;} + NS_IMETHOD GetHelperForLanguage(PRUint32 language, nsISupports **_retval) + {return NS_ERROR_NOT_IMPLEMENTED;} + NS_IMETHOD GetContractID(char * *aContractID) + {return NS_ERROR_NOT_IMPLEMENTED;} + NS_IMETHOD GetClassDescription(char * *aClassDescription) + {return NS_ERROR_NOT_IMPLEMENTED;} + NS_IMETHOD GetClassID(nsCID * *aClassID) + {return NS_ERROR_NOT_IMPLEMENTED;} + NS_IMETHOD GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) + {return NS_ERROR_NOT_IMPLEMENTED;} +}; + + +class nsOsmozillaPeer : public nsIOsmozilla , public nsClassInfoMixin +{ +public: + nsOsmozillaPeer(Osmozilla *osmo); + virtual ~nsOsmozillaPeer(); + + // methods from nsISupports + NS_IMETHOD QueryInterface(const nsIID & aIID, void **aInstancePtr); + NS_IMETHOD_(nsrefcnt) AddRef(); + NS_IMETHOD_(nsrefcnt) Release(); + +public: + NS_DECL_NSIOSMOZILLA + void SetInstance(Osmozilla *osmo); + +protected: + nsrefcnt mRefCnt; + Osmozilla *mPlugin; +}; + + +static NS_DEFINE_IID(kIZillaPluginIID, NS_IOSMOZILLA_IID); +static NS_DEFINE_IID(kIClassInfoIID, NS_ICLASSINFO_IID); +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); + +nsOsmozillaPeer::nsOsmozillaPeer(Osmozilla *osmo) +{ + mPlugin=osmo; + mRefCnt = 0; +} + +nsOsmozillaPeer::~nsOsmozillaPeer() +{ +} +// Notice that we expose our claim to implement nsIClassInfo. +//NS_IMPL_ISUPPORTS2(nsOsmozillaPeer, nsITestPlugin, nsIClassInfo) + +// the following method will be callable from JavaScript +NS_IMETHODIMP nsOsmozillaPeer::Pause() { + Osmozilla_Pause(mPlugin); + return NS_OK; +} +NS_IMETHODIMP nsOsmozillaPeer::Play() { + Osmozilla_Play(mPlugin); + return NS_OK; +} +NS_IMETHODIMP nsOsmozillaPeer::Stop() { + Osmozilla_Stop(mPlugin); + return NS_OK; +} + +NS_IMETHODIMP nsOsmozillaPeer::Update(const char *type, const char *commands) +{ + Osmozilla_Update(mPlugin, type, commands); + return NS_OK; +} + +void nsOsmozillaPeer::SetInstance(Osmozilla *osmo) +{ + mPlugin = osmo; +} + +NS_IMETHODIMP_(nsrefcnt) nsOsmozillaPeer::AddRef() +{ + ++mRefCnt; + return mRefCnt; +} + +NS_IMETHODIMP_(nsrefcnt) nsOsmozillaPeer::Release() +{ + --mRefCnt; + if (mRefCnt == 0) { + delete this; + return 0; + } + return mRefCnt; +} + +// here nsOsmozillaPeer should return three interfaces it can be asked for by their iid's +// static casts are necessary to ensure that correct pointer is returned +NS_IMETHODIMP nsOsmozillaPeer::QueryInterface(const nsIID & aIID, + void **aInstancePtr) +{ + if (!aInstancePtr) + return NS_ERROR_NULL_POINTER; + + if (aIID.Equals(kIZillaPluginIID)) { + *aInstancePtr = NS_STATIC_CAST(nsIOsmozilla *, this); + AddRef(); + return NS_OK; + } + + if (aIID.Equals(kIClassInfoIID)) { + *aInstancePtr = NS_STATIC_CAST(nsIClassInfo *, this); + AddRef(); + return NS_OK; + } + + if (aIID.Equals(kISupportsIID)) { + *aInstancePtr = NS_STATIC_CAST(nsISupports *, (NS_STATIC_CAST (nsIOsmozilla *, this))); + AddRef(); + return NS_OK; + } + return NS_NOINTERFACE; +} + + +extern NPNetscapeFuncs *sBrowserFunctions; + +void NPOsmozilla_GetServiceManager() +{ + // this is probably a good place to get the service manager + // note that Mozilla will add reference, so do not forget to release + nsISupports *sm = NULL; + + if (!sBrowserFunctions) return; + sBrowserFunctions->getvalue(NULL, NPNVserviceManager, &sm); + + // Mozilla returns nsIServiceManager so we can use it directly; doing QI on + // nsISupports here can still be more appropriate in case something is changed + // in the future so we don't need to do casting of any sort. + if (sm) { + sm->QueryInterface(NS_GET_IID(nsIServiceManager), (void **) &gServiceManager); + NS_RELEASE(sm); + } +} + +void NPOsmozilla_ReleaseServiceManager() +{ +#ifdef GECKO_XPCOM + // we should release the service manager + NS_IF_RELEASE(gServiceManager); + gServiceManager = NULL; +#endif +} + +void NPOsmozilla_ShutdownScript(Osmozilla *osmo) +{ + nsOsmozillaPeer *peer = (nsOsmozillaPeer *) osmo->scriptable_peer; + if (peer != NULL) { + peer->SetInstance(NULL); + NS_IF_RELEASE(peer); + } +} + + +NPError NPOsmozilla_GetPeer(Osmozilla *osmo, void *value) +{ + if (!osmo->scriptable_peer) { + osmo->scriptable_peer = new nsOsmozillaPeer(osmo); + if (!osmo->scriptable_peer) return NPERR_OUT_OF_MEMORY_ERROR; + NS_ADDREF( (nsOsmozillaPeer *) osmo->scriptable_peer); + } + + NS_ADDREF( (nsOsmozillaPeer *)osmo->scriptable_peer); + *(nsISupports **) value = (nsISupports *) osmo->scriptable_peer; + return NPERR_NO_ERROR; +} + +NPError NPOsmozilla_GetPeerIID(Osmozilla *osmo, void *value) +{ + static nsIID scriptableIID = NS_IOSMOZILLA_IID; + if (!sBrowserFunctions) return NPERR_OUT_OF_MEMORY_ERROR; + + nsIID *ptr = (nsIID *) sBrowserFunctions->memalloc( sizeof(nsIID) ); + if (! ptr) return NPERR_OUT_OF_MEMORY_ERROR; + + *ptr = scriptableIID; + *(nsIID **) value = ptr; + return NPERR_NO_ERROR; +} + +#else + +#define kOSMOZILLA_ID_METHOD_PLAY 0 +#define kOSMOZILLA_ID_METHOD_PAUSE 1 +#define kOSMOZILLA_ID_METHOD_STOP 2 +#define kOSMOZILLA_ID_METHOD_UPDATE 3 + +#define kOSMOZILLA_NUM_METHODS 4 + +NPIdentifier v_OSMOZILLA_MethodIdentifiers[kOSMOZILLA_NUM_METHODS]; +const NPUTF8 * v_OSMOZILLA_MethodNames[kOSMOZILLA_NUM_METHODS] = { + "Play", + "Pause", + "Stop", + "Update" +}; + +NPClass osmozilla_script_class; + +typedef struct { + NPClass *_class; + uint32_t referenceCount; + Osmozilla *osmo; +} OsmozillaObject; + +NPObject *OSMOZILLA_Allocate(NPP npp, NPClass *theClass) +{ + OsmozillaObject *obj = NULL; + + sBrowserFunctions->getstringidentifiers(v_OSMOZILLA_MethodNames, kOSMOZILLA_NUM_METHODS, v_OSMOZILLA_MethodIdentifiers); + obj = (OsmozillaObject *)malloc(sizeof(OsmozillaObject)); + obj->osmo = (Osmozilla *) npp->pdata; + return (NPObject *)obj; +} + +void OSMOZILLA_Deallocate(NPObject* obj) +{ + free(obj); + return; +} + +void OSMOZILLA_Invalidate(NPObject* obj) +{ + return; +} + +bool OSMOZILLA_HasMethod(NPObject* obj, NPIdentifier name) +{ + int i = 0; + while (i < kOSMOZILLA_NUM_METHODS) { + if ( name == v_OSMOZILLA_MethodIdentifiers[i] ) { + return 1; + } + i++; + } + return 0; +} + +bool OSMOZILLA_Invoke(NPObject* obj, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result) +{ + OsmozillaObject *npo = (OsmozillaObject *)obj; + if (!npo->osmo) return 0; + if (name == v_OSMOZILLA_MethodIdentifiers[kOSMOZILLA_ID_METHOD_PLAY]) { + Osmozilla_Play(npo->osmo); + return 1; + } + if (name == v_OSMOZILLA_MethodIdentifiers[kOSMOZILLA_ID_METHOD_PAUSE]) { + Osmozilla_Pause(npo->osmo); + return 1; + } + if (name == v_OSMOZILLA_MethodIdentifiers[kOSMOZILLA_ID_METHOD_STOP]) { + Osmozilla_Stop(npo->osmo); + return 1; + } + if (name == v_OSMOZILLA_MethodIdentifiers[kOSMOZILLA_ID_METHOD_UPDATE]) { + const char *mime = NULL; + const char *update = NULL; + if (argCount==2) { + mime = (args[0].type==NPVariantType_String) ? args[0].value.stringValue.UTF8Characters : NULL; + update = (args[1].type==NPVariantType_String) ? args[1].value.stringValue.UTF8Characters : NULL; + } + if (!update) return 0; + Osmozilla_Update(npo->osmo, mime, update); + return 1; + } + return 0; +} + +bool OSMOZILLA_InvokeDefault(NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result) +{ + return 1; +} + +bool OSMOZILLA_HasProperty(NPObject* obj, NPIdentifier name) +{ + bool result = 0; + /*nothing exposed yet*/ + return result; +} + +bool OSMOZILLA_GetProperty(NPObject* obj, NPIdentifier name, NPVariant* result) +{ + return 1; +} + +bool OSMOZILLA_SetProperty(NPObject *obj, NPIdentifier name, const NPVariant *value) +{ + return 1; +} + +bool OSMOZILLA_RemoveProperty(NPObject *npobj, NPIdentifier name) +{ + return 1; +} + +bool OSMOZILLA_Enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count) +{ + return 1; +} + +void Osmozilla_InitScripting(Osmozilla *osmo) +{ + osmozilla_script_class.allocate = OSMOZILLA_Allocate; + osmozilla_script_class.deallocate = OSMOZILLA_Deallocate; + osmozilla_script_class.invalidate = OSMOZILLA_Invalidate; + osmozilla_script_class.hasMethod = OSMOZILLA_HasMethod; + osmozilla_script_class.invoke = OSMOZILLA_Invoke; + osmozilla_script_class.invokeDefault = OSMOZILLA_InvokeDefault; + osmozilla_script_class.hasProperty = OSMOZILLA_HasProperty; + osmozilla_script_class.getProperty = OSMOZILLA_GetProperty; + osmozilla_script_class.setProperty = OSMOZILLA_SetProperty; + osmozilla_script_class.removeProperty = OSMOZILLA_RemoveProperty; + osmozilla_script_class.enumerate = OSMOZILLA_Enumerate; + + /*create script object*/ + osmo->script_obj = sBrowserFunctions->createobject(osmo->np_instance, &osmozilla_script_class); + +} + +#endif //GECKO_XPCOM + diff --git a/applications/osmozilla/osmo_npapi.h b/applications/osmozilla/osmo_npapi.h new file mode 100644 index 0000000..cd2c3bf --- /dev/null +++ b/applications/osmozilla/osmo_npapi.h @@ -0,0 +1,133 @@ +/* +* GPAC - Multimedia Framework C SDK +* +* Copyright (c) ENST 2000-200X +* All rights reserved +* +* This file is part of GPAC / Osmozilla NPAPI plugin +* +* 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. +* +*/ + +#ifndef _OSMO_NPAPI_H_ +#define _OSMO_NPAPI_H_ + + +#ifdef WIN32 +#include +#ifndef __cplusplus +typedef BOOL bool; +#endif //__cplusplus +#endif + +#include "npapi.h" + +/*check this with gecko 1.9.2*/ +#if (NP_VERSION_MINOR < 20) +#define GECKO_XPCOM +#endif + +#ifdef GECKO_XPCOM +#include "npupp.h" + +#ifndef uint16_t +typedef uint16 uint16_t; +#endif + +#ifndef int16_t +typedef int16 int16_t; +#endif + +#define NPINT32 int32 + +#else + +#include "npfunctions.h" + +#define NPINT32 int32_t + +#endif + +#ifdef XP_UNIX +#include +#endif //XP_UNIX + + +#ifndef HIBYTE +#define HIBYTE(i) (i >> 8) +#endif + +#ifndef LOBYTE +#define LOBYTE(i) (i & 0xff) +#endif + +/*functions callbacks to browser*/ +NPError Osmozilla_GetURL(NPP instance, const char *url, const char *target); +void Osmozilla_SetStatus(NPP instance, const char *message); + + +/* +Plugins functions exposed to browser +*/ +NPError NPOsmozilla_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved); +NPError NPOsmozilla_Destroy(NPP instance, NPSavedData** save); +NPError NPOsmozilla_SetWindow(NPP instance, NPWindow* window); +NPError NPOsmozilla_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype); +NPError NPOsmozilla_DestroyStream(NPP instance, NPStream* stream, NPError reason); +NPINT32 NPOsmozilla_WriteReady(NPP instance, NPStream* stream); +NPINT32 NPOsmozilla_Write(NPP instance, NPStream* stream, NPINT32 offset, NPINT32 len, void* buffer); +void NPOsmozilla_StreamAsFile(NPP instance, NPStream* stream, const char* fname); +void NPOsmozilla_Print(NPP instance, NPPrint* platformPrint); +int16_t NPOsmozilla_HandleEvent(NPP instance, void* event); +void NPOsmozilla_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData); +NPError NPOsmozilla_GetValue(NPP instance, NPPVariable variable, void *result); +NPError NPOsmozilla_SetValue(NPP instance, NPNVariable variable, void *value); + + +/* +Functions called by browser +*/ + +typedef struct __tag_osmozilla Osmozilla; + +/*base functions*/ +int Osmozilla_Initialize(Osmozilla *osmo, signed short argc, char* argn[], char* argv[]); +void Osmozilla_Shutdown(Osmozilla *osmo); +int Osmozilla_SetWindow(Osmozilla *osmozilla, void *os_wnd_handle, void *os_wnd_display, unsigned int width, unsigned int height); +void Osmozilla_ConnectTo(Osmozilla *osmozilla, const char *url); +void Osmozilla_Print(Osmozilla *osmozilla, unsigned int is_embed, void *os_print_dc, unsigned int target_x, unsigned int target_y, unsigned int target_width, unsigned int target_height); +char *Osmozilla_GetVersion(); + + +/*scripting functions*/ +void Osmozilla_Play(Osmozilla *osmo); +void Osmozilla_Pause(Osmozilla *osmo); +void Osmozilla_Stop(Osmozilla *osmo); +void Osmozilla_Update(Osmozilla *osmo, const char *type, const char *commands); + + + +#ifdef GECKO_XPCOM + +void NPOsmozilla_GetServiceManager(); +void NPOsmozilla_ReleaseServiceManager(); +void NPOsmozilla_ShutdownScript(Osmozilla *osmo); +NPError NPOsmozilla_GetPeer(Osmozilla *osmo, void *value); +NPError NPOsmozilla_GetPeerIID(Osmozilla *osmo, void *value); + +#endif //GECKO_XPCOM + +#endif //_NPPLAT_H_ diff --git a/applications/osmozilla/osmozilla.cpp b/applications/osmozilla/osmozilla.cpp index e683b1e..784fd6e 100644 --- a/applications/osmozilla/osmozilla.cpp +++ b/applications/osmozilla/osmozilla.cpp @@ -1,265 +1,55 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: NPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Netscape Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the NPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the NPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include -#include -#include -#include -#include -#ifdef WIN32 -#include -#include -#endif -#include "osmozilla.h" - -#include -#include - -nsIServiceManager *gServiceManager = NULL; - - -#define GPAC_PLUGIN_MIMETYPES \ - "audio/mpeg:mp2,mp3,mpga,mpega:MP3 Music;" \ - "audio/x-mpeg:mp2,mp3,mpga,mpega:MP3 Music;" \ - "audio/amr:amr,awb:AMR Audio;" \ - "audio/mp4:mp4,mpg4,mpeg4,m4a:MPEG-4 Audio;" \ - "audio/aac:aac:MPEG-4 AAC Music;" \ - "audio/aacp:aac:MPEG-4 AACPlus Music;" \ - "audio/basic:snd,au:Basic Audio;" \ - "audio/x-wav:wav:WAV Audio;" \ - "audio/3gpp:3gp,3gpp:3GPP/MMS Music;" \ - "audio/3gpp2:3g2,3gp2:3GPP2/MMS Music;" \ - "video/mpeg:mpg,mpeg,mpe,mpv2:MPEG Video;" \ - "video/x-mpeg:mpg,mpeg,mpe,mpv2:MPEG Video;" \ - "video/mpeg-system:mpg,mpeg,mpe,vob,mpv2:MPEG Video;" \ - "video/x-mpeg-system:mpg,mpeg,mpe,vob,mpv2:MPEG Video;" \ - "video/avi:avi:AVI Video;" \ - "video/quicktime:mov,qt:QuickTime Movies;" \ - "video/x-ms-asf:asf,asx:Windows Media Video;" \ - "video/x-ms-wmv:wmv:Windows Media;" \ - "video/mp4:mp4,mpg4:MPEG-4 Video;" \ - "video/3gpp:3gp,3gpp:3GPP/MMS Video;" \ - "video/3gpp2:3g2,3gp2:3GPP2/MMS Video;" \ - "image/jpeg:jpeg,jpg:JPEG Images;" \ - "image/png:png:PNG Images;" \ - "image/bmp:bmp:MS Bitmap Images;" \ - "image/svg+xml:svg,svg.gz,svgz:SVG Document;" \ - "image/x-svgm:svgm:SVGM Document;" \ - "x-subtitle/srt:srt:SRT SubTitles;" \ - "x-subtitle/sub:sub:SUB SubTitles;" \ - "x-subtitle/ttxt:ttxt:GPAC 3GPP TimedText;" \ - "model/vrml:wrl,wrl.gz:VRML World;" \ - "model/x3d+vrml:x3dv,x3dv.gz,x3dvz:X3D/VRML World;" \ - "model/x3d+xml:x3d,x3d.gz,x3dz:X3D/XML World;" \ - "application/ogg:ogg:Ogg Media;" \ - "application/x-ogg:ogg:Ogg Media;" \ - "application/x-bt:bt,bt.gz,btz:MPEG-4 Text (BT);" \ - "application/x-xmt:xmt,xmt.gz,xmtz:MPEG-4 Text (XMT);" \ - "application/mp4:mp4,mpg4:MPEG-4 Movies;" \ - "application/sdp:sdp:Streaming Media Session;" \ - /* explicit plugin call */ \ - "application/x-gpac::GPAC plugin;" \ - - -char* NPP_GetMIMEDescription(void) -{ - return (char *) GPAC_PLUGIN_MIMETYPES; -} +/* +* GPAC - Multimedia Framework C SDK +* +* Copyright (c) ENST 2000-200X +* All rights reserved +* +* This file is part of GPAC / Osmozilla NPAPI plugin +* +* 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. +* +*/ -///////////////////////////////////// -// general initialization and shutdown -// -NPError NS_PluginInitialize() -{ - // this is probably a good place to get the service manager - // note that Mozilla will add reference, so do not forget to release - nsISupports *sm = NULL; - - NPN_GetValue(NULL, NPNVserviceManager, &sm); - - // Mozilla returns nsIServiceManager so we can use it directly; doing QI on - // nsISupports here can still be more appropriate in case something is changed - // in the future so we don't need to do casting of any sort. - if (sm) { - sm->QueryInterface(NS_GET_IID(nsIServiceManager), (void **) &gServiceManager); - NS_RELEASE(sm); - } - return NPERR_NO_ERROR; -} - -void NS_PluginShutdown() -{ - // we should release the service manager - NS_IF_RELEASE(gServiceManager); - gServiceManager = NULL; -} - -// get values per plugin -NPError NS_PluginGetValue(NPPVariable aVariable, void *aValue) -{ - NPError err = NPERR_NO_ERROR; - switch (aVariable) { - case NPPVpluginNameString: - *((char **)aValue) = (char *) "Osmozilla"; - break; - case NPPVpluginDescriptionString: - *((char **)aValue) = (char *) "GPAC Plugin " GPAC_FULL_VERSION " for Mozilla. For more information go to GPAC website"; - break; - default: - err = NPERR_INVALID_PARAM; - break; - } - return err; -} - -///////////////////////////////////////////////////////////// -// -// construction and destruction of our plugin instance object -// -nsPluginInstanceBase * NS_NewPluginInstance(nsPluginCreateData * aCreateDataStruct) -{ - if(!aCreateDataStruct) return NULL; - nsOsmozillaInstance * plugin = new nsOsmozillaInstance(aCreateDataStruct); - return plugin; -} - -void NS_DestroyPluginInstance(nsPluginInstanceBase * aPlugin) -{ - if(aPlugin) delete (nsOsmozillaInstance *)aPlugin; -} - -//////////////////////////////////////// -// -// nsOsmozillaInstance class implementation -// -nsOsmozillaInstance::nsOsmozillaInstance(nsPluginCreateData * aCreateDataStruct) : nsPluginInstanceBase(), - mInstance(aCreateDataStruct->instance) -{ -#ifdef XP_UNIX - mWindow = 0L; - mFontInfo = NULL; - mXtwidget = NULL; -#endif +#include "osmozilla.h" #ifdef XP_WIN - m_hWnd = NULL; +#include #endif - mScriptablePeer = NULL; - mInitialized = 0; - - - m_szURL = NULL; - m_term = NULL; - m_bIsConnected = 0; - - m_argc=aCreateDataStruct->argc; - m_argv=aCreateDataStruct->argv; - m_argn=aCreateDataStruct->argn; - - SetOptions(); -} - -void nsOsmozillaInstance::SetOptions() -{ - m_bLoop = 0; - m_bAutoStart = 1; - m_bUse3D = 0; - - /*options sent from plugin*/ - for(int i=0;i +#include +#include - /*URL is not absolute, request new stream to mozilla - we don't pass absolute URLs since some may not be - handled by gecko */ - if (m_szURL) { - Bool absolute_url = 0; - if (strstr(m_szURL, "://")) absolute_url = 1; - else if (m_szURL[0] == '/') { - FILE *test = gf_f64_open(m_szURL, "rb"); - if (test) { - absolute_url = 1; - fclose(test); - } - } - else if ((m_szURL[1] == ':') && ((m_szURL[2] == '\\') || (m_szURL[2] == '/'))) absolute_url = 1; - if (!absolute_url) { - char *url = m_szURL; - m_szURL = NULL; - NPN_GetURL(mInstance, url, NULL); - gf_free(url); - } - } +short Osmozilla_GetURL(NPP instance, const char *url, const char *target); +void Osmozilla_SetStatus(NPP instance, const char *message); -} -nsOsmozillaInstance::~nsOsmozillaInstance() +void Osmozilla_Shutdown(Osmozilla *osmo) { - if (mInstance) { - mInstance->pdata = NULL; - mInstance = NULL; + if (osmo->url) gf_free(osmo->url); + osmo->url = NULL; + if (osmo->term) { + GF_Terminal *a_term = osmo->term; + osmo->term = NULL; + gf_term_del(a_term); } - mInitialized = FALSE; - if (mScriptablePeer != NULL) { - mScriptablePeer->SetInstance(NULL); - NS_IF_RELEASE(mScriptablePeer); - } + if (osmo->user->modules) gf_modules_del(osmo->user->modules); + if (osmo->user->config) gf_cfg_del(osmo->user->config); + gf_free(osmo->user); + osmo->user = NULL; } static void osmozilla_do_log(void *cbk, u32 level, u32 tool, const char *fmt, va_list list) @@ -269,201 +59,12 @@ static void osmozilla_do_log(void *cbk, u32 level, u32 tool, const char *fmt, va fflush(logs); } -NPBool nsOsmozillaInstance::init(NPWindow* aWindow) -{ - FILE *ft; - char config_path[GF_MAX_PATH], config_test_file[GF_MAX_PATH]; - char *gpac_cfg; - const char *str; - - if(aWindow == NULL) return FALSE; - -#ifdef XP_WIN - gpac_cfg = (char *)"GPAC.cfg"; - - HKEY hKey = NULL; - DWORD dwSize; - /*locate the key in current user, then in local machine*/ - if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\GPAC", 0, KEY_READ, &hKey) != ERROR_SUCCESS) - RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\GPAC", 0, KEY_READ, &hKey); - dwSize = GF_MAX_PATH; -#ifdef _DEBUG - if (RegQueryValueEx(hKey, "DebugDir", NULL, NULL,(unsigned char*) config_path, &dwSize) != ERROR_SUCCESS) -#endif - RegQueryValueEx(hKey, "InstallDir", NULL, NULL,(unsigned char*) config_path, &dwSize); - RegCloseKey(hKey); - - /*do we have write access?*/ - strcpy(config_test_file, config_path); - if (config_path[strlen(config_path)-1] != '\\') - strcat(config_test_file, "\\"); - assert(strlen(config_path)+strlen(gpac_cfg)+1term) return 0; switch (evt->type) { case GF_EVENT_MESSAGE: @@ -473,61 +74,48 @@ Bool nsOsmozillaInstance::EventProc(GF_Event *evt) else sprintf((char *)msg, "GPAC: %s", evt->message.message); - NPN_Status(mInstance, msg); + Osmozilla_SetStatus(osmo->np_instance, msg); break; case GF_EVENT_PROGRESS: if (evt->progress.done == evt->progress.total) { - NPN_Status(mInstance, ""); + Osmozilla_SetStatus(osmo->np_instance, ""); } else { char *szTitle = (char *)""; if (evt->progress.progress_type==0) szTitle = (char *)"Buffer "; else if (evt->progress.progress_type==1) szTitle = (char *)"Download "; else if (evt->progress.progress_type==2) szTitle = (char *)"Import "; sprintf(msg, "(GPAC) %s: %02.2f", szTitle, (100.0*evt->progress.done) / evt->progress.total); - NPN_Status(mInstance, msg); + Osmozilla_SetStatus(osmo->np_instance, msg); } break; - /*IGNORE any scene size, just work with the size allocated in the parent doc*/ + /*IGNORE any scene size, just work with the size allocated in the parent doc*/ case GF_EVENT_SCENE_SIZE: - gf_term_set_size(m_term, m_width, m_height); + gf_term_set_size(osmo->term, osmo->width, osmo->height); break; - /*window has been resized (full-screen plugin), resize*/ + /*window has been resized (full-screen plugin), resize*/ case GF_EVENT_SIZE: - m_width = evt->size.width; - m_height = evt->size.height; - gf_term_set_size(m_term, m_width, m_height); + osmo->width = evt->size.width; + osmo->height = evt->size.height; + gf_term_set_size(osmo->term, osmo->width, osmo->height); break; case GF_EVENT_CONNECT: - m_bIsConnected = evt->connect.is_connected; + osmo->is_connected = evt->connect.is_connected; break; case GF_EVENT_DURATION: - m_bCanSeek = evt->duration.can_seek; - m_Duration = evt->duration.duration; + osmo->can_seek = evt->duration.can_seek; + osmo->duration = evt->duration.duration; break; case GF_EVENT_DBLCLICK: - gf_term_set_option(m_term, GF_OPT_FULLSCREEN, !gf_term_get_option(m_term, GF_OPT_FULLSCREEN)); + gf_term_set_option(osmo->term, GF_OPT_FULLSCREEN, !gf_term_get_option(osmo->term, GF_OPT_FULLSCREEN)); break; - case GF_EVENT_KEYDOWN: - if ((evt->key.flags & GF_KEY_MOD_ALT)) { - } else { - switch (evt->key.key_code) { - case GF_KEY_HOME: - gf_term_set_option(m_term, GF_OPT_NAVIGATION_TYPE, 1); - break; -/* case GF_KEY_ESCAPE: - gf_term_set_option(m_term, GF_OPT_FULLSCREEN, !gf_term_get_option(m_term, GF_OPT_FULLSCREEN)); - break; -*/ } - } - break; case GF_EVENT_NAVIGATE_INFO: strcpy(msg, evt->navigate.to_url); - NPN_Status(mInstance, msg); + Osmozilla_SetStatus(osmo->np_instance, msg); break; case GF_EVENT_NAVIGATE: - if (gf_term_is_supported_url(m_term, evt->navigate.to_url, 1, m_disable_mime)) { - gf_term_navigate_to(m_term, evt->navigate.to_url); + if (gf_term_is_supported_url(osmo->term, evt->navigate.to_url, 1, osmo->disable_mime)) { + gf_term_navigate_to(osmo->term, evt->navigate.to_url); return 1; } else { u32 i; @@ -540,7 +128,7 @@ Bool nsOsmozillaInstance::EventProc(GF_Event *evt) else if (!strcmp(evt->navigate.parameters[i], "_new")) target = (char *)"_new"; else if (!strnicmp(evt->navigate.parameters[i], "_target=", 8)) target = (char *) evt->navigate.parameters[i]+8; } - NPN_GetURL(mInstance, evt->navigate.to_url, target); + Osmozilla_GetURL(osmo->np_instance, evt->navigate.to_url, target); return 1; } break; @@ -548,205 +136,283 @@ Bool nsOsmozillaInstance::EventProc(GF_Event *evt) return 0; } -Bool Osmozilla_EventProc(void *priv, GF_Event *evt) +int Osmozilla_Initialize(Osmozilla *osmo, signed short argc, char* argn[], char* argv[]) { - nsOsmozillaInstance *gpac = (nsOsmozillaInstance *) priv; - return gpac->EventProc(evt); -} + const char *str; + int i; + u32 log_level, log_tools; -NPError nsOsmozillaInstance::SetWindow(NPWindow* aWindow) -{ - const char *gui; - if (mInitialized) { - m_width = aWindow->width; - m_height = aWindow->height; - if (m_bIsConnected) gf_term_set_size(m_term, m_width, m_height); - return TRUE; + osmo->auto_start = 1; + + /*options sent from plugin*/ + for(i=0;iauto_start = 0; + + else if (!stricmp(argn[i],"src") ) { + if (osmo->url) gf_free(osmo->url); + osmo->url = gf_strdup(argv[i]); + } + else if (!stricmp(argn[i],"use3d") && (!stricmp(argv[i], "true") || !stricmp(argv[i], "yes") ) ) { + osmo->use_3d = 1; + } + else if (!stricmp(argn[i],"loop") && (!stricmp(argv[i], "true") || !stricmp(argv[i], "yes") ) ) { + osmo->loop = 1; + } + else if (!stricmp(argn[i],"aspectratio")) { + osmo->aspect_ratio = GF_ASPECT_RATIO_KEEP; + if (!stricmp(argv[i], "keep")) osmo->aspect_ratio = GF_ASPECT_RATIO_KEEP; + else if (!stricmp(argv[i], "16:9")) osmo->aspect_ratio = GF_ASPECT_RATIO_16_9; + else if (!stricmp(argv[i], "4:3")) osmo->aspect_ratio = GF_ASPECT_RATIO_4_3; + else if (!stricmp(argv[i], "fill")) osmo->aspect_ratio = GF_ASPECT_RATIO_FILL_SCREEN; + } } - - if(aWindow == NULL) return FALSE; - if (!aWindow->width || !aWindow->height) return FALSE; - m_width = aWindow->width; - m_height = aWindow->height; + /*URL is not absolute, request new stream to mozilla - we don't pass absolute URLs since some may not be + handled by gecko */ + if (osmo->url) { + Bool absolute_url = 0; + if (strstr(osmo->url, "://")) absolute_url = 1; + else if (osmo->url[0] == '/') { + FILE *test = gf_f64_open(osmo->url, "rb"); + if (test) { + absolute_url = 1; + fclose(test); + } + } + else if ((osmo->url[1] == ':') && ((osmo->url[2] == '\\') || (osmo->url[2] == '/'))) absolute_url = 1; - m_user.EventProc = Osmozilla_EventProc; - -#ifdef XP_WIN - m_user.os_window_handler = aWindow->window; + if (!absolute_url) { + char *url = osmo->url; + osmo->url = NULL; + Osmozilla_GetURL(osmo->np_instance, url, NULL); + gf_free(url); + } + } + + GF_SAFEALLOC(osmo->user, GF_User); + osmo->user->config = gf_cfg_init(NULL, NULL); + /*need to have a valid cfg file for now*/ + if (!osmo->user->config) { + gf_free(osmo->user); + osmo->user = NULL; +#ifdef WIN32 + MessageBox(NULL, "GPAC CONFIGURATION FILE NOT FOUND OR INVALID", "OSMOZILLA FATAL ERROR", MB_OK); +#else + fprintf(stdout, "OSMOZILLA FATAL ERROR\nGPAC CONFIGURATION FILE NOT FOUND OR INVALID\n"); #endif + return 0; + } -#ifdef XP_UNIX - m_user.os_window_handler = aWindow->window; - /*HACK - although we don't use the display in the X11 plugin, this is used to signal that - the user is mozilla and prevent some X11 calls crashing the browser in file playing mode - (eg, "firefox myfile.mp4" )*/ - m_user.os_display =((NPSetWindowCallbackStruct *)aWindow->ws_info)->display; - XSynchronize((Display *) m_user.os_display, True); - m_user.os_window_handler = aWindow->window; + str = gf_cfg_get_key(osmo->user->config, "General", "ModulesDirectory"); + osmo->user->modules = gf_modules_new(str, osmo->user->config); + if (!gf_modules_get_count(osmo->user->modules)) { + if (osmo->user->modules) gf_modules_del(osmo->user->modules); + gf_free(osmo->user); + osmo->user = NULL; +#ifdef WIN32 + MessageBox(NULL, "GPAC MODULES NOT FOUND", "OSMOZILLA FATAL ERROR", MB_OK); +#else + fprintf(stdout, "OSMOZILLA FATAL ERROR\nGPAC MODULES NOT FOUND\n"); #endif + return 0; + } + + osmo->user->opaque = osmo; + osmo->user->EventProc = Osmozilla_EventProc; + + /*always fetch mime ? Check with anchor examples*/ + osmo->disable_mime = 0; + str = gf_cfg_get_key(osmo->user->config, "General", "NoMIMETypeFetch"); + if (str && !strcmp(str, "yes")) osmo->disable_mime = 0; + /*check log file*/ + str = gf_cfg_get_key(osmo->user->config, "General", "LogFile"); + if (str) { + osmo->logs = gf_f64_open(str, "wt"); + if (osmo->logs) gf_log_set_callback(osmo->logs, osmozilla_do_log); + } + + /*setup logs*/ + log_level = gf_log_parse_level(gf_cfg_get_key(osmo->user->config, "General", "LogLevel")); + if (!log_level) + fprintf(stdout, "Osmozilla: invalid log level specified\n"); + gf_log_set_level(log_level); + log_tools = gf_log_parse_tools(gf_cfg_get_key(osmo->user->config, "General", "LogTools")); + if (!log_tools) + fprintf(stdout, "Osmozilla: invalid log tools specified\n"); + gf_log_set_tools(log_tools); + + fprintf(stdout, "Osmozilla initialized\n"); + + return 1; +} + +int Osmozilla_SetWindow(Osmozilla *osmo, void *os_wnd_handle, void *os_wnd_display, unsigned int width, unsigned int height) +{ + const char *gui; + if (osmo->window_set) { + osmo->width = width; + osmo->height = height; + if (osmo->is_connected) gf_term_set_size(osmo->term, osmo->width, osmo->height); + return 1; + } + if (!os_wnd_handle) return 0; + + osmo->width = width; + osmo->height = height; + + osmo->user->os_window_handler = os_wnd_handle; + osmo->user->os_display = os_wnd_display; - m_prev_time = 0; - m_url_changed = 0; - - m_term = gf_term_new(&m_user); - if (! m_term) return FALSE; + /*Everything is now setup, create the terminal*/ + fprintf(stdout, "Creating Osmozilla terminal\n"); + osmo->term = gf_term_new(osmo->user); + if (!osmo->term) return 0; + fprintf(stdout, "Osmozilla terminal created\n"); - gf_term_set_option(m_term, GF_OPT_ASPECT_RATIO, aspect_ratio); - mInitialized = TRUE; + gf_term_set_option(osmo->term, GF_OPT_ASPECT_RATIO, osmo->aspect_ratio); + osmo->window_set = 1; #ifdef XP_WIN - SetFocus((HWND)aWindow->window); + SetFocus((HWND)os_wnd_handle); #endif /*stream not ready*/ - if (!m_szURL || !m_bAutoStart) return TRUE; + if (!osmo->url || !osmo->auto_start) { + fprintf(stdout, "Osmozilla ready - not connecting to %s yet\n", osmo->url); + return 1; + } /*connect from 0 and pause if not autoplay*/ - gui = gf_cfg_get_key(m_user.config, "General", "StartupFile"); + gui = gf_cfg_get_key(osmo->user->config, "General", "StartupFile"); if (gui) { - gf_cfg_set_key(m_user.config, "Temp", "BrowserMode", "yes"); - gf_cfg_set_key(m_user.config, "Temp", "GUIStartupFile", m_szURL); - gf_term_connect(m_term, gui); + gf_cfg_set_key(osmo->user->config, "Temp", "BrowserMode", "yes"); + gf_cfg_set_key(osmo->user->config, "Temp", "GUIStartupFile", osmo->url); + gf_term_connect(osmo->term, gui); } else { - gf_term_connect(m_term, m_szURL); + gf_term_connect(osmo->term, osmo->url); } - - return TRUE; + fprintf(stdout, "Osmozilla connected to %s\n", osmo->url); + return 1; } +char *Osmozilla_GetVersion() +{ + return (char *) "GPAC Plugin " GPAC_FULL_VERSION " for NPAPI compatible Web Browsers. For more information go to GPAC website"; +} - -NPError nsOsmozillaInstance::NewStream(NPMIMEType type, NPStream * stream, - NPBool seekable, uint16 * stype) +void Osmozilla_ConnectTo(Osmozilla *osmo, const char *url) { - if (m_szURL) gf_free(m_szURL); - m_szURL = gf_strdup((const char *)stream->url); + fprintf(stdout, "Osmozilla connecting to %s\n", url); + if (osmo->url) gf_free(osmo->url); + osmo->url = gf_strdup(url); /*connect from 0 and pause if not autoplay*/ - if (m_bAutoStart) { - const char *gui = gf_cfg_get_key(m_user.config, "General", "StartupFile"); + if (osmo->auto_start) { + const char *gui = gf_cfg_get_key(osmo->user->config, "General", "StartupFile"); if (gui) { - gf_cfg_set_key(m_user.config, "Temp", "BrowserMode", "yes"); - gf_cfg_set_key(m_user.config, "Temp", "GUIStartupFile", m_szURL); - gf_term_connect(m_term, gui); + gf_cfg_set_key(osmo->user->config, "Temp", "BrowserMode", "yes"); + gf_cfg_set_key(osmo->user->config, "Temp", "GUIStartupFile", url); + gf_term_connect(osmo->term, gui); } else { - gf_term_connect(m_term, m_szURL); + gf_term_connect(osmo->term, url); } } - - /*we handle data fetching ourselves*/ - *stype = NP_SEEK; - return NPERR_NO_ERROR; + fprintf(stdout, "Osmozilla connected to %s\n", url); } -NPError nsOsmozillaInstance::DestroyStream(NPStream * stream, NPError reason) +void Osmozilla_Pause(Osmozilla *osmo) { - if (0 && m_szURL) { - gf_term_disconnect(m_term); - gf_free(m_szURL); - m_szURL = NULL; - } - return NPERR_NO_ERROR; -} - -uint16 nsOsmozillaInstance::HandleEvent(void* event) -{ - fprintf(stdout, "event !\n"); - return false; -} - -void nsOsmozillaInstance::Pause() -{ -fprintf(stdout, "pause\n"); - if (m_term) { - if (gf_term_get_option(m_term, GF_OPT_PLAY_STATE) == GF_STATE_PAUSED) { - gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); + if (osmo->term) { + if (gf_term_get_option(osmo->term, GF_OPT_PLAY_STATE) == GF_STATE_PAUSED) { + gf_term_set_option(osmo->term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); } else { - gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED); + gf_term_set_option(osmo->term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED); } } } -void nsOsmozillaInstance::Play() +void Osmozilla_Play(Osmozilla *osmo) { - if (!m_bIsConnected) { - if (m_szURL) gf_term_connect(m_term, (const char *) m_szURL); + if (!osmo->is_connected) { + if (osmo->url) gf_term_connect(osmo->term, (const char *) osmo->url); } else { - gf_term_set_option(m_term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); + gf_term_set_option(osmo->term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); } } -void nsOsmozillaInstance::Stop() +void Osmozilla_Stop(Osmozilla *osmo) { - gf_term_disconnect(m_term); + if (osmo->term) gf_term_disconnect(osmo->term); } #ifdef XP_WIN PBITMAPINFO CreateBitmapInfoStruct(GF_VideoSurface *pfb) { - PBITMAPINFO pbmi; - WORD cClrBits; + PBITMAPINFO pbmi; + WORD cClrBits; cClrBits = 32; - pbmi = (PBITMAPINFO) LocalAlloc(LPTR, - sizeof(BITMAPINFOHEADER)); + pbmi = (PBITMAPINFO) LocalAlloc(LPTR, + sizeof(BITMAPINFOHEADER)); - pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbmi->bmiHeader.biWidth = pfb->width; pbmi->bmiHeader.biHeight = 1; - pbmi->bmiHeader.biPlanes = 1; - pbmi->bmiHeader.biBitCount = cClrBits; - - pbmi->bmiHeader.biCompression = BI_RGB; - pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8 - * pbmi->bmiHeader.biHeight; - pbmi->bmiHeader.biClrImportant = 0; - return pbmi; + pbmi->bmiHeader.biPlanes = 1; + pbmi->bmiHeader.biBitCount = cClrBits; + + pbmi->bmiHeader.biCompression = BI_RGB; + pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8 + * pbmi->bmiHeader.biHeight; + pbmi->bmiHeader.biClrImportant = 0; + return pbmi; } #endif -void nsOsmozillaInstance::Print(NPPrint* printInfo) +void Osmozilla_Print(Osmozilla *osmo, unsigned int is_embed, void *os_print_dc, unsigned int target_x, unsigned int target_y, unsigned int target_width, unsigned int target_height) { - if (printInfo->mode == NP_EMBED) - { - NPEmbedPrint *ep = (NPEmbedPrint *)printInfo; + if (is_embed) { #ifdef XP_MACOS /* - ep->platformPrint contains a THPrint reference on MacOS + os_print_dc contains a THPrint reference on MacOS */ - } + } #endif // XP_MACOS #ifdef XP_UNIX - /* - ep->platformPrint contains a NPPrintCallbackStruct on Unix and - the plug-in location and size in the NPWindow are in page coordinates (720/ inch), but the printer requires point coordinates (72/inch) - */ + /* + os_print_dc contains a NPPrintCallbackStruct on Unix and + the plug-in location and size in the NPWindow are in page coordinates (720/ inch), but the printer requires point coordinates (72/inch) + */ #endif // XP_UNIX #ifdef XP_WIN - /* - The coordinates for the window rectangle are in TWIPS format. - This means that you need to convert the x-y coordinates using the Windows API call DPtoLP when you output text - */ - HDC pDC = (HDC)printInfo->print.embedPrint.platformPrint; - GF_VideoSurface fb; - u32 xsrc, ysrc; - u16 src_16; - char *src; - /*lock the source buffer */ - gf_term_get_screen_buffer(m_term, &fb); - BITMAPINFO *infoSrc = CreateBitmapInfoStruct(&fb); - float deltay = (float)printInfo->print.embedPrint.window.height/(float)fb.height; - int ysuiv = 0; - char *ligne = (char *) LocalAlloc(GMEM_FIXED, fb.width*4); - for (ysrc=0; ysrcterm, &fb); + infoSrc = CreateBitmapInfoStruct(&fb); + deltay = (float)target_height/(float)fb.height; + ligne = (char *) LocalAlloc(GMEM_FIXED, fb.width*4); + for (ysrc=0; ysrc>5; src+=2; break; - } - dst += 4; } - int ycrt = ysuiv; - ysuiv = (u32) ( ((float)ysrc+1.0)*deltay); - int delta = ysuiv-ycrt; - StretchDIBits( - pDC, printInfo->print.embedPrint.window.x, ycrt+printInfo->print.embedPrint.window.y, printInfo->print.embedPrint.window.width, - delta, - 0, 0, fb.width, 1, - ligne, infoSrc, DIB_RGB_COLORS, SRCCOPY); + dst += 4; } + ycrt = ysuiv; + ysuiv = (u32) ( ((float)ysrc+1.0)*deltay); + delta = ysuiv-ycrt; + StretchDIBits( + pDC, target_x, target_y, target_width, + delta, + 0, 0, fb.width, 1, + ligne, infoSrc, DIB_RGB_COLORS, SRCCOPY); + } - /*unlock GPAC frame buffer */ - gf_term_release_screen_buffer(m_term, &fb); - /* gf_free temporary objects */ - GlobalFree(ligne); - LocalFree(infoSrc); + /*unlock GPAC frame buffer */ + gf_term_release_screen_buffer(osmo->term, &fb); + /* gf_free temporary objects */ + GlobalFree(ligne); + LocalFree(infoSrc); #endif // XP_WIN - } else if (printInfo->mode == NP_FULL) - { - NPFullPrint *ep = (NPFullPrint *)printInfo; - // TODO present the print dialog and manage the print - } + + return; +} + +/*TODO - this is full print, present the print dialog and manage the print*/ } -void nsOsmozillaInstance::Update(const char *type, const char *commands) +void Osmozilla_Update(Osmozilla *osmo, const char *type, const char *commands) { - if (m_term) { - GF_Err e = gf_term_scene_update(m_term, (char *) type, (char *) commands); + if (osmo->term) { + GF_Err e = gf_term_scene_update(osmo->term, (char *) type, (char *) commands); if (e) { char szMsg[1024]; sprintf((char *)szMsg, "GPAC: Error applying update (%s)", gf_error_to_string(e) ); - NPN_Status(mInstance, szMsg); + Osmozilla_SetStatus(osmo->np_instance, szMsg); } } } - -// Scriptability related code - -nsOsmozillaPeer *nsOsmozillaInstance::getScriptablePeer() -{ -fprintf(stdout, "get peer\n"); - if (!mScriptablePeer) { - mScriptablePeer = new nsOsmozillaPeer(this); - if (!mScriptablePeer) return NULL; - NS_ADDREF(mScriptablePeer); - } - NS_ADDREF(mScriptablePeer); - return mScriptablePeer; -} - -static NS_DEFINE_IID(kIZillaPluginIID, NS_IOSMOZILLA_IID); -static NS_DEFINE_IID(kIClassInfoIID, NS_ICLASSINFO_IID); -static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); - -nsOsmozillaPeer::nsOsmozillaPeer(nsOsmozillaInstance * aPlugin) -{ - mPlugin=aPlugin; - mRefCnt = 0; -} - -nsOsmozillaPeer::~nsOsmozillaPeer() -{ -} - // Notice that we expose our claim to implement nsIClassInfo. -//NS_IMPL_ISUPPORTS2(nsOsmozillaPeer, nsITestPlugin, nsIClassInfo) - - // the following method will be callable from JavaScript -NS_IMETHODIMP nsOsmozillaPeer::Pause() { mPlugin->Pause(); return NS_OK; } -NS_IMETHODIMP nsOsmozillaPeer::Play() { mPlugin->Play(); return NS_OK; } -NS_IMETHODIMP nsOsmozillaPeer::Stop() { mPlugin->Stop(); return NS_OK; } - -NS_IMETHODIMP nsOsmozillaPeer::Update(const char *type, const char *commands) -{ - mPlugin->Update(type, commands); - return NS_OK; -} - -void nsOsmozillaPeer::SetInstance(nsOsmozillaInstance * plugin) -{ - mPlugin = plugin; -} - -NS_IMETHODIMP_(nsrefcnt) nsOsmozillaPeer::AddRef() -{ - ++mRefCnt; - return mRefCnt; -} - -NS_IMETHODIMP_(nsrefcnt) nsOsmozillaPeer::Release() -{ - --mRefCnt; - if (mRefCnt == 0) { - delete this; - return 0; - } - return mRefCnt; -} - -// here nsOsmozillaPeer should return three interfaces it can be asked for by their iid's -// static casts are necessary to ensure that correct pointer is returned -NS_IMETHODIMP nsOsmozillaPeer::QueryInterface(const nsIID & aIID, - void **aInstancePtr) -{ - if (!aInstancePtr) - return NS_ERROR_NULL_POINTER; - - if (aIID.Equals(kIZillaPluginIID)) { - *aInstancePtr = NS_STATIC_CAST(nsIOsmozilla *, this); - AddRef(); - return NS_OK; - } - - if (aIID.Equals(kIClassInfoIID)) { - *aInstancePtr = NS_STATIC_CAST(nsIClassInfo *, this); - AddRef(); - return NS_OK; - } - - if (aIID.Equals(kISupportsIID)) { - *aInstancePtr = NS_STATIC_CAST(nsISupports *, (NS_STATIC_CAST (nsIOsmozilla *, this))); - AddRef(); - return NS_OK; - } - return NS_NOINTERFACE; -} - diff --git a/applications/osmozilla/osmozilla.h b/applications/osmozilla/osmozilla.h index d00619b..5929d97 100644 --- a/applications/osmozilla/osmozilla.h +++ b/applications/osmozilla/osmozilla.h @@ -1,241 +1,71 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: NPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Netscape Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the NPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the NPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef __PLUGIN_H__ -#define __PLUGIN_H__ - -#include - -#include "npplat.h" -#include "nsIOsmozilla.h" - -#include - -#ifndef WIN32 -#include -#include -#include -#endif - -class nsOsmozillaPeer; - -struct nsPluginCreateData -{ - NPP instance; - NPMIMEType type; - uint16 mode; - int16 argc; - char** argn; - char** argv; - NPSavedData* saved; -}; - -class nsPluginInstanceBase +/* +* GPAC - Multimedia Framework C SDK +* +* Copyright (c) ENST 2000-200X +* All rights reserved +* +* This file is part of GPAC / Osmozilla NPAPI plugin +* +* 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. +* +*/ + +#ifndef __OSMOZILLA_H__ +#define __OSMOZILLA_H__ + + +/*DO NOT INCLUDE ANY GPAC FILE IN THIS HEADER, IT CAUSES TYPE REDEFINITION CONFLICT ON OSX*/ +typedef struct _tag_terminal GF_Terminal; +typedef struct _tag_user GF_User; + +#include + + +typedef struct _NPP *NPP; + +typedef struct __tag_osmozilla { -public: - // these three methods must be implemented in the derived - // class platform specific way - virtual NPBool init(NPWindow* aWindow) = 0; - virtual void shut() = 0; - virtual NPBool isInitialized() = 0; - - // implement all or part of those methods in the derived - // class as needed - virtual NPError SetWindow(NPWindow* pNPWindow) { return NPERR_NO_ERROR; } - virtual NPError NewStream(NPMIMEType type, NPStream* stream, - NPBool seekable, uint16* stype) { return NPERR_NO_ERROR; } - virtual NPError DestroyStream(NPStream *stream, NPError reason) { return NPERR_NO_ERROR; } - virtual void StreamAsFile(NPStream* stream, const char* fname) { return; } - virtual int32 WriteReady(NPStream *stream) { return 0x0fffffff; } - virtual int32 Write(NPStream *stream, int32 offset, - int32 len, void *buffer) { return len; } - virtual void Print(NPPrint* printInfo) { return; } - virtual uint16 HandleEvent(void* event) { return 0; } - virtual void URLNotify(const char* url, NPReason reason, - void* notifyData) { return; } - virtual NPError GetValue(NPPVariable variable, void *value) { return NPERR_NO_ERROR; } - virtual NPError SetValue(NPNVariable variable, void *value) { return NPERR_NO_ERROR; } -}; - -// functions that should be implemented for each specific plugin - -// creation and destruction of the object of the derived class -nsPluginInstanceBase * NS_NewPluginInstance(nsPluginCreateData * aCreateDataStruct); -void NS_DestroyPluginInstance(nsPluginInstanceBase * aPlugin); - -// global plugin initialization and shutdown -NPError NS_PluginInitialize(); -void NS_PluginShutdown(); - -// global to get plugins name & description -NPError NS_PluginGetValue(NPPVariable aVariable, void *aValue); -char* NPP_GetMIMEDescription(void); - - -//#define NO_GPAC - -class nsOsmozillaInstance : public nsPluginInstanceBase -{ -public: - - nsOsmozillaInstance(nsPluginCreateData * aCreateDataStruct); - virtual ~nsOsmozillaInstance(); - - NPBool init(NPWindow* aWindow); - void shut(); - NPBool isInitialized() {return mInitialized;} + /*plugiun & window info*/ + NPP np_instance; + int window_set; + unsigned int height, width; - - NPError SetWindow(NPWindow* aWindow); - NPError NewStream(NPMIMEType type, NPStream * stream, NPBool seekable,uint16 * stype); - NPError DestroyStream(NPStream * stream, NPError reason); - NPError GetValue(NPPVariable aVariable, void *aValue); - virtual uint16 HandleEvent(void* event); - - - nsOsmozillaPeer * getScriptablePeer(); - - // locals - const char * getVersion(); - - int m_argc; - char **m_argv; - char **m_argn; - nsOsmozillaPeer *mScriptablePeer; - - void Pause(); - void Play(); - void Stop(); - void Update(const char *type, const char *commands); - void Print(NPPrint* printInfo); - Bool EventProc(GF_Event *evt); - - -private: - NPP mInstance; - NPBool mInitialized; - -#ifdef XP_WIN - HWND m_hWnd; -#endif -#ifdef XP_UNIX - Window mWindow; - Display *mDisplay; - XFontStruct *mFontInfo; - Widget mXtwidget; -#endif - -#ifdef XP_MACOSX - NPWindow *window; -#endif + /*GPAC term*/ + GF_User *user; + GF_Terminal *term; /*general options*/ - Bool m_bLoop, m_bAutoStart, m_bIsConnected; - - GF_Terminal *m_term; - GF_User m_user; - - char *m_szURL; - - Bool m_isopen, m_paused, m_url_changed, m_bUse3D, m_disable_mime; - u32 max_duration, m_log_level, m_log_tools, aspect_ratio; - FILE *m_logs; - Bool m_bCanSeek; - Double m_Duration; - uint32 m_height, m_width; - unsigned char *m_navigate_url; - u32 current_time_ms, m_prev_time; - Float current_FPS; - - void SetOptions(); -}; - -// We must implement nsIClassInfo because it signals the - // Mozilla Security Manager to allow calls from JavaScript. - // helper class to implement all necessary nsIClassInfo method stubs - // and to set flags used by the security system - -class nsClassInfoMixin : public nsIClassInfo - { - // These flags are used by the DOM and security systems to signal that - // JavaScript callers are allowed to call this object's scritable methods. - NS_IMETHOD GetFlags(PRUint32 *aFlags) - {*aFlags = nsIClassInfo::PLUGIN_OBJECT | nsIClassInfo::DOM_OBJECT; - return NS_OK;} - - NS_IMETHOD GetImplementationLanguage(PRUint32 *aImplementationLanguage) - {*aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; - return NS_OK;} - - // The rest of the methods can safely return error codes... - NS_IMETHOD GetInterfaces(PRUint32 *count, nsIID * **array) - {return NS_ERROR_NOT_IMPLEMENTED;} - NS_IMETHOD GetHelperForLanguage(PRUint32 language, nsISupports **_retval) - {return NS_ERROR_NOT_IMPLEMENTED;} - NS_IMETHOD GetContractID(char * *aContractID) - {return NS_ERROR_NOT_IMPLEMENTED;} - NS_IMETHOD GetClassDescription(char * *aClassDescription) - {return NS_ERROR_NOT_IMPLEMENTED;} - NS_IMETHOD GetClassID(nsCID * *aClassID) - {return NS_ERROR_NOT_IMPLEMENTED;} - NS_IMETHOD GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) - {return NS_ERROR_NOT_IMPLEMENTED;} - }; - + char loop, auto_start, is_connected, use_3d, disable_mime; + unsigned int aspect_ratio; + + /*the URL we are connected to*/ + char *url; + /*timing info of current url*/ + double duration; + char can_seek; + + /*log file if any*/ + FILE *logs; + +#ifdef GECKO_XPCOM + void *scriptable_peer; +#else + struct NPObject *script_obj; +#endif -class nsOsmozillaPeer : public nsIOsmozilla , public nsClassInfoMixin -{ -public: - nsOsmozillaPeer(nsOsmozillaInstance * aPlugin); - virtual ~nsOsmozillaPeer(); - - // methods from nsISupports - NS_IMETHOD QueryInterface(const nsIID & aIID, void **aInstancePtr); - NS_IMETHOD_(nsrefcnt) AddRef(); - NS_IMETHOD_(nsrefcnt) Release(); - -public: - NS_DECL_NSIOSMOZILLA - void SetInstance(nsOsmozillaInstance * plugin); - -protected: - nsrefcnt mRefCnt; - nsOsmozillaInstance * mPlugin; -}; +} Osmozilla; -#endif // __PLUGIN_H__ +#endif // __OSMOZILLA_H__ diff --git a/applications/osmozilla/osmozilla.rc b/applications/osmozilla/osmozilla.rc index 18be328..9fc460b 100644 --- a/applications/osmozilla/osmozilla.rc +++ b/applications/osmozilla/osmozilla.rc @@ -9,6 +9,10 @@ // #include "winresrc.h" +/*do not include setup.h*/ +#define _GF_SETUP_H_ +#include + ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS @@ -28,8 +32,8 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,1 - PRODUCTVERSION 1,0,0,1 + FILEVERSION 1,0,1,0 + PRODUCTVERSION 1,0,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -49,7 +53,7 @@ BEGIN VALUE "FileDescription", "Osmozilla allows playback of many media and rich media files. For more information, visit gpac.sourceforge.net\0" VALUE "FileExtents", "*|aac|wrl,wrl.gz|x3dv,x3dv.gz,x3dvz|x3d,x3d.gz,x3dz|svg,svg.gz,svgz|mpg,mpeg,mp2,mpa,mpe,mpv2|asf,wma,wmv,asx,asr|avi|mp4,mpg4|mp4|m4a|3gp,3gpp|3gp,3gpp|3g2,3gp2|3g2,3gp2|mp2,mp3,mpga,mpega|ogg|sdp\0" VALUE "FileOpenName", "GPAC Plugin|AAC Music|VRML World|X3D/VRML World|X3D/XML World|SVG Document|MPEG Video|WindowsMedia Movies|AVI Movies|MPEG-4 Videos|MPEG-4 Movies|MPEG-4 Music|3GPP Movies|3GPP Music|3GPP2 Movies|3GPP2 Music|MP3 Music|OGG Movies|SDP Session\0" - VALUE "FileVersion", "0.4.5\0" + VALUE "FileVersion", GPAC_VERSION"-rev"GPAC_SVN_REVISION"\0" VALUE "InternalName", "nposmozilla\0" VALUE "LegalCopyright", "Copyright © GPAC 2005-2007\0" VALUE "LegalTrademarks", "\0" @@ -57,7 +61,7 @@ BEGIN VALUE "OriginalFilename", "nposmozilla.dll\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "Osmozilla - GPAC Plugin for Mozilla\0" - VALUE "ProductVersion", "0.4.5\0" + VALUE "ProductVersion", GPAC_VERSION"-rev"GPAC_SVN_REVISION"\0" VALUE "SpecialBuild", "\0" END END diff --git a/applications/udptsseg/Makefile b/applications/udptsseg/Makefile index 776c1b9..f7f7bf2 100644 --- a/applications/udptsseg/Makefile +++ b/applications/udptsseg/Makefile @@ -1,81 +1,81 @@ -include ../../config.mak - -vpath %.c $(SRC_PATH)/applications/udptsseg - -CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include" - -ifeq ($(DEBUGBUILD), yes) -CFLAGS+=-g -LDFLAGS+=-g -endif - -ifeq ($(GPROFBUILD), yes) -CFLAGS+=-pg -LDFLAGS+=-pg -endif - -#common obj -OBJS= main.o - -LINKFLAGS=-L../../bin/gcc -L../../extra_lib/lib/gcc - -ifeq ($(CONFIG_WIN32),yes) -EXE=.exe -PROG=udptsseg$(EXE) -ifeq ($(MP4BOX_STATIC),yes) -LINKFLAGS+=-lgpac_static -lz $(EXTRALIBS) -else -LINKFLAGS+=-lgpac -endif -else -EXT= -PROG=udptsseg -ifeq ($(MP4BOX_STATIC),yes) -LINKFLAGS+=-lgpac_static -lz $(EXTRALIBS) -else -LINKFLAGS+=-lgpac -endif -endif - -#3 - spidermonkey support -ifeq ($(CONFIG_JS),no) -else -SCENEGRAPH_CFLAGS+=$(JS_FLAGS) -ifeq ($(CONFIG_JS),local) -NEED_LOCAL_LIB="yes" -endif -LINKFLAGS+=$(JS_LIBS) -endif - - -SRCS := $(OBJS:.o=.c) - -all: $(PROG) - -$(PROG): $(OBJS) - $(CC) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(LINKFLAGS) - - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< - - -clean: - rm -f $(OBJS) ../../bin/gcc/$(PROG) - -dep: depend - -depend: - rm -f .depend - $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend - -distclean: clean - rm -f Makefile.bak .depend - - - -# include dependency files if they exist -# -ifneq ($(wildcard .depend),) -include .depend -endif +include ../../config.mak + +vpath %.c $(SRC_PATH)/applications/udptsseg + +CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include" + +ifeq ($(DEBUGBUILD), yes) +CFLAGS+=-g +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD), yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + +#common obj +OBJS= main.o + +LINKFLAGS=-L../../bin/gcc -L../../extra_lib/lib/gcc + +ifeq ($(CONFIG_WIN32),yes) +EXE=.exe +PROG=udptsseg$(EXE) +ifeq ($(MP4BOX_STATIC),yes) +LINKFLAGS+=-lgpac_static -lz $(EXTRALIBS) +else +LINKFLAGS+=-lgpac +endif +else +EXT= +PROG=udptsseg +ifeq ($(MP4BOX_STATIC),yes) +LINKFLAGS+=-lgpac_static -lz $(EXTRALIBS) +else +LINKFLAGS+=-lgpac +endif +endif + +#3 - spidermonkey support +ifeq ($(CONFIG_JS),no) +else +SCENEGRAPH_CFLAGS+=$(JS_FLAGS) +ifeq ($(CONFIG_JS),local) +NEED_LOCAL_LIB="yes" +endif +LINKFLAGS+=$(JS_LIBS) +endif + + +SRCS := $(OBJS:.o=.c) + +all: $(PROG) + +$(PROG): $(OBJS) + $(CC) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(LINKFLAGS) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + + +clean: + rm -f $(OBJS) ../../bin/gcc/$(PROG) + +dep: depend + +depend: + rm -f .depend + $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend + +distclean: clean + rm -f Makefile.bak .depend + + + +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/applications/udptsseg/main.c b/applications/udptsseg/main.c index e2f472e..33ede4f 100644 --- a/applications/udptsseg/main.c +++ b/applications/udptsseg/main.c @@ -1,315 +1,315 @@ -/* -* GPAC - Multimedia Framework C SDK -* -* Copyright (c) ENST 2000-200X -* All rights reserved -* -* This file is part of GPAC / udp TS segmenter (udptsseg) application -* -* 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 -#include -#include -#include -#include - -#define UDP_BUFFER_SIZE 64484 - -/* adapted from http://svn.assembla.com/svn/legend/segmenter/segmenter.c */ -static GF_Err write_manifest(char *manifest, char *segment_dir, u32 segment_duration, char *segment_prefix, char *http_prefix, - u32 first_segment, u32 last_segment, Bool end) { - FILE *manifest_fp; - u32 i; - char manifest_tmp_name[GF_MAX_PATH]; - char manifest_name[GF_MAX_PATH]; - char *tmp_manifest = manifest_tmp_name; - - if (segment_dir) { - sprintf(manifest_tmp_name, "%stmp.m3u8", segment_dir); - sprintf(manifest_name, "%s%s", segment_dir, manifest); - } else { - sprintf(manifest_tmp_name, "tmp.m3u8"); - sprintf(manifest_name, "%s", manifest); - } - - manifest_fp = fopen(tmp_manifest, "w"); - if (!manifest_fp) { - fprintf(stderr, "Could not create m3u8 manifest file (%s)\n", tmp_manifest); - return GF_BAD_PARAM; - } - - fprintf(manifest_fp, "#EXTM3U\n#EXT-X-TARGETDURATION:%u\n#EXT-X-MEDIA-SEQUENCE:%u\n", segment_duration, first_segment); - - for (i = first_segment; i <= last_segment; i++) { - fprintf(manifest_fp, "#EXTINF:%u,\n%s%s_%u.ts\n", segment_duration, http_prefix, segment_prefix, i); - } - - if (end) { - fprintf(manifest_fp, "#EXT-X-ENDLIST\n"); - } - fclose(manifest_fp); - - if (!rename(tmp_manifest, manifest_name)) { - return GF_OK; - } else { - if (remove(manifest_name)) { - fprintf(stdout, "Error removing file %s\n", manifest_name); - return GF_IO_ERR; - } else if (rename(tmp_manifest, manifest_name)) { - fprintf(stderr, "Could not rename temporary m3u8 manifest file (%s) into %s\n", tmp_manifest, manifest_name); - return GF_IO_ERR; - } else { - return GF_OK; - } - } -} - -void usage() -{ - fprintf(stderr, "usage: udptsseg -src=UDP -dst-file=FILE -segment-duration=DUR -segment-dir=DIR -segment-manifest=M3U8 -segment-http-prefix=P -segment-number=N\n" - "-src=UDP udp://address:port providing the input transport stream\n" - "-dst-file=FILE e.g. out.ts, radical name of all segments\n" - "-segment-dir=DIR server local directory to store segments (with the trailing path separator)\n" - "-segment-duration=DUR segment duration in seconds\n" - "-segment-manifest=M3U8 m3u8 file basename\n" - "-segment-http-prefix=P client address for accessing server segments\n" - "-segment-number=N only n segments are used using a cyclic pattern\n" - "\n"); -} - -int main(int argc, char **argv) -{ - u32 i; - char *arg = NULL; - char *ts_in = NULL; - char *segment_dir = NULL; - char *segment_manifest = NULL; - char *segment_http_prefix = NULL; - u32 run_time = 0; - char *input_ip = NULL; - u32 input_port = 0; - GF_Socket *input_udp_sk = NULL; - char *input_buffer = NULL; - u32 input_buffer_size = UDP_BUFFER_SIZE; - GF_Err e = GF_OK; - FILE *ts_output_file = NULL; - char *ts_out = NULL; - char segment_prefix[GF_MAX_PATH]; - char segment_name[GF_MAX_PATH]; - u32 segment_duration = 0; - u32 segment_index = 0; - u32 segment_number = 0; - char segment_manifest_default[GF_MAX_PATH]; - u32 run = 1; - u32 last_segment_time = 0; - u32 last_segment_size = 0; - u32 read = 0; - u32 towrite = 0; - u32 leftinbuffer = 0; - - fprintf(stdout, "UDP Transport Stream Segmenter\n"); - - if (argc < 7) { - usage(); - return 0; - } - /*****************/ - /* gpac init */ - /*****************/ - gf_sys_init(0); - gf_log_set_level(GF_LOG_ERROR); - gf_log_set_tools(0xFFFFFFFF); - - /*****************/ - /* parsing of the arguments */ - /*****************/ - for (i = 1; i < (u32) argc ; i++) { - arg = argv[i]; - if (!strnicmp(arg, "-src=udp://",11)) { - char *sep; - arg+=11; - sep = strchr(arg+6, ':'); - if (sep) { - input_port = atoi(sep+1); - sep[0]=0; - input_ip = gf_strdup(arg); - sep[0]=':'; - } else { - input_ip = gf_strdup(arg); - } - - } else if (!strnicmp(arg, "-time=", 6)) { - run_time = atoi(arg+6); - } else if (!strnicmp(arg, "-dst-file=", 10)) { - ts_out = gf_strdup(arg+10); - } else if (!strnicmp(arg, "-segment-dir=", 13)) { - segment_dir = gf_strdup(arg+13); - } else if (!strnicmp(arg, "-segment-duration=", 18)) { - segment_duration = atoi(arg+18); - } else if (!strnicmp(arg, "-segment-manifest=", 18)) { - segment_manifest = gf_strdup(arg+18); - } else if (!strnicmp(arg, "-segment-http-prefix=", 21)) { - segment_http_prefix = gf_strdup(arg+21); - } else if (!strnicmp(arg, "-segment-number=", 16)) { - segment_number = atoi(arg+16); - } - } - fprintf(stdout, "Listening to TS input on %s:%d\n", input_ip, input_port); - fprintf(stdout, "Creating %d sec. segments in directory %s\n", segment_duration, segment_dir); - fprintf(stdout, "Creating %s manifest with %d segments\n", segment_manifest, segment_number); - - /*****************/ - /* creation of the input socket */ - /*****************/ - input_udp_sk = gf_sk_new(GF_SOCK_TYPE_UDP); - if (gf_sk_is_multicast_address((char *)input_ip)) { - e = gf_sk_setup_multicast(input_udp_sk, (char *)input_ip, input_port, 32, 0, NULL); - } else { - e = gf_sk_bind(input_udp_sk, NULL, input_port, (char *)input_ip, input_port, GF_SOCK_REUSE_PORT); - } - if (e) { - fprintf(stdout, "Error initializing UDP socket for %s:%d : %s\n", input_ip, input_port, gf_error_to_string(e)); - goto exit; - } - gf_sk_set_buffer_size(input_udp_sk, 0, UDP_BUFFER_SIZE); - gf_sk_set_block_mode(input_udp_sk, 1); - - /*****************/ - /* Initialisation of the TS and Manifest files */ - /*****************/ - - if (segment_duration) { - char *dot; - strcpy(segment_prefix, ts_out); - dot = strrchr(segment_prefix, '.'); - dot[0] = 0; - if (segment_dir) { - if (strchr("\\/", segment_name[strlen(segment_name)-1])) { - sprintf(segment_name, "%s%s_%d.ts", segment_dir, segment_prefix, segment_index); - } else { - sprintf(segment_name, "%s%c%s_%d.ts", segment_dir, GF_PATH_SEPARATOR, segment_prefix, segment_index); - } - } else { - sprintf(segment_name, "%s_%d.ts", segment_prefix, segment_index); - } - fprintf(stderr, "Processing %s segment\r", segment_name); - ts_out = gf_strdup(segment_name); - if (!segment_manifest) { - sprintf(segment_manifest_default, "%s.m3u8", segment_prefix); - segment_manifest = segment_manifest_default; - } - //write_manifest(segment_manifest, segment_dir, segment_duration, segment_prefix, segment_http_prefix, segment_index, 0, 0); - } - ts_output_file = fopen(ts_out, "wb"); - if (!ts_output_file) { - fprintf(stderr, "Error opening %s\n", ts_out); - goto exit; - } - - /*allocate data buffer*/ - input_buffer = (char*)gf_malloc(input_buffer_size); - assert(input_buffer); - - /*****************/ - /* main loop */ - /*****************/ - last_segment_time = gf_sys_clock(); - last_segment_size = 0; - while (run) { - /*check for some input from the network*/ - if (input_ip) { - gf_sk_receive(input_udp_sk, input_buffer+leftinbuffer, input_buffer_size-leftinbuffer, 0, &read); - leftinbuffer += read; - if (leftinbuffer) { - fprintf(stderr, "Processing %s segment ... received %d bytes (buffer: %d, segment: %d)\n", segment_name, read, leftinbuffer, last_segment_size); - if (input_buffer[0] != 0x47) { - u32 i = 0; - while (input_buffer[i] != 0x47 && i < leftinbuffer) i++; - fprintf(stderr, "Warning: data in buffer not starting with the MPEG-2 TS sync byte, skipping %d bytes of %d\n", i, leftinbuffer); - if (i < leftinbuffer) memmove(input_buffer, input_buffer+i, leftinbuffer-i); - leftinbuffer -=i; - } - if ((leftinbuffer % 188) != 0) { - fprintf(stderr, "Warning: data in buffer with a size (%d bytes) not multiple of 188 bytes\n", leftinbuffer); - towrite = leftinbuffer - (leftinbuffer % 188); - } else { - towrite = leftinbuffer; - } - } else { - towrite = 0; - } - /*write to current file */ - if (ts_output_file != NULL) { - u32 now = gf_sys_clock(); - if (towrite) { - fwrite(input_buffer, 1, towrite, ts_output_file); - if (towrite < leftinbuffer) { - fprintf(stderr, "Warning: wrote %d bytes, keeping %d bytes\n", towrite, (leftinbuffer-towrite)); - memmove(input_buffer, input_buffer+towrite, leftinbuffer-towrite); - } - leftinbuffer -= towrite; - last_segment_size += towrite; - } - if ((now - last_segment_time) > segment_duration*1000) { - last_segment_time = now; - fclose(ts_output_file); - fprintf(stderr, "Closing segment %s (%d bytes)\n", segment_name, last_segment_size); - last_segment_size = 0; - segment_index++; - if (segment_dir) { - if (strchr("\\/", segment_name[strlen(segment_name)-1])) { - sprintf(segment_name, "%s%s_%d.ts", segment_dir, segment_prefix, segment_index); - } else { - sprintf(segment_name, "%s%c%s_%d.ts", segment_dir, GF_PATH_SEPARATOR, segment_prefix, segment_index); - } - } else { - sprintf(segment_name, "%s_%d.ts", segment_prefix, segment_index); - } - ts_output_file = fopen(segment_name, "wb"); - if (!ts_output_file) { - fprintf(stderr, "Error opening segment %s\n", segment_name); - goto exit; - } - /* delete the oldest segment */ - if (segment_number && ((s32) (segment_index - segment_number - 1) >= 0)){ - char old_segment_name[GF_MAX_PATH]; - if (segment_dir) { - if (strchr("\\/", segment_name[strlen(segment_name)-1])) { - sprintf(old_segment_name, "%s%s_%d.ts", segment_dir, segment_prefix, segment_index - segment_number - 1); - } else { - sprintf(old_segment_name, "%s/%s_%d.ts", segment_dir, segment_prefix, segment_index - segment_number - 1); - } - } else { - sprintf(old_segment_name, "%s_%d.ts", segment_prefix, segment_index - segment_number - 1); - } - gf_delete_file(old_segment_name); - fprintf(stderr, "Deleting segment %s\n", old_segment_name); - } - write_manifest(segment_manifest, segment_dir, segment_duration, segment_prefix, segment_http_prefix, - // (segment_index >= segment_number/2 ? segment_index - segment_number/2 : 0), segment_index >1 ? segment_index-1 : 0, 0); - ( (segment_index > segment_number ) ? segment_index - segment_number : 0), segment_index >1 ? segment_index-1 : 0, 0); - } - } - - //} - } - /*cpu load regulation*/ - gf_sleep(1); - } -exit: - return 0; -} +/* +* GPAC - Multimedia Framework C SDK +* +* Copyright (c) ENST 2000-200X +* All rights reserved +* +* This file is part of GPAC / udp TS segmenter (udptsseg) application +* +* 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 +#include +#include +#include +#include + +#define UDP_BUFFER_SIZE 64484 + +/* adapted from http://svn.assembla.com/svn/legend/segmenter/segmenter.c */ +static GF_Err write_manifest(char *manifest, char *segment_dir, u32 segment_duration, char *segment_prefix, char *http_prefix, + u32 first_segment, u32 last_segment, Bool end) { + FILE *manifest_fp; + u32 i; + char manifest_tmp_name[GF_MAX_PATH]; + char manifest_name[GF_MAX_PATH]; + char *tmp_manifest = manifest_tmp_name; + + if (segment_dir) { + sprintf(manifest_tmp_name, "%stmp.m3u8", segment_dir); + sprintf(manifest_name, "%s%s", segment_dir, manifest); + } else { + sprintf(manifest_tmp_name, "tmp.m3u8"); + sprintf(manifest_name, "%s", manifest); + } + + manifest_fp = fopen(tmp_manifest, "w"); + if (!manifest_fp) { + fprintf(stderr, "Could not create m3u8 manifest file (%s)\n", tmp_manifest); + return GF_BAD_PARAM; + } + + fprintf(manifest_fp, "#EXTM3U\n#EXT-X-TARGETDURATION:%u\n#EXT-X-MEDIA-SEQUENCE:%u\n", segment_duration, first_segment); + + for (i = first_segment; i <= last_segment; i++) { + fprintf(manifest_fp, "#EXTINF:%u,\n%s%s_%u.ts\n", segment_duration, http_prefix, segment_prefix, i); + } + + if (end) { + fprintf(manifest_fp, "#EXT-X-ENDLIST\n"); + } + fclose(manifest_fp); + + if (!rename(tmp_manifest, manifest_name)) { + return GF_OK; + } else { + if (remove(manifest_name)) { + fprintf(stdout, "Error removing file %s\n", manifest_name); + return GF_IO_ERR; + } else if (rename(tmp_manifest, manifest_name)) { + fprintf(stderr, "Could not rename temporary m3u8 manifest file (%s) into %s\n", tmp_manifest, manifest_name); + return GF_IO_ERR; + } else { + return GF_OK; + } + } +} + +void usage() +{ + fprintf(stderr, "usage: udptsseg -src=UDP -dst-file=FILE -segment-duration=DUR -segment-dir=DIR -segment-manifest=M3U8 -segment-http-prefix=P -segment-number=N\n" + "-src=UDP udp://address:port providing the input transport stream\n" + "-dst-file=FILE e.g. out.ts, radical name of all segments\n" + "-segment-dir=DIR server local directory to store segments (with the trailing path separator)\n" + "-segment-duration=DUR segment duration in seconds\n" + "-segment-manifest=M3U8 m3u8 file basename\n" + "-segment-http-prefix=P client address for accessing server segments\n" + "-segment-number=N only n segments are used using a cyclic pattern\n" + "\n"); +} + +int main(int argc, char **argv) +{ + u32 i; + char *arg = NULL; + char *ts_in = NULL; + char *segment_dir = NULL; + char *segment_manifest = NULL; + char *segment_http_prefix = NULL; + u32 run_time = 0; + char *input_ip = NULL; + u32 input_port = 0; + GF_Socket *input_udp_sk = NULL; + char *input_buffer = NULL; + u32 input_buffer_size = UDP_BUFFER_SIZE; + GF_Err e = GF_OK; + FILE *ts_output_file = NULL; + char *ts_out = NULL; + char segment_prefix[GF_MAX_PATH]; + char segment_name[GF_MAX_PATH]; + u32 segment_duration = 0; + u32 segment_index = 0; + u32 segment_number = 0; + char segment_manifest_default[GF_MAX_PATH]; + u32 run = 1; + u32 last_segment_time = 0; + u32 last_segment_size = 0; + u32 read = 0; + u32 towrite = 0; + u32 leftinbuffer = 0; + + fprintf(stdout, "UDP Transport Stream Segmenter\n"); + + if (argc < 7) { + usage(); + return 0; + } + /*****************/ + /* gpac init */ + /*****************/ + gf_sys_init(0); + gf_log_set_level(GF_LOG_ERROR); + gf_log_set_tools(0xFFFFFFFF); + + /*****************/ + /* parsing of the arguments */ + /*****************/ + for (i = 1; i < (u32) argc ; i++) { + arg = argv[i]; + if (!strnicmp(arg, "-src=udp://",11)) { + char *sep; + arg+=11; + sep = strchr(arg+6, ':'); + if (sep) { + input_port = atoi(sep+1); + sep[0]=0; + input_ip = gf_strdup(arg); + sep[0]=':'; + } else { + input_ip = gf_strdup(arg); + } + + } else if (!strnicmp(arg, "-time=", 6)) { + run_time = atoi(arg+6); + } else if (!strnicmp(arg, "-dst-file=", 10)) { + ts_out = gf_strdup(arg+10); + } else if (!strnicmp(arg, "-segment-dir=", 13)) { + segment_dir = gf_strdup(arg+13); + } else if (!strnicmp(arg, "-segment-duration=", 18)) { + segment_duration = atoi(arg+18); + } else if (!strnicmp(arg, "-segment-manifest=", 18)) { + segment_manifest = gf_strdup(arg+18); + } else if (!strnicmp(arg, "-segment-http-prefix=", 21)) { + segment_http_prefix = gf_strdup(arg+21); + } else if (!strnicmp(arg, "-segment-number=", 16)) { + segment_number = atoi(arg+16); + } + } + fprintf(stdout, "Listening to TS input on %s:%d\n", input_ip, input_port); + fprintf(stdout, "Creating %d sec. segments in directory %s\n", segment_duration, segment_dir); + fprintf(stdout, "Creating %s manifest with %d segments\n", segment_manifest, segment_number); + + /*****************/ + /* creation of the input socket */ + /*****************/ + input_udp_sk = gf_sk_new(GF_SOCK_TYPE_UDP); + if (gf_sk_is_multicast_address((char *)input_ip)) { + e = gf_sk_setup_multicast(input_udp_sk, (char *)input_ip, input_port, 32, 0, NULL); + } else { + e = gf_sk_bind(input_udp_sk, NULL, input_port, (char *)input_ip, input_port, GF_SOCK_REUSE_PORT); + } + if (e) { + fprintf(stdout, "Error initializing UDP socket for %s:%d : %s\n", input_ip, input_port, gf_error_to_string(e)); + goto exit; + } + gf_sk_set_buffer_size(input_udp_sk, 0, UDP_BUFFER_SIZE); + gf_sk_set_block_mode(input_udp_sk, 1); + + /*****************/ + /* Initialisation of the TS and Manifest files */ + /*****************/ + + if (segment_duration) { + char *dot; + strcpy(segment_prefix, ts_out); + dot = strrchr(segment_prefix, '.'); + dot[0] = 0; + if (segment_dir) { + if (strchr("\\/", segment_name[strlen(segment_name)-1])) { + sprintf(segment_name, "%s%s_%d.ts", segment_dir, segment_prefix, segment_index); + } else { + sprintf(segment_name, "%s%c%s_%d.ts", segment_dir, GF_PATH_SEPARATOR, segment_prefix, segment_index); + } + } else { + sprintf(segment_name, "%s_%d.ts", segment_prefix, segment_index); + } + fprintf(stderr, "Processing %s segment\r", segment_name); + ts_out = gf_strdup(segment_name); + if (!segment_manifest) { + sprintf(segment_manifest_default, "%s.m3u8", segment_prefix); + segment_manifest = segment_manifest_default; + } + //write_manifest(segment_manifest, segment_dir, segment_duration, segment_prefix, segment_http_prefix, segment_index, 0, 0); + } + ts_output_file = fopen(ts_out, "wb"); + if (!ts_output_file) { + fprintf(stderr, "Error opening %s\n", ts_out); + goto exit; + } + + /*allocate data buffer*/ + input_buffer = (char*)gf_malloc(input_buffer_size); + assert(input_buffer); + + /*****************/ + /* main loop */ + /*****************/ + last_segment_time = gf_sys_clock(); + last_segment_size = 0; + while (run) { + /*check for some input from the network*/ + if (input_ip) { + gf_sk_receive(input_udp_sk, input_buffer+leftinbuffer, input_buffer_size-leftinbuffer, 0, &read); + leftinbuffer += read; + if (leftinbuffer) { + fprintf(stderr, "Processing %s segment ... received %d bytes (buffer: %d, segment: %d)\n", segment_name, read, leftinbuffer, last_segment_size); + if (input_buffer[0] != 0x47) { + u32 i = 0; + while (input_buffer[i] != 0x47 && i < leftinbuffer) i++; + fprintf(stderr, "Warning: data in buffer not starting with the MPEG-2 TS sync byte, skipping %d bytes of %d\n", i, leftinbuffer); + if (i < leftinbuffer) memmove(input_buffer, input_buffer+i, leftinbuffer-i); + leftinbuffer -=i; + } + if ((leftinbuffer % 188) != 0) { + fprintf(stderr, "Warning: data in buffer with a size (%d bytes) not multiple of 188 bytes\n", leftinbuffer); + towrite = leftinbuffer - (leftinbuffer % 188); + } else { + towrite = leftinbuffer; + } + } else { + towrite = 0; + } + /*write to current file */ + if (ts_output_file != NULL) { + u32 now = gf_sys_clock(); + if (towrite) { + fwrite(input_buffer, 1, towrite, ts_output_file); + if (towrite < leftinbuffer) { + fprintf(stderr, "Warning: wrote %d bytes, keeping %d bytes\n", towrite, (leftinbuffer-towrite)); + memmove(input_buffer, input_buffer+towrite, leftinbuffer-towrite); + } + leftinbuffer -= towrite; + last_segment_size += towrite; + } + if ((now - last_segment_time) > segment_duration*1000) { + last_segment_time = now; + fclose(ts_output_file); + fprintf(stderr, "Closing segment %s (%d bytes)\n", segment_name, last_segment_size); + last_segment_size = 0; + segment_index++; + if (segment_dir) { + if (strchr("\\/", segment_name[strlen(segment_name)-1])) { + sprintf(segment_name, "%s%s_%d.ts", segment_dir, segment_prefix, segment_index); + } else { + sprintf(segment_name, "%s%c%s_%d.ts", segment_dir, GF_PATH_SEPARATOR, segment_prefix, segment_index); + } + } else { + sprintf(segment_name, "%s_%d.ts", segment_prefix, segment_index); + } + ts_output_file = fopen(segment_name, "wb"); + if (!ts_output_file) { + fprintf(stderr, "Error opening segment %s\n", segment_name); + goto exit; + } + /* delete the oldest segment */ + if (segment_number && ((s32) (segment_index - segment_number - 1) >= 0)){ + char old_segment_name[GF_MAX_PATH]; + if (segment_dir) { + if (strchr("\\/", segment_name[strlen(segment_name)-1])) { + sprintf(old_segment_name, "%s%s_%d.ts", segment_dir, segment_prefix, segment_index - segment_number - 1); + } else { + sprintf(old_segment_name, "%s/%s_%d.ts", segment_dir, segment_prefix, segment_index - segment_number - 1); + } + } else { + sprintf(old_segment_name, "%s_%d.ts", segment_prefix, segment_index - segment_number - 1); + } + gf_delete_file(old_segment_name); + fprintf(stderr, "Deleting segment %s\n", old_segment_name); + } + write_manifest(segment_manifest, segment_dir, segment_duration, segment_prefix, segment_http_prefix, + // (segment_index >= segment_number/2 ? segment_index - segment_number/2 : 0), segment_index >1 ? segment_index-1 : 0, 0); + ( (segment_index > segment_number ) ? segment_index - segment_number : 0), segment_index >1 ? segment_index-1 : 0, 0); + } + } + + //} + } + /*cpu load regulation*/ + gf_sleep(1); + } +exit: + return 0; +} diff --git a/applications/v4studio/wxGPACPanel.cpp b/applications/v4studio/wxGPACPanel.cpp index a1ae41b..1e36858 100644 --- a/applications/v4studio/wxGPACPanel.cpp +++ b/applications/v4studio/wxGPACPanel.cpp @@ -246,97 +246,16 @@ bool GPACInit(void *application, GF_Terminal **term, GF_User *user, bool quiet) #endif /*load config*/ - user->config = gf_cfg_new(abs_gpac_path.c_str(), gpac_cfg); + Bool first_launch = 0; + user->config = gf_cfg_init(NULL, &first_launch); if (!user->config) { - unsigned char config_file[GF_MAX_PATH]; - strcpy((char *) config_file, (const char *) abs_gpac_path.c_str()); - if (config_file[strlen((char *) config_file)-1] != GF_PATH_SEPARATOR) { - char szSep[2]; - szSep[0] = GF_PATH_SEPARATOR; - szSep[1] = 0; - strcat((char *) config_file, (const char *)szSep); - } - strcat((char *) config_file, gpac_cfg); - FILE *ft = fopen((const char *) config_file, "wt"); - if (!ft) { - wxMessageDialog(NULL, "Cannot create blank config file", "Init error", wxOK).ShowModal(); - return 0; - } - fclose(ft); - user->config = gf_cfg_new(abs_gpac_path.c_str(), gpac_cfg); - if (!user->config) { - wxMessageDialog(NULL, "Cannot open GPAC configuration file", "Init error", wxOK); - return 0; - } + wxMessageDialog(NULL, "Cannot create GPAC config file", "Init error", wxOK).ShowModal(); } if (!quiet) ::wxLogMessage("GPAC configuration file opened - looking for modules"); const char *str = gf_cfg_get_key(user->config, "General", "ModulesDirectory"); - Bool first_launch = 0; - if (!str) { - first_launch = 1; -#ifdef GPAC_MODULES_PATH - str = GPAC_MODULES_PATH; -#else - str = abs_gpac_path.c_str(); -#endif - } user->modules = gf_modules_new(str, user->config); - /*initial launch*/ - if (first_launch || !gf_modules_get_count(user->modules)) { - const char *sOpt; - wxDirDialog dlg(NULL, "Locate GPAC modules directory"); - if (!gf_modules_get_count(user->modules)) { - gf_modules_del(user->modules); - user->modules = NULL; - if ( dlg.ShowModal() != wxID_OK ) return false; - str = dlg.GetPath().c_str();; - - user->modules = gf_modules_new(str, user->config); - if (!user->modules || !gf_modules_get_count(user->modules) ) { - wxMessageDialog(NULL, "Cannot find any modules for GPAC", "Init error", wxOK); - gf_cfg_del(user->config); - return 0; - } - } - - gf_cfg_set_key(user->config, "General", "ModulesDirectory", (const char *) str); - - /*check audio config on windows, force config*/ - sOpt = gf_cfg_get_key(user->config, "Audio", "ForceConfig"); - if (!sOpt) { - gf_cfg_set_key(user->config, "Audio", "ForceConfig", "yes"); - gf_cfg_set_key(user->config, "Audio", "NumBuffers", "2"); - gf_cfg_set_key(user->config, "Audio", "TotalDuration", "120"); - } - -#ifdef WIN32 - sOpt = gf_cfg_get_key(user->config, "Compositor", "Raster2D"); - if (!sOpt) gf_cfg_set_key(user->config, "Compositor", "Raster2D", "gdip_rend"); - sOpt = gf_cfg_get_key(user->config, "General", "CacheDirectory"); - if (!sOpt) { - unsigned char str_path[MAX_PATH]; - sprintf((char *) str_path, "%scache", abs_gpac_path.c_str()); - gf_cfg_set_key(user->config, "General", "CacheDirectory", (const char *) str_path); - } - /*by default use GDIplus, much faster than freetype on font loading*/ - gf_cfg_set_key(user->config, "FontEngine", "FontReader", "gdip_rend"); - gf_cfg_set_key(user->config, "Video", "DriverName", "DirectX Video Output"); -#else - wxDirDialog dlg3(NULL, "Please specify a cache directory for GPAC"); - dlg3.SetPath("/tmp"); - if ( dlg3.ShowModal() == wxID_OK ) - gf_cfg_set_key(user->config, "General", "CacheDirectory", (const char *) dlg3.GetPath().c_str() ); - - wxDirDialog dlg2(NULL, "Please locate a TrueType font repository on your system for text support"); - dlg2.SetPath("/usr/share/fonts/truetype"); - if ( dlg2.ShowModal() == wxID_OK ) - gf_cfg_set_key(user->config, "FontEngine", "FontDirectory", (const char *) dlg2.GetPath().c_str() ); - - gf_cfg_set_key(user->config, "Video", "DriverName", "SDL Video Output"); -#endif - } if (! gf_modules_get_count(user->modules) ) { wxMessageDialog(NULL, "No modules available - system cannot work", "Fatal Error", wxOK).ShowModal(); gf_modules_del(user->modules); diff --git a/bin/smartphone 2003 (armv4)/release/install/archive.bat b/bin/smartphone 2003 (armv4)/release/install/archive.bat new file mode 100644 index 0000000..acad9b7 --- /dev/null +++ b/bin/smartphone 2003 (armv4)/release/install/archive.bat @@ -0,0 +1,8 @@ +set OLDDIR=%CD% +cd /d %~dp0 + +for /f "delims=" %%a in ('svnversion ') do set gpac_revision=%%a + +zip "GPAC_0.4.6-r%gpac_revision%_WindowsMobile.zip" ../*.dll ../*.exe ../*.plg + +cd /d %OLDDIR% diff --git a/bin/smartphone 2003 (armv4)/release/install/build_installer.bat b/bin/smartphone 2003 (armv4)/release/install/build_installer.bat new file mode 100644 index 0000000..eb69935 --- /dev/null +++ b/bin/smartphone 2003 (armv4)/release/install/build_installer.bat @@ -0,0 +1,33 @@ +set OLDDIR=%CD% +cd /d %~dp0 + +for /f "delims=" %%a in ('svnversion') do set gpac_revision=%%a + +ECHO [Version] > gpaccab.inf +ECHO Provider = "GPAC 0.4.6-r%gpac_revision%" >> gpaccab.inf +type gpac.inf >> gpaccab.inf + +CabWiz gpaccab.inf + +ECHO off + +ECHO [CEAppManager]> gpac.ini +ECHO Version = 0.4.6-r%gpac_revision%>> gpac.ini +ECHO Component = GPAC for Windows Mobile>> gpac.ini +ECHO [GPAC for Windows Mobile]>> gpac.ini +ECHO Description = GPAC MPEG-4 Player>> gpac.ini +ECHO Uninstall = GPAC Osmophone>> gpac.ini +ECHO IconFile = ..\..\..\..\doc\osmo4.ico>> gpac.ini +ECHO IconIndex = 0 >> gpac.ini +ECHO CabFiles = gpaccab.cab >> gpac.ini + +ECHO on + +ezsetup -l english -i gpac.ini -r readme.txt -e ../../../../COPYING -o gpac.exe +rename gpac.exe "GPAC_0.4.6-r%gpac_revision%_WindowsMobile.exe" +DEL gpaccab.cab +DEL gpaccab.inf +DEL gpac.ini +DEL *.tmp + +cd /d %OLDDIR% diff --git a/bin/smartphone 2003 (armv4)/release/install/do.bat b/bin/smartphone 2003 (armv4)/release/install/do.bat deleted file mode 100644 index 838e486..0000000 --- a/bin/smartphone 2003 (armv4)/release/install/do.bat +++ /dev/null @@ -1,27 +0,0 @@ -for /f "delims=" %%a in ('svnversion') do set gpac_revision=%%a - -ECHO [Version] > gpaccab.inf -ECHO Provider = "GPAC 0.4.6-r%gpac_revision%" >> gpaccab.inf -type gpac.inf >> gpaccab.inf - -CabWiz gpaccab.inf - -ECHO off - -ECHO [CEAppManager]> gpac.ini -ECHO Version = 0.4.6-r%gpac_revision%>> gpac.ini -ECHO Component = GPAC for Windows Mobile>> gpac.ini -ECHO [GPAC for Windows Mobile]>> gpac.ini -ECHO Description = GPAC MPEG-4 Player>> gpac.ini -ECHO Uninstall = GPAC Osmophone>> gpac.ini -ECHO IconFile = ..\..\..\..\doc\osmo4.ico>> gpac.ini -ECHO IconIndex = 0 >> gpac.ini -ECHO CabFiles = gpaccab.cab >> gpac.ini - -ECHO on - -ezsetup -l english -i gpac.ini -r readme.txt -e ../../../../COPYING -o gpac.exe -rename gpac.exe "GPAC_0.4.6-r%gpac_revision%_WindowsMobile.exe" -DEL gpaccab.cab -DEL gpaccab.inf -DEL gpac.ini diff --git a/bin/smartphone 2003 (armv4)/release/install/gpac.inf b/bin/smartphone 2003 (armv4)/release/install/gpac.inf index 92802dc..e442453 100644 --- a/bin/smartphone 2003 (armv4)/release/install/gpac.inf +++ b/bin/smartphone 2003 (armv4)/release/install/gpac.inf @@ -38,7 +38,7 @@ msvcr80.dll = 1 libGLES_CM.dll = 1 ;comment this one if not using SpiderMonkey -js.dll = 1 +js32.dll = 1 ;uncomment if your device doesn't have GX installed (I think most do) ;gx.dll = 2 @@ -91,7 +91,7 @@ DefaultDestDir = 0, %InstallDir% ;"gx.dll" "libgpac.dll" "GPAX.dll" -"js.dll" +"js32.dll" "libGLES_CM.dll" "msvcr80.dll" diff --git a/bin/win32/release/nsis_install/gpac_installer.nsi b/bin/win32/release/nsis_install/gpac_installer.nsi index 31c2a75..128a87c 100644 --- a/bin/win32/release/nsis_install/gpac_installer.nsi +++ b/bin/win32/release/nsis_install/gpac_installer.nsi @@ -242,6 +242,9 @@ Section "Osmo4/GPAC Player" SecOsmo4 File "..\gm_dx_hw.dll" File "..\js32.dll" File "..\gm_gpac_js.dll" + File "..\libeay32.dll" + File "..\ssleay32.dll" + File "..\gm_ismacryp.dll" ;create default cache SetOutPath $INSTDIR\cache @@ -505,7 +508,9 @@ Section "Add Start Menu Shortcuts" SetShellVarContext all CreateDirectory "$SMPROGRAMS\Osmo4" CreateShortCut "$SMPROGRAMS\Osmo4\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 - CreateShortCut "$SMPROGRAMS\Osmo4\Osmo4.lnk" "$INSTDIR\Osmo4.exe" "" "$INSTDIR\Osmo4.exe" 0 + CreateShortCut "$SMPROGRAMS\Osmo4\Osmo4 (Classic UI).lnk" "$INSTDIR\Osmo4.exe" "" + CreateShortCut "$SMPROGRAMS\Osmo4\Osmo4 (New UI).lnk" "$INSTDIR\MP4Client.exe" "-gui" + CreateShortCut "$SMPROGRAMS\Osmo4\Osmo4 (New UI With Console).lnk" "$INSTDIR\MP4Client.exe" "" CreateShortCut "$SMPROGRAMS\Osmo4\Readme.lnk" "$INSTDIR\ReadMe.txt" CreateShortCut "$SMPROGRAMS\Osmo4\License.lnk" "$INSTDIR\License.txt" CreateShortCut "$SMPROGRAMS\Osmo4\History.lnk" "$INSTDIR\changelog.txt" diff --git a/bin/win32/release/nsis_install/readme.txt b/bin/win32/release/nsis_install/readme.txt index 962fbc8..379aa05 100644 --- a/bin/win32/release/nsis_install/readme.txt +++ b/bin/win32/release/nsis_install/readme.txt @@ -1,13 +1,13 @@ -GPAC: NSIS installer manual -========================== - -Recommended ------------ - -Please execute the "generate_installer.bat" file at the root GPAC directory. The revision and version will be retrieved. - - -Alternative (developers only) ------------------------------ - -Launching the NSIS installer the "bin\win32\release\nsis_install" will generate an unversion installer. The DATE/HOUR will be included in the installer file. Use it in case you're making some experimental developments. +GPAC: NSIS installer manual +========================== + +Recommended +----------- + +Please execute the "generate_installer.bat" file at the root GPAC directory. The revision and version will be retrieved. + + +Alternative (developers only) +----------------------------- + +Launching the NSIS installer the "bin\win32\release\nsis_install" will generate an unversion installer. The DATE/HOUR will be included in the installer file. Use it in case you're making some experimental developments. diff --git a/build/android/AndroidManifest.xml b/build/android/AndroidManifest.xml index 2243c8a..d17445e 100644 --- a/build/android/AndroidManifest.xml +++ b/build/android/AndroidManifest.xml @@ -1,6 +1,6 @@ diff --git a/build/android/README b/build/android/README new file mode 100644 index 0000000..b9ba225 --- /dev/null +++ b/build/android/README @@ -0,0 +1,73 @@ +********************************* +* How to build GPAC for Android * +********************************* + +To compile GPAC for Android, please execute the following steps: + +1) Check out the GPAC SVN repository (but if you read this you probably already checkouted the GPAC SVN repository): + + svn co https://gpac.svn.sourceforge.net/svnroot/gpac/trunk/ + This directory will be reminded as + +2) Get the Android softwares: + + A. Download the Android SDK at http://developer.android.com/sdk/index.html and unzip it at a place of your choice (referenced as ). + + B. Download the Android NDK at http://developer.android.com/sdk/ndk/index.html and unzip it at a place of your choice (referenced as ). + + C. One of the following tools i) or ii) are needed for building the Android Package (APK): + i) GPAC provides scripts to build the APK from the shell. No IDE is needed. Get ANT (at least the 1.8 version) from http://ant.apache.org/bindownload.cgi and install it at a place of your choice (referenced as ). + You will then ignore every step in this readme that follow the ii) mark (as it concerns only people using eclipse instead of ANT). + + ii) Eclipse IDE is useful if you want to go beyond the build (ie debug, add features, use the simulator etc). Firstly get Eclipse for java at http://www.eclipse.org/downloads/?osType=linux. + Then get the ADT (Android Development Tools) plug-in in order to allow Eclipse to interact with Android tools at http://developer.android.com/sdk/eclipse-adt.html and follow the instructions. + You will then ignore every step in this readme that follow the i) mark (as it concerns only people using ANT instead of Eclipse). + + D. Get and install SDK Component for Android: + + i) If you have ANT, launch /tools/android. This opens a window. On the left panel, click on "Available packages", select "Android Repository" and then "Install Selected". + + ii) If you have Eclipse Select Window->Preferences->Android and put the SDK directory path. Then select Window > Android SDK and AVD Managergo get the packages (Android repository packages are needed. The third party ones depend on the target devices. More informations at http://developer.android.com/sdk/adding-components.html. + +3) Compile extra-libs for android + + A. Build all extra-libs + + Go to /trunk/gpac_extra_libs. Unzip the zipped package : + unzip gpac_extra_libs.zip + Go to /trunk/gpac_extra_libs/build/android. Give you the right to execute the script gpac_build_all_extra_libs (e.g. chmod u+x gpac_build_all_extra_libs ). + Run the script as follow : ./gpac_build_all_extra_libs + + B. Copy all the compiled extra lib to the right folder + + Go back to /trunk/gpac_extra_libs/ . + Copy the just compiled libs into /trunk/gpac/extra_lib/lib/android by entering this command : + cp -r lib/android/* ../gpac/extra_lib/lib/android/ + +4) Building GPAC for Android + + (optionnal) Links the Android SDK and NDK directories + + * cd /opt/ + * sudo ln -s /home/xxx/xxx/ android_sdk /* /opt/android_sdk will then become your new */ + * sudo ln -s /home/xxx/xxx/ android_ndk /* /opt/android_ndk will then become your new */ + + i) Building Osmo4.apk without Eclipse + + (optionnal)Create a link to the ANT directory + * cd /opt/ + * sudo ln -s /home/xxx/xxx/ANT_DIR ant /* /opt/ant will then cecome your new + + Then go to GPAC_DIR/build/android/jni and launch the script + ./gpac_build_android + It will generate the package Osmo4.apk. + You can find the Osmo4.apk in GPAC_DIR/applications/osmo4_android/bin + + ii)Building Osmo4.apk with Eclipse + + Go to GPAC_DIR/build/android/jni and launch the script + ./gpac_build_android + ** Warning, two messages will appear to alert you didnt provide any link to ANT and to the Android SDK . ** + ** These message inform you that the script can't build the Osmo4.apk package on it's own and that you'll need eclipse to build it.** + Start Eclipse and select File->Import->General->Existing projects into Workspace and open the directory /applications/osmo4_android. + Build the package and it is created in /applications/osmo4_android/bin. diff --git a/build/android/gen/com/artemis/gpac/R.java b/build/android/gen/com/artemis/gpac/R.java deleted file mode 100644 index 597d21d..0000000 --- a/build/android/gen/com/artemis/gpac/R.java +++ /dev/null @@ -1,23 +0,0 @@ -/* AUTO-GENERATED FILE. DO NOT MODIFY. - * - * This class was automatically generated by the - * aapt tool from the resource data it found. It - * should not be modified by hand. - */ - -package com.artemis.gpac; - -public final class R { - public static final class attr { - } - public static final class drawable { - public static final int icon=0x7f020000; - } - public static final class layout { - public static final int main=0x7f030000; - } - public static final class string { - public static final int app_name=0x7f040001; - public static final int hello=0x7f040000; - } -} diff --git a/build/android/gen/com/enst/gpac/R.java b/build/android/gen/com/enst/gpac/R.java new file mode 100644 index 0000000..a280408 --- /dev/null +++ b/build/android/gen/com/enst/gpac/R.java @@ -0,0 +1,23 @@ +/* AUTO-GENERATED FILE. DO NOT MODIFY. + * + * This class was automatically generated by the + * aapt tool from the resource data it found. It + * should not be modified by hand. + */ + +package com.enst.gpac; + +public final class R { + public static final class attr { + } + public static final class drawable { + public static final int icon=0x7f020000; + } + public static final class layout { + public static final int main=0x7f030000; + } + public static final class string { + public static final int app_name=0x7f040001; + public static final int hello=0x7f040000; + } +} diff --git a/build/android/jni/Android.mk b/build/android/jni/Android.mk index 5053e7d..d2696ed 100755 --- a/build/android/jni/Android.mk +++ b/build/android/jni/Android.mk @@ -1 +1,3 @@ include $(call all-subdir-makefiles) + + diff --git a/build/android/jni/Application.mk b/build/android/jni/Application.mk index 4663f2f..e0f29c1 100644 --- a/build/android/jni/Application.mk +++ b/build/android/jni/Application.mk @@ -1,4 +1,4 @@ APP_ABI := armeabi armeabi-v7a -APP_OPTIM := release +APP_OPTIM := debug APP_MODULES := gpac gm_bifs_dec gm_ctx_load gm_dummy_in gm_ft_font gm_img_in gm_ismacryp gm_isom_in gm_laser_dec gm_odf_dec gm_rtp_in gm_saf_in gm_soft_raster gm_svg_in gm_timedtext libjavaenv gm_droidout gm_droidaudio gm_gpac_js gm_mp3_in gm_ffmpeg_in gm_mpegts_in gm_aac_in gm_mpd_in gm_widgetman gpacWrapper diff --git a/build/android/jni/common.mk b/build/android/jni/common.mk index 6279823..483cd5a 100644 --- a/build/android/jni/common.mk +++ b/build/android/jni/common.mk @@ -1,4 +1,4 @@ -COMMON_PATH := $(call my-dir) +OMMON_PATH := $(call my-dir) #Settings common to all JNI Builds TARGET_PLATFORM := android-4 diff --git a/build/android/jni/gpac_build_android b/build/android/jni/gpac_build_android index ee1539d..c7e88aa 100755 --- a/build/android/jni/gpac_build_android +++ b/build/android/jni/gpac_build_android @@ -1,7 +1,6 @@ -#!/bin/bash +#!/bin/bash -e -echo -e "\033[32m Note: You have to install Android NDK and setup the environment first!\033[0m" -echo -e "\033[32m Note: You have to compile extra_libs first!\033[0m" +echo -e "\033[32m If you have problem using this script, read the README in trunk/gpac/build/android \033[0m" if [ -z "$1" ] then @@ -9,36 +8,57 @@ then exit 1 fi +if [ -z "$2" ] +then + echo -e "\033[34m Usage: $0 PATH_TO_ANDROID_SDK : You have not give the directory path of SDK. Auto build of Osmo4.apk not possible. Build it with Eclipse \033[0m" +fi + +if [ -z "$3" ] +then + echo -e "\033[34m Usage: $0 PATH_TO_ANT : You have not give the directory path of ANT. Auto build of Osmo4.apk not possible. Build it with Eclipse \033[0m" +fi + export PATH="$1:$PATH" + +if [ ! -z "$3" ] && [ ! -z "$2" ] +then +export PATH="$2/tools:$3/bin:$PATH" +shift 3 +ANT=1 +else +ANT=0 shift +fi # Be sure to resolve if script not called from its directory export BUILDPATH=$(dirname "$0") -cd $BUILDPATH || exit 1 +cd $BUILDPATH export BUILDPATH=$(pwd) echo "Current Dir = $BUILDPATH" -version=$(svnversion) +version=$(svnversion ../../..) echo "*** Build path is $BUILDPATH, setting revision number $version" -grep "$version" ../../../include/gpac/version.h 1>/dev/null && echo "Version $version already set" || echo "#define GPAC_SVN_REVISION \"$version\"" > ../../../include/gpac/version.h || exit 1 +if grep "$version" ../../../include/gpac/version.h >/dev/null 2>&1 ; then + echo "Version $version already set" +else + echo "#define GPAC_SVN_REVISION \"$version\"" > ../../../include/gpac/version.h +fi echo "Building lib gpac ..." -mkdir ../../../bin/android 2>/dev/null -cd ../../../ || exit 1 +cd ../../../ BASEPATH=$(pwd) -rm -rf $BUILDPATH/../obj/local/armeabi/* || mkdir $BUILDPATH/../obj/local/armeabi -rm -rf $BUILDPATH/../obj/local/armeabi-v7a/* || mkdir $BUILDPATH/../obj/local/armeabi-v7a +#rm -rf $BUILDPATH/../obj/* - -cd $BUILDPATH || exit 1 +cd $BUILDPATH echo -n "Buiding all libs from $BUILDPATH..." -ndk-build $* && echo "[OK] build successful." || echo "Build FAILED" || exit 1 +ndk-build +echo "[OK] build successful." #echo "Copying modules to modules dir..." -cd ../libs/ || exit 1 +cd ../libs/ #for i in $(find . -name 'gm*.so') #do # echo -n "$i..." -# cp "$i" "$BASEPATH/applications/osmo4_android/res/raw/" || exit 1 +# cp "$i" "$BASEPATH/applications/osmo4_android/res/raw/" #done #echo #echo "[OK] success." @@ -47,16 +67,56 @@ LIBS_DIR="$BASEPATH/applications/osmo4_android/libs/" echo "Copying libs to libs dir $LIBS_DIR ..." for i in $(find . -name '*.so') do - echo -n "$i..." - cp "$i" "$LIBS_DIR/$i" || exit 1 + echo -n " Copy $i" + cp "$i" "$LIBS_DIR/$i" +done +echo +echo "[OK] success module for Osmo4." + + +LIBS_DIR="$BASEPATH/applications/mp4box_android/libs/" +echo "Copying libs to libs dir $LIBS_DIR ..." +for i in $(find . \( -name '*.so' \) -a \( -name "*ft2*" -o -name "*edit*" -o -name "*libgpac.so*" -o -name "*jpeg*" -o -name "*js_osmo*" -o -name "*mp4box*" -o -name "*openjpeg*" -o -name "*png*" -o -name "*libz.*" \) ) +do +echo " Copy $i" +cp "$i" "$LIBS_DIR/$i" done echo -echo "[OK] success." -cd "$BASEPATH/extra_lib/lib/android" || exit 1 +echo "[OK] success module for MP4box." + + +LIBS_DIR="$BASEPATH/applications/osmo4_android/libs/" +cd "$BASEPATH/extra_lib/lib/android" echo "Copying all extra libs to $LIBS_DIR ..." for i in $(find . -name '*.so') do - echo -n "$i..." - cp "$i" "$LIBS_DIR/$i" || exit 1 +echo " Copy $i" +cp "$i" "$LIBS_DIR/$i" +done +echo "[OK] success extra lib for Osmo4." + +LIBS_DIR="$BASEPATH/applications/mp4box_android/libs/" +cd "$BASEPATH/extra_lib/lib/android" +echo "Copying all extra libs to $LIBS_DIR ..." + +for i in $(find . \( -name '*.so' \) -a \( -name "*ft2*" -o -name "*edit*" -o -name "*libgpac.so*" -o -name "*jpeg*" -o -name "*js_osmo*" -o -name "*mp4box*" -o -name "*openjpeg*" -o -name "*png*" -o -name "*libz.*" \) ) +do +echo " Copy $i" +cp "$i" "$LIBS_DIR/$i" done -echo "[OK] success." +echo "[OK] success extra lib MP4box." + +if [ $ANT -eq 1 ] +then +echo "\nSelf-updating project" +android update project -p "$BASEPATH/applications/osmo4_android/" + +echo -e "\nBuiding Osmo4.apk" +cd $BASEPATH/applications/osmo4_android/ +ant release + +zipalign -v 4 bin/Osmo4-unaligned.apk $BASEPATH/Osmo4-$(grep "\#define GPAC_VERSION " $BASEPATH/include/gpac/tools.h | cut -d "\"" -f 2 )-r$version.apk +rm bin/Osmo4-* +echo -e "\n[OK] success." +fi + diff --git a/build/android/jni/libgpac/Android.mk b/build/android/jni/libgpac/Android.mk index 67f4816..8fd12c6 100755 --- a/build/android/jni/libgpac/Android.mk +++ b/build/android/jni/libgpac/Android.mk @@ -1,6 +1,3 @@ -#you should run gpac config first -#./configure --host=arm-eabi CC=arm-eabi-gcc CPPFLAGS="-I$NDK/build/platforms/android-3/arch-arm/usr/include/" CFLAGS="-nostdlib" LDFLAGS="-Wl,-rpath-link=$NDK/build/platforms/android-4/arch-arm/usr/lib/ -L$NDK/build/platforms/android-3/arch-arm/usr/lib/" LIBS="-lc " -#../../configure --host=arm-eabi CC=arm-eabi-gcc CPPFLAGS="-I$NDK/platforms/android-4/arch-arm/usr/include/" CFLAGS="-nostdlib" LDFLAGS="-Wl,-rpath-link=$NDK/platforms/android-4/arch-arm/usr/lib/ -L$NDK/platforms/android-4/arch-arm/usr/lib/" LIBS="-lc " LOCAL_PATH:= $(call my-dir) APP_ABI := armeabi armeabi-v7a @@ -15,13 +12,13 @@ LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/include LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/include/freetype LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/include/freetype/freetype -LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/include/jpeg/android/ +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/include/jpeg/ LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/include/png/ LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/include/faad LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/include/js/ LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../modules -LOCAL_LDLIBS += -L$(COMMON_PATH)/../../../extra_lib/lib/android/$(TARGET_ARCH_ABI) +LOCAL_LDLIBS += -L$(LOCAL_PATH)/../../../../extra_lib/lib/android/$(TARGET_ARCH_ABI) LOCAL_LDLIBS += -lGLESv1_CM -ldl LOCAL_LDLIBS += -ljs_osmo -leditline -lft2 -ljpeg -lopenjpeg -lpng -lz #LOCAL_EXPORT_LDLIBS= -ljs_osmo -leditline -lft2 -ljpeg -lopenjpeg -lpng -lz @@ -95,6 +92,7 @@ LOCAL_SRC_FILES := \ ../../../../src/compositor/hc_flash_shape.c \ ../../../../src/compositor/svg_filters.c \ ../../../../src/media_tools/avilib.c \ + ../../../../src/media_tools/dvb.c \ ../../../../src/media_tools/filestreamer.c \ ../../../../src/media_tools/isom_tools.c \ ../../../../src/media_tools/mpeg2_ps.c \ @@ -114,6 +112,7 @@ LOCAL_SRC_FILES := \ ../../../../src/media_tools/reedsolomon.c \ ../../../../src/media_tools/mpd.c \ ../../../../src/media_tools/m3u8.c \ + ../../../../src/media_tools/carousel.c \ ../../../../src/laser/lsr_tables.c \ ../../../../src/laser/lsr_dec.c \ ../../../../src/laser/lsr_enc.c \ diff --git a/build/android/jni/libgpac/config.h b/build/android/jni/libgpac/config.h index f263e5b..9d80511 100644 --- a/build/android/jni/libgpac/config.h +++ b/build/android/jni/libgpac/config.h @@ -1,7 +1,6 @@ /* Automatically generated by configure */ #ifndef GF_CONFIG_H #define GF_CONFIG_H -#define GPAC_CONFIGURATION "--host=arm-eabi CC=arm-eabi-gcc CPPFLAGS=-I/mci/artemis/arsov/tools/android/android-ndk-r5/build/platforms/android-3/arch-arm/usr/include/ CFLAGS=-nostdlib LDFLAGS='-Wl,-rpath-link=/mci/artemis/arsov/tools/android/android-ndk-r5/build/platforms/android-3/arch-arm/usr/lib/ -L/mci/artemis/arsov/tools/android/android-ndk-r5/build/platforms/android-3/arch-arm/usr/lib/' LIBS='-lc '" #define GPAC_CONFIG_LINUX 1 diff --git a/build/android/jni/modules/base.mk b/build/android/jni/modules/base.mk index c7f9d68..2f53ccc 100644 --- a/build/android/jni/modules/base.mk +++ b/build/android/jni/modules/base.mk @@ -1,4 +1,4 @@ -LOCAL_PATH := $(call my-dir) +OCAL_PATH := $(call my-dir) include $(LOCAL_PATH)/../common.mk LOCAL_C_INCLUDES := $(LOCAL_PATH) diff --git a/build/android/jni/modules/gm_ffmpeg_in.mk b/build/android/jni/modules/gm_ffmpeg_in.mk index 6e5c7b3..a0cce7c 100644 --- a/build/android/jni/modules/gm_ffmpeg_in.mk +++ b/build/android/jni/modules/gm_ffmpeg_in.mk @@ -6,15 +6,9 @@ LOCAL_MODULE := gm_ffmpeg_in include $(LOCAL_PATH)/base.mk -LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/android/ffmpeg/jni/ -#LOCAL_C_INCLUDES += /home/gacon/workspace/ffmpeg/jni/ +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/include/ffmpeg_android/ LOCAL_LDLIBS += -lffmpeg -#LOCAL_LDLIBS += -lavcodec -lavformat -lavutil -#LOCAL_STATIC_LIBRARIES := libavformat libavcodec libavutil libpostproc libswscale -#LOCAL_STATIC_LIBRARIES += libavformat -#LOCAL_STATIC_LIBRARIES += libavutil -#LOCAL_STATIC_LIBRARIES += libswscale LOCAL_SRC_FILES := ../../../../modules/ffmpeg_in/ffmpeg_load.c ../../../../modules/ffmpeg_in/ffmpeg_demux.c ../../../../modules/ffmpeg_in/ffmpeg_decode.c diff --git a/build/android/jni/modules/gm_ft_font.mk b/build/android/jni/modules/gm_ft_font.mk index ac4c141..d01b571 100644 --- a/build/android/jni/modules/gm_ft_font.mk +++ b/build/android/jni/modules/gm_ft_font.mk @@ -6,8 +6,7 @@ LOCAL_MODULE := gm_ft_font include $(LOCAL_PATH)/base.mk -LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/android/freetypedroid/jni/include -LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../../extra_lib/android/freetypedroid/jni/include/freetype +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/include/freetype LOCAL_SRC_FILES := ../../../../modules/ft_font/ft_font.c diff --git a/build/android/jni/modules/gm_gpac_js.mk b/build/android/jni/modules/gm_gpac_js.mk index 885704e..f0442da 100644 --- a/build/android/jni/modules/gm_gpac_js.mk +++ b/build/android/jni/modules/gm_gpac_js.mk @@ -6,10 +6,7 @@ LOCAL_MODULE := gm_gpac_js include $(LOCAL_PATH)/base.mk -LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/android/js/jni -LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/android/js/jni/Linux_All_DBG.OBJ -LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/android/js/jni/editline -#LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/include/js/ +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/include/js/ LOCAL_SRC_FILES := ../../../../modules/gpac_js/gpac_js.c diff --git a/build/android/jni/modules/gm_widgetman.mk b/build/android/jni/modules/gm_widgetman.mk index 7cd1a4b..e3e2fae 100644 --- a/build/android/jni/modules/gm_widgetman.mk +++ b/build/android/jni/modules/gm_widgetman.mk @@ -6,11 +6,7 @@ LOCAL_MODULE := gm_widgetman include $(LOCAL_PATH)/base.mk -LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/include/ -LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/android/zlibdroid/jni/ -LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/android/js/jni/ -LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/android/js/jni/Linux_All_DBG.OBJ -LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/android/js/jni/editline +LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../extra_lib/include/js/ LOCAL_SRC_FILES := ../../../../modules/widgetman/widgetman.c ../../../../modules/widgetman/unzip.c ../../../../modules/widgetman/widget.c ../../../../modules/widgetman/wgt_load.c diff --git a/build/android/jni/mp4box/Android.mk b/build/android/jni/mp4box/Android.mk new file mode 100644 index 0000000..dde0485 --- /dev/null +++ b/build/android/jni/mp4box/Android.mk @@ -0,0 +1,20 @@ +LOCAL_PATH := $(call my-dir) +APP_ABI := armeabi + + +LOCAL_MODULE := mp4box +LOCAL_MODULE_FILENAME := libmp4box + +LOCAL_C_INCLUDES := $(LOCAL_PATH)/../libgpac \ + $(LOCAL_PATH)/../../../../include + +LOCAL_LDLIBS += -L$(LOCAL_PATH)/../../libs/$(TARGET_ARCH_ABI) +LOCAL_LDLIBS += -lgpac -llog + +LOCAL_SRC_FILES := ../../../../applications/mp4box/filedump.c \ + ../../../../applications/mp4box/fileimport.c \ + ../../../../applications/mp4box/live.c \ + ../../../../applications/mp4box/main.c \ + ../../../../applications/mp4box/wrapper.c + +include $(BUILD_SHARED_LIBRARY) diff --git a/build/android/jni/mp4box/Application.mk b/build/android/jni/mp4box/Application.mk new file mode 100644 index 0000000..565356f --- /dev/null +++ b/build/android/jni/mp4box/Application.mk @@ -0,0 +1,4 @@ +LOCAL_PATH:= $(call my-dir) + +APP_ABI := armeabi armeabi-v7a +APP_MODULES := mp4box diff --git a/build/android/jni/wrapper/Android.mk b/build/android/jni/wrapper/Android.mk index 4df2694..68f74fd 100644 --- a/build/android/jni/wrapper/Android.mk +++ b/build/android/jni/wrapper/Android.mk @@ -1,4 +1,4 @@ -LOCAL_PATH:= $(call my-dir) +OCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) include $(LOCAL_PATH)/../common.mk diff --git a/build/android/src/com/artemis/gpac/gpac.java b/build/android/src/com/artemis/gpac/gpac.java deleted file mode 100644 index 6b4a8d4..0000000 --- a/build/android/src/com/artemis/gpac/gpac.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.artemis.gpac; - -import android.app.Activity; -import android.os.Bundle; - -public class gpac extends Activity { - /** Called when the activity is first created. */ - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.main); - } -} \ No newline at end of file diff --git a/build/android/src/com/enst/gpac/gpac.java b/build/android/src/com/enst/gpac/gpac.java new file mode 100644 index 0000000..2fee76d --- /dev/null +++ b/build/android/src/com/enst/gpac/gpac.java @@ -0,0 +1,13 @@ +package com.enst.gpac; + +import android.app.Activity; +import android.os.Bundle; + +public class gpac extends Activity { + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + } +} \ No newline at end of file diff --git a/build/msvc8/gpac.sln b/build/msvc8/gpac.sln index 6093655..6edff05 100644 --- a/build/msvc8/gpac.sln +++ b/build/msvc8/gpac.sln @@ -1,4 +1,3 @@ - Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp4client", "mp4client.vcproj", "{A35D99BF-D72D-4F56-99A1-97249B22BCE2}" @@ -80,7 +79,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp3_in", "mp3_in.vcproj", " EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp4box", "mp4box.vcproj", "{48E2C7C6-52EB-46FB-8722-00A62F46F497}" ProjectSection(ProjectDependencies) = postProject - {233014D5-F6E5-419D-8757-FA9CE7337088} = {233014D5-F6E5-419D-8757-FA9CE7337088} + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mpegts_in", "mpegts_in.vcproj", "{B38E812D-9823-48E7-BE5F-BF09B0AD4165}" @@ -228,370 +227,659 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GPAX", "GPAX.vcproj", "{724 {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hyb_in", "hyb_in.vcproj", "{41B1DAF0-D7ED-4934-B915-05DBB0EE6B0E}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 + Debug|Mixed Platforms = Debug|Mixed Platforms Debug|Smartphone 2003 (ARMV4) = Debug|Smartphone 2003 (ARMV4) + Debug|Win32 = Debug|Win32 + Release|Mixed Platforms = Release|Mixed Platforms Release|Smartphone 2003 (ARMV4) = Release|Smartphone 2003 (ARMV4) + Release|Win32 = Release|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Debug|Win32.Build.0 = Debug|Win32 - {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Debug|Win32.ActiveCfg = Debug|Win32 + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) - {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Release|Win32.Build.0 = Release|Win32 - {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Release|Win32.ActiveCfg = Release|Win32 + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Debug|Win32.ActiveCfg = Debug|Win32 + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Debug|Win32.Build.0 = Debug|Win32 + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Release|Win32.ActiveCfg = Release|Win32 + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Release|Win32.Build.0 = Release|Win32 + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {C79C2D73-06E9-4622-92CE-F166B1B51792}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {C79C2D73-06E9-4622-92CE-F166B1B51792}.Debug|Win32.ActiveCfg = Debug|Win32 {C79C2D73-06E9-4622-92CE-F166B1B51792}.Debug|Win32.Build.0 = Debug|Win32 + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {C79C2D73-06E9-4622-92CE-F166B1B51792}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {C79C2D73-06E9-4622-92CE-F166B1B51792}.Release|Win32.ActiveCfg = Release|Win32 {C79C2D73-06E9-4622-92CE-F166B1B51792}.Release|Win32.Build.0 = Release|Win32 - {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) - {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) - {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Win32.ActiveCfg = Debug|Win32 - {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Win32.Build.0 = Debug|Win32 - {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) - {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) - {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Win32.ActiveCfg = Release|Win32 - {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Win32.Build.0 = Release|Win32 + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Win32.ActiveCfg = Debug|Win32 {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Win32.Build.0 = Debug|Win32 + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Win32.ActiveCfg = Release|Win32 {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Win32.Build.0 = Release|Win32 + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Win32.ActiveCfg = Debug|Win32 {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Win32.Build.0 = Debug|Win32 + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Win32.ActiveCfg = Release|Win32 {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Win32.Build.0 = Release|Win32 + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Win32.ActiveCfg = Debug|Win32 {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Win32.Build.0 = Debug|Win32 + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Win32.ActiveCfg = Release|Win32 {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Win32.Build.0 = Release|Win32 + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Win32.ActiveCfg = Debug|Win32 {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Win32.Build.0 = Debug|Win32 + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Win32.ActiveCfg = Release|Win32 {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Win32.Build.0 = Release|Win32 + {B64736BD-9245-4F40-961D-EB9822265764}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {B64736BD-9245-4F40-961D-EB9822265764}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {B64736BD-9245-4F40-961D-EB9822265764}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {B64736BD-9245-4F40-961D-EB9822265764}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {B64736BD-9245-4F40-961D-EB9822265764}.Debug|Win32.ActiveCfg = Debug|Win32 {B64736BD-9245-4F40-961D-EB9822265764}.Debug|Win32.Build.0 = Debug|Win32 + {B64736BD-9245-4F40-961D-EB9822265764}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {B64736BD-9245-4F40-961D-EB9822265764}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {B64736BD-9245-4F40-961D-EB9822265764}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {B64736BD-9245-4F40-961D-EB9822265764}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {B64736BD-9245-4F40-961D-EB9822265764}.Release|Win32.ActiveCfg = Release|Win32 {B64736BD-9245-4F40-961D-EB9822265764}.Release|Win32.Build.0 = Release|Win32 + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Win32.ActiveCfg = Debug|Win32 {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Win32.Build.0 = Debug|Win32 + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Win32.ActiveCfg = Release|Win32 {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Win32.Build.0 = Release|Win32 + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Win32.ActiveCfg = Debug|Win32 {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Win32.Build.0 = Debug|Win32 + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Win32.ActiveCfg = Release|Win32 {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Win32.Build.0 = Release|Win32 + {CAA5A551-006A-4119-8115-FB14692E719F}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {CAA5A551-006A-4119-8115-FB14692E719F}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {CAA5A551-006A-4119-8115-FB14692E719F}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {CAA5A551-006A-4119-8115-FB14692E719F}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {CAA5A551-006A-4119-8115-FB14692E719F}.Debug|Win32.ActiveCfg = Debug|Win32 {CAA5A551-006A-4119-8115-FB14692E719F}.Debug|Win32.Build.0 = Debug|Win32 + {CAA5A551-006A-4119-8115-FB14692E719F}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {CAA5A551-006A-4119-8115-FB14692E719F}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {CAA5A551-006A-4119-8115-FB14692E719F}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {CAA5A551-006A-4119-8115-FB14692E719F}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {CAA5A551-006A-4119-8115-FB14692E719F}.Release|Win32.ActiveCfg = Release|Win32 {CAA5A551-006A-4119-8115-FB14692E719F}.Release|Win32.Build.0 = Release|Win32 + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Win32.ActiveCfg = Debug|Win32 {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Win32.Build.0 = Debug|Win32 + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Win32.ActiveCfg = Release|Win32 {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Win32.Build.0 = Release|Win32 + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Win32.ActiveCfg = Debug|Win32 {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Win32.Build.0 = Debug|Win32 + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Win32.ActiveCfg = Release|Win32 {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Win32.Build.0 = Release|Win32 + {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Win32.ActiveCfg = Debug|Win32 {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Win32.Build.0 = Debug|Win32 + {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Win32.ActiveCfg = Release|Win32 {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Win32.Build.0 = Release|Win32 + {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Win32.ActiveCfg = Debug|Win32 {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Win32.Build.0 = Debug|Win32 + {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Win32.ActiveCfg = Release|Win32 {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Win32.Build.0 = Release|Win32 + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Win32.ActiveCfg = Debug|Win32 {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Win32.Build.0 = Debug|Win32 + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Win32.ActiveCfg = Release|Win32 {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Win32.Build.0 = Release|Win32 + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Win32.ActiveCfg = Debug|Win32 {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Win32.Build.0 = Debug|Win32 + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Win32.ActiveCfg = Release|Win32 {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Win32.Build.0 = Release|Win32 + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Debug|Win32.ActiveCfg = Debug|Win32 {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Debug|Win32.Build.0 = Debug|Win32 + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Release|Win32.ActiveCfg = Release|Win32 {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Release|Win32.Build.0 = Release|Win32 + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Win32.ActiveCfg = Debug|Win32 {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Win32.Build.0 = Debug|Win32 + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Win32.ActiveCfg = Release|Win32 {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Win32.Build.0 = Release|Win32 + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Win32.ActiveCfg = Debug|Win32 {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Win32.Build.0 = Debug|Win32 + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Win32.ActiveCfg = Release|Win32 {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Win32.Build.0 = Release|Win32 + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Win32.ActiveCfg = Debug|Win32 {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Win32.Build.0 = Debug|Win32 + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Win32.ActiveCfg = Release|Win32 {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Win32.Build.0 = Release|Win32 + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Debug|Win32.ActiveCfg = Debug|Win32 {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Debug|Win32.Build.0 = Debug|Win32 + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Release|Win32.ActiveCfg = Release|Win32 {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Release|Win32.Build.0 = Release|Win32 + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Win32.ActiveCfg = Debug|Win32 {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Win32.Build.0 = Debug|Win32 + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Win32.ActiveCfg = Release|Win32 {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Win32.Build.0 = Release|Win32 + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Win32.ActiveCfg = Debug|Win32 {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Win32.Build.0 = Debug|Win32 + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Win32.ActiveCfg = Release|Win32 {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Win32.Build.0 = Release|Win32 + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Win32.ActiveCfg = Debug|Win32 {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Win32.Build.0 = Debug|Win32 + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Win32.ActiveCfg = Release|Win32 {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Win32.Build.0 = Release|Win32 + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Debug|Win32.ActiveCfg = Debug|Win32 {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Debug|Win32.Build.0 = Debug|Win32 + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Release|Win32.ActiveCfg = Release|Win32 {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Release|Win32.Build.0 = Release|Win32 + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Win32.ActiveCfg = Debug|Win32 {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Win32.Build.0 = Debug|Win32 + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Win32.ActiveCfg = Release|Win32 {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Win32.Build.0 = Release|Win32 + {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Win32.ActiveCfg = Debug|Win32 {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Win32.Build.0 = Debug|Win32 + {402A8794-B724-44A3-B608-84B600ECA387}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {402A8794-B724-44A3-B608-84B600ECA387}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {402A8794-B724-44A3-B608-84B600ECA387}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {402A8794-B724-44A3-B608-84B600ECA387}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {402A8794-B724-44A3-B608-84B600ECA387}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {402A8794-B724-44A3-B608-84B600ECA387}.Release|Win32.ActiveCfg = Release|Win32 {402A8794-B724-44A3-B608-84B600ECA387}.Release|Win32.Build.0 = Release|Win32 + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Win32.ActiveCfg = Debug|Win32 {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Win32.Build.0 = Debug|Win32 + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Win32.ActiveCfg = Release|Win32 {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Win32.Build.0 = Release|Win32 + {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Win32.ActiveCfg = Debug|Win32 {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Win32.Build.0 = Debug|Win32 + {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Win32.ActiveCfg = Release|Win32 {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Win32.Build.0 = Release|Win32 + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Win32.ActiveCfg = Debug|Win32 {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Win32.Build.0 = Debug|Win32 + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Win32.ActiveCfg = Release|Win32 {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Win32.Build.0 = Release|Win32 + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Win32.ActiveCfg = Debug|Win32 {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Win32.Build.0 = Debug|Win32 + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Win32.ActiveCfg = Release|Win32 {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Win32.Build.0 = Release|Win32 + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Debug|Win32.ActiveCfg = Debug|Win32 {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Debug|Win32.Build.0 = Debug|Win32 + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Release|Win32.ActiveCfg = Release|Win32 {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Release|Win32.Build.0 = Release|Win32 + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Debug|Win32.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Release|Win32.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Debug|Smartphone 2003 (ARMV4).Deploy.0 = Debug|Smartphone 2003 (ARMV4) {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Debug|Win32.ActiveCfg = Debug|Win32 + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Release|Mixed Platforms.Build.0 = Release|Win32 {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4) {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Release|Win32.ActiveCfg = Release|Win32 {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Release|Win32.Build.0 = Release|Win32 + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Debug|Win32.ActiveCfg = Debug|Win32 {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Debug|Win32.Build.0 = Debug|Win32 + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Release|Win32.ActiveCfg = Release|Win32 {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Release|Win32.Build.0 = Release|Win32 + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Win32.ActiveCfg = Debug|Win32 {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Win32.Build.0 = Debug|Win32 + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4) {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Win32.ActiveCfg = Release|Win32 {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Win32.Build.0 = Release|Win32 + {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Win32.ActiveCfg = Debug|Win32 {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Win32.Build.0 = Debug|Win32 + {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4) {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Win32.ActiveCfg = Release|Win32 {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Win32.Build.0 = Release|Win32 + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Smartphone 2003 (ARMV4).Deploy.0 = Debug|Smartphone 2003 (ARMV4) {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Win32.ActiveCfg = Debug|Win32 {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Win32.Build.0 = Debug|Win32 + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4) {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Win32.ActiveCfg = Release|Win32 {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Win32.Build.0 = Release|Win32 + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Debug|Win32.ActiveCfg = Debug|Win32 {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Debug|Win32.Build.0 = Debug|Win32 + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4) {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Release|Win32.ActiveCfg = Release|Win32 {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Release|Win32.Build.0 = Release|Win32 + {073E2381-4FDE-4C4D-A117-C489DB17C48C}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489DB17C48C}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489DB17C48C}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {073E2381-4FDE-4C4D-A117-C489DB17C48C}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {073E2381-4FDE-4C4D-A117-C489DB17C48C}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {073E2381-4FDE-4C4D-A117-C489DB17C48C}.Debug|Smartphone 2003 (ARMV4).Deploy.0 = Debug|Smartphone 2003 (ARMV4) {073E2381-4FDE-4C4D-A117-C489DB17C48C}.Debug|Win32.ActiveCfg = Debug|Win32 {073E2381-4FDE-4C4D-A117-C489DB17C48C}.Debug|Win32.Build.0 = Debug|Win32 + {073E2381-4FDE-4C4D-A117-C489DB17C48C}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489DB17C48C}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489DB17C48C}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {073E2381-4FDE-4C4D-A117-C489DB17C48C}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {073E2381-4FDE-4C4D-A117-C489DB17C48C}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {073E2381-4FDE-4C4D-A117-C489DB17C48C}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4) {073E2381-4FDE-4C4D-A117-C489DB17C48C}.Release|Win32.ActiveCfg = Release|Win32 {073E2381-4FDE-4C4D-A117-C489DB17C48C}.Release|Win32.Build.0 = Release|Win32 + {073E2381-4FDE-4C4D-B217-C489EB17C48B}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-B217-C489EB17C48B}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-B217-C489EB17C48B}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {073E2381-4FDE-4C4D-B217-C489EB17C48B}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {073E2381-4FDE-4C4D-B217-C489EB17C48B}.Debug|Win32.ActiveCfg = Debug|Win32 {073E2381-4FDE-4C4D-B217-C489EB17C48B}.Debug|Win32.Build.0 = Debug|Win32 + {073E2381-4FDE-4C4D-B217-C489EB17C48B}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-B217-C489EB17C48B}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-B217-C489EB17C48B}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {073E2381-4FDE-4C4D-B217-C489EB17C48B}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {073E2381-4FDE-4C4D-B217-C489EB17C48B}.Release|Win32.ActiveCfg = Release|Win32 {073E2381-4FDE-4C4D-B217-C489EB17C48B}.Release|Win32.Build.0 = Release|Win32 + {B1AEFA90-318F-459C-96EE-B4DFF3318B7B}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {B1AEFA90-318F-459C-96EE-B4DFF3318B7B}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {B1AEFA90-318F-459C-96EE-B4DFF3318B7B}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {B1AEFA90-318F-459C-96EE-B4DFF3318B7B}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {B1AEFA90-318F-459C-96EE-B4DFF3318B7B}.Debug|Win32.ActiveCfg = Debug|Win32 {B1AEFA90-318F-459C-96EE-B4DFF3318B7B}.Debug|Win32.Build.0 = Debug|Win32 + {B1AEFA90-318F-459C-96EE-B4DFF3318B7B}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {B1AEFA90-318F-459C-96EE-B4DFF3318B7B}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {B1AEFA90-318F-459C-96EE-B4DFF3318B7B}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {B1AEFA90-318F-459C-96EE-B4DFF3318B7B}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {B1AEFA90-318F-459C-96EE-B4DFF3318B7B}.Release|Win32.ActiveCfg = Release|Win32 {B1AEFA90-318F-459C-96EE-B4DFF3318B7B}.Release|Win32.Build.0 = Release|Win32 + {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Debug|Smartphone 2003 (ARMV4).Deploy.0 = Debug|Smartphone 2003 (ARMV4) {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Debug|Win32.ActiveCfg = Debug|Win32 {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Debug|Win32.Build.0 = Debug|Win32 + {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4) {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Release|Win32.ActiveCfg = Release|Win32 {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Release|Win32.Build.0 = Release|Win32 + {5D3983BF-143F-49C3-9284-89778282AEFE}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {5D3983BF-143F-49C3-9284-89778282AEFE}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {5D3983BF-143F-49C3-9284-89778282AEFE}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) {5D3983BF-143F-49C3-9284-89778282AEFE}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) {5D3983BF-143F-49C3-9284-89778282AEFE}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) {5D3983BF-143F-49C3-9284-89778282AEFE}.Debug|Smartphone 2003 (ARMV4).Deploy.0 = Debug|Smartphone 2003 (ARMV4) {5D3983BF-143F-49C3-9284-89778282AEFE}.Debug|Win32.ActiveCfg = Debug|Win32 {5D3983BF-143F-49C3-9284-89778282AEFE}.Debug|Win32.Build.0 = Debug|Win32 + {5D3983BF-143F-49C3-9284-89778282AEFE}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {5D3983BF-143F-49C3-9284-89778282AEFE}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {5D3983BF-143F-49C3-9284-89778282AEFE}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) {5D3983BF-143F-49C3-9284-89778282AEFE}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) {5D3983BF-143F-49C3-9284-89778282AEFE}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) {5D3983BF-143F-49C3-9284-89778282AEFE}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4) {5D3983BF-143F-49C3-9284-89778282AEFE}.Release|Win32.ActiveCfg = Release|Win32 {5D3983BF-143F-49C3-9284-89778282AEFE}.Release|Win32.Build.0 = Release|Win32 + {F728CC74-A7D0-43D2-8A28-05CE9F2EF0D0}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {F728CC74-A7D0-43D2-8A28-05CE9F2EF0D0}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {F728CC74-A7D0-43D2-8A28-05CE9F2EF0D0}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Win32 {F728CC74-A7D0-43D2-8A28-05CE9F2EF0D0}.Debug|Win32.ActiveCfg = Debug|Win32 {F728CC74-A7D0-43D2-8A28-05CE9F2EF0D0}.Debug|Win32.Build.0 = Debug|Win32 + {F728CC74-A7D0-43D2-8A28-05CE9F2EF0D0}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {F728CC74-A7D0-43D2-8A28-05CE9F2EF0D0}.Release|Mixed Platforms.Build.0 = Release|Win32 {F728CC74-A7D0-43D2-8A28-05CE9F2EF0D0}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Win32 {F728CC74-A7D0-43D2-8A28-05CE9F2EF0D0}.Release|Win32.ActiveCfg = Release|Win32 {F728CC74-A7D0-43D2-8A28-05CE9F2EF0D0}.Release|Win32.Build.0 = Release|Win32 + {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Win32.ActiveCfg = Debug|Win32 + {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Win32.Build.0 = Debug|Win32 + {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Win32.ActiveCfg = Release|Win32 + {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Win32.Build.0 = Release|Win32 + {41B1DAF0-D7ED-4934-B915-05DBB0EE6B0E}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {41B1DAF0-D7ED-4934-B915-05DBB0EE6B0E}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {41B1DAF0-D7ED-4934-B915-05DBB0EE6B0E}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {41B1DAF0-D7ED-4934-B915-05DBB0EE6B0E}.Debug|Win32.ActiveCfg = Debug|Win32 + {41B1DAF0-D7ED-4934-B915-05DBB0EE6B0E}.Debug|Win32.Build.0 = Debug|Win32 + {41B1DAF0-D7ED-4934-B915-05DBB0EE6B0E}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {41B1DAF0-D7ED-4934-B915-05DBB0EE6B0E}.Release|Mixed Platforms.Build.0 = Release|Win32 + {41B1DAF0-D7ED-4934-B915-05DBB0EE6B0E}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Win32 + {41B1DAF0-D7ED-4934-B915-05DBB0EE6B0E}.Release|Win32.ActiveCfg = Release|Win32 + {41B1DAF0-D7ED-4934-B915-05DBB0EE6B0E}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/build/msvc8/hyb_in.vcproj b/build/msvc8/hyb_in.vcproj new file mode 100644 index 0000000..69d04d6 --- /dev/null +++ b/build/msvc8/hyb_in.vcproj @@ -0,0 +1,358 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/libgpac.vcproj b/build/msvc8/libgpac.vcproj index c8097f6..e0c6669 100644 --- a/build/msvc8/libgpac.vcproj +++ b/build/msvc8/libgpac.vcproj @@ -28,7 +28,7 @@ > + + @@ -3717,6 +3722,18 @@ RelativePath="..\..\include\gpac\internal\avilib.h" > + + + + + + @@ -6529,6 +6546,10 @@ RelativePath="..\..\include\gpac\utf.h" > + + diff --git a/build/msvc8/libgpac_dll.vcproj b/build/msvc8/libgpac_dll.vcproj index cbe341c..850a717 100644 --- a/build/msvc8/libgpac_dll.vcproj +++ b/build/msvc8/libgpac_dll.vcproj @@ -78,11 +78,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -625,11 +470,11 @@ Filter="h;hpp;hxx;hm;inl" > - - diff --git a/build/msvc8/rvc_dec.vcproj b/build/msvc8/rvc_dec.vcproj new file mode 100644 index 0000000..06e89cb --- /dev/null +++ b/build/msvc8/rvc_dec.vcproj @@ -0,0 +1,453 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/GPAX.vcproj b/build/msvc9/GPAX.vcproj index fbe50a1..f630067 100644 --- a/build/msvc9/GPAX.vcproj +++ b/build/msvc9/GPAX.vcproj @@ -118,9 +118,9 @@ /> - + + + - - + + + + + + + + + + + + + + @@ -4406,6 +4447,18 @@ RelativePath="..\..\include\gpac\internal\avilib.h" > + + + + + + diff --git a/build/msvc9/libgpac_dll.vcproj b/build/msvc9/libgpac_dll.vcproj index b1843b9..9a7c960 100644 --- a/build/msvc9/libgpac_dll.vcproj +++ b/build/msvc9/libgpac_dll.vcproj @@ -79,7 +79,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -634,23 +478,18 @@ Filter="h;hpp;hxx;hm;inl" > - - - + diff --git a/build/msvc9/platinum.vcproj b/build/msvc9/platinum.vcproj index cea8c12..982bc6d 100644 --- a/build/msvc9/platinum.vcproj +++ b/build/msvc9/platinum.vcproj @@ -117,7 +117,7 @@ /> - + + + - - CFBundleShortVersionString - 0.4.5 + 9.9.9 CFBundleSignature gpac CFBundleURLTypes @@ -550,7 +550,7 @@ CFBundleVersion - 2200 + 9999 LSMinimumSystemVersion 10.5.0 NSMainNibFile diff --git a/build/xcode/README_IOS.txt b/build/xcode/README_IOS.txt index e4efeb1..7b74101 100644 --- a/build/xcode/README_IOS.txt +++ b/build/xcode/README_IOS.txt @@ -1,16 +1,36 @@ How to build GPAC for iOS +========================= -Tested revision: 2264 -Tested XCode (SDK): 3.2.4 (4.1) +Tested revision: 3239 +Tested XCode (SDK): 3.2.6 (4.3) -You have to have GPAC extra_libs in your extra_lib/lib/gcc directory -Be careful when building SDL in Release, I never made it work +To compile GPAC in command-line mode, please execute the following steps: -1) Open the XCode project. -2) Build libgpac_dynamic via XCode (should end on link error) -3) Execute "script_libgpac.sh Debug" (or Release) -4) Build libgpac_dynamic via XCode (should succeed) -5) Build all modules on one click via XCode (should end on link error) -6) Execute "script_libgpac.sh Debug" (or Release) -7) Build all modules via XCode (should succeed) -8) Build osmo4ios via XCode +1) Check out the GPAC SVN repository: + "svn co https://gpac.svn.sourceforge.net/svnroot/gpac/trunk/" + +2) Unzip the "gpac_extra_libs/gpac_extra_libs.zip" file in its current directory (ie not a subfolder). + You should have the following directory tree: + trunk/ + gpac/ + ... + gpac_extra_libs/ + a52dec/ + AMR_NB/ + ... + +3) Compile gpac dependencies (zlib, faad, libpng etc): + execute "gpac_extra_libs/build/xcode_ios/generate_extra_libs.sh" script. + +4) Check all gpac dependencies have been successfully compiled: + $> ls gpac_extra_libs/lib/iOS + libSDL.a libfaad.a libfreetype.a libjpeg.a libjs.a libmad.a libpng.a + +5) Copy the extra_libs to the right place: + if you checked out as mentionned in 1), execute the "gpac_extra_libs/CopyLibs2Public4iOS.sh" script. + Otherwise copy manually the libs to the gpac/extra_lib/lib/ios directory. + +6) Compile GPAC: + execute the "gpac/build/xcode/generate_ios.sh" script. + The script checks that all files have been compiled, print an error message if needed. + Otherwise it generats a .tar.gz archive into the gpac/bin/iOS directory. diff --git a/build/xcode/build/Release-iphonesimulator/libgpac_dynamic.dylib b/build/xcode/build/Release-iphonesimulator/libgpac_dynamic.dylib new file mode 100644 index 0000000..ea0eca7 Binary files /dev/null and b/build/xcode/build/Release-iphonesimulator/libgpac_dynamic.dylib differ diff --git a/build/xcode/generate_ios.sh b/build/xcode/generate_ios.sh index 824a288..6f268df 100755 --- a/build/xcode/generate_ios.sh +++ b/build/xcode/generate_ios.sh @@ -1,16 +1,27 @@ #!/bin/sh -#echo "*** Compile libgpac for Simulator (i386) ***" -xcodebuild -target libgpac_dynamic -sdk iphonesimulator -configuration Release -project gpac4ios.xcodeproj +cd "`dirname $0`" + +echo "*** Set version within Info.plist application file ***" +version=`grep '#define GPAC_VERSION ' ../../include/gpac/tools.h | cut -d '"' -f 2` +rev=`LANG=en_US svn info | grep Revision | tr -d 'Revision: '` +if [ "$rev" != "" ] +then + svn revert ../../applications/osmo4_ios/osmo4ios-Info.plist + sed 's/.*<\/string>/'"$version"'<\/string>/' ../../applications/osmo4_ios/osmo4ios-Info.plist > ../../applications/osmo4_ios/osmo4ios-Info.plist.new + sed 's/.*<\/string>/'"$rev"'<\/string>/' ../../applications/osmo4_ios/osmo4ios-Info.plist.new > ../../applications/osmo4_ios/osmo4ios-Info.plist + rm ../../applications/osmo4_ios/osmo4ios-Info.plist.new +fi + +echo "*** Clean previous build files ***" +xcodebuild -alltargets -sdk iphoneos -configuration Debug -project gpac4ios.xcodeproj clean +xcodebuild -alltargets -sdk iphoneos -configuration Release -project gpac4ios.xcodeproj clean echo "*** Compile libgpac for iOS (arm) ***" xcodebuild -target libgpac_dynamic -sdk iphoneos -configuration Release -project gpac4ios.xcodeproj ./script_libgpac.sh Release #xcodebuild -target libgpac_dynamic -sdk iphoneos -configuration Release -project gpac4ios.xcodeproj -#echo "*** Compile modules and osmo4ios for Simulator (i386) ***" -#xcodebuild -alltargets -parallelizeTargets -sdk iphonesimulator -configuration Release -project gpac4ios.xcodeproj - echo "*** Compile modules for iOS (arm) ***" xcodebuild -alltargets -parallelizeTargets -sdk iphoneos -configuration Release -project gpac4ios.xcodeproj ./script_modules.sh Release @@ -32,21 +43,32 @@ then exit 1 fi -echo "*** Generate an archive and clean ***" +#echo "*** Build archive name ***" cd ../.. -version=`grep '#define GPAC_VERSION ' include/gpac/tools.h | cut -d '"' -f 2` -rev=`LANG=en_US svn info | grep Revision | tr -d 'Revision: '` if [ "$rev" != "" ] then full_version="$version-r$rev" else - #if no revision can be extracted from SVN, use date + #if no revision can be extracted from SVN, use date full_version="$version-$(date +%Y%m%d)" fi + +echo "*** Generate an archive and clean ***" cd bin/iOS -rm -rf osmo4ios.app/.svn +mkdir osmo4ios.app/gui +mkdir osmo4ios.app/gui/icons +mkdir osmo4ios.app/gui/extensions +cp ../../applications/osmo4_ios/Resources/icon.png osmo4ios.app/ +cp ../../gui/gui*.bt osmo4ios.app/gui/ +cp ../../gui/gui*.js osmo4ios.app/gui/ +cp ../../gui/gwlib.js osmo4ios.app/gui/ +cp ../../gui/mpegu-core.js osmo4ios.app/gui/ +cp -r ../../gui/icons osmo4ios.app/gui/ +cp -r ../../gui/extensions osmo4ios.app/gui/ +find osmo4ios.app | fgrep .svn | fgrep -v svn/ | xargs rm -rf tar -czf "osmo4ios-$full_version.tar.gz" osmo4ios.app/ rm -rf osmo4ios.app +svn up -r $rev cd ../../build/xcode/ echo "*** Extra Libs generation for iOS completed (full_version)! ***" diff --git a/build/xcode/gpac4ios.xcodeproj/project.pbxproj b/build/xcode/gpac4ios.xcodeproj/project.pbxproj index 7b67b24..296cd00 100755 --- a/build/xcode/gpac4ios.xcodeproj/project.pbxproj +++ b/build/xcode/gpac4ios.xcodeproj/project.pbxproj @@ -429,6 +429,7 @@ 71CCF3FD12770A8C00339E12 /* user.h in Headers */ = {isa = PBXBuildFile; fileRef = 71CCF3AE12770A8C00339E12 /* user.h */; }; 71CCF3FE12770A8C00339E12 /* utf.h in Headers */ = {isa = PBXBuildFile; fileRef = 71CCF3AF12770A8C00339E12 /* utf.h */; }; 71CCF3FF12770A8C00339E12 /* xml.h in Headers */ = {isa = PBXBuildFile; fileRef = 71CCF3B012770A8C00339E12 /* xml.h */; }; + 71EC88E11396273B004DCB6A /* osmo.icns in Resources */ = {isa = PBXBuildFile; fileRef = 71EC88E01396273B004DCB6A /* osmo.icns */; }; 71F2A45E12830B5300C384DE /* libjs.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 71F2A45412830B1400C384DE /* libjs.a */; }; 71F2A46E12830BE200C384DE /* libjpeg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 71F2A45312830B1400C384DE /* libjpeg.a */; }; 71F2A46F12830BE800C384DE /* libpng.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 71F2A45612830B1400C384DE /* libpng.a */; }; @@ -489,9 +490,19 @@ 970A28621344632F0007362C /* libgpac_dynamic.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 970A28521344632F0007362C /* libgpac_dynamic.dylib */; }; 970A28631344632F0007362C /* libgpac_dynamic.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 970A28521344632F0007362C /* libgpac_dynamic.dylib */; }; 970A28641344632F0007362C /* libgpac_dynamic.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 970A28521344632F0007362C /* libgpac_dynamic.dylib */; }; + 97FBAAE913BB61D700800B2F /* dvb.c in Sources */ = {isa = PBXBuildFile; fileRef = 97FBAAE813BB61D700800B2F /* dvb.c */; }; + 97FF0660138CE4C400D6C707 /* os_config_init.c in Sources */ = {isa = PBXBuildFile; fileRef = 97FF065F138CE4C400D6C707 /* os_config_init.c */; }; + 97FF0662138CE4E400D6C707 /* carousel.c in Sources */ = {isa = PBXBuildFile; fileRef = 97FF0661138CE4E400D6C707 /* carousel.c */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 713FD6E31393868200E8102E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; + proxyType = 1; + remoteGlobalIDString = 718478371278647200917298; + remoteInfo = dummy_in; + }; 718477D4127814D600917298 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */; @@ -928,6 +939,7 @@ 71CCF3AE12770A8C00339E12 /* user.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = user.h; sourceTree = ""; }; 71CCF3AF12770A8C00339E12 /* utf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utf.h; sourceTree = ""; }; 71CCF3B012770A8C00339E12 /* xml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xml.h; sourceTree = ""; }; + 71EC88E01396273B004DCB6A /* osmo.icns */ = {isa = PBXFileReference; explicitFileType = image.icns; name = osmo.icns; path = ../../applications/osmo4_ios/Resources/osmo.icns; sourceTree = SOURCE_ROOT; }; 71F2A45012830B1400C384DE /* libfaad.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libfaad.a; path = ../../extra_lib/lib/iOS/libfaad.a; sourceTree = SOURCE_ROOT; }; 71F2A45112830B1400C384DE /* libfreetype.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libfreetype.a; path = ../../extra_lib/lib/iOS/libfreetype.a; sourceTree = SOURCE_ROOT; }; 71F2A45312830B1400C384DE /* libjpeg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libjpeg.a; path = ../../extra_lib/lib/iOS/libjpeg.a; sourceTree = SOURCE_ROOT; }; @@ -947,6 +959,9 @@ 970A270D1343540C0007362C /* libgcc_s.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libgcc_s.1.dylib; path = usr/lib/libgcc_s.1.dylib; sourceTree = SDKROOT; }; 970A283F134462AE0007362C /* libgpac_dynamic.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libgpac_dynamic.dylib; path = "build/Release-iphonesimulator/libgpac_dynamic.dylib"; sourceTree = ""; }; 970A28521344632F0007362C /* libgpac_dynamic.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libgpac_dynamic.dylib; path = ../../bin/iOS/osmo4ios.app/libgpac_dynamic.dylib; sourceTree = SOURCE_ROOT; }; + 97FBAAE813BB61D700800B2F /* dvb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dvb.c; sourceTree = ""; }; + 97FF065F138CE4C400D6C707 /* os_config_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = os_config_init.c; sourceTree = ""; }; + 97FF0661138CE4E400D6C707 /* carousel.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = carousel.c; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1443,6 +1458,7 @@ 71A19B1412796AC700ACFF58 /* osmo4iOS */ = { isa = PBXGroup; children = ( + 71EC88E01396273B004DCB6A /* osmo.icns */, 71A19B43127971C700ACFF58 /* libgpac_symbols.h */, 71A19B411279713300ACFF58 /* extract.c */, 71A19B2012796B6F00ACFF58 /* main.c */, @@ -1693,6 +1709,8 @@ 71CCF1CD1277045100339E12 /* media_tools */ = { isa = PBXGroup; children = ( + 97FBAAE813BB61D700800B2F /* dvb.c */, + 97FF0661138CE4E400D6C707 /* carousel.c */, 970A26C713434D2C0007362C /* m3u8.c */, 970A26C813434D2C0007362C /* mpd.c */, 71CCF1CE1277045100339E12 /* av_parsers.c */, @@ -1822,6 +1840,7 @@ 71CCF2291277045100339E12 /* utils */ = { isa = PBXGroup; children = ( + 97FF065F138CE4C400D6C707 /* os_config_init.c */, 970A26D513434DAC0007362C /* ringbuffer.c */, 970A26D613434DAC0007362C /* unicode.c */, 7147425F12B918C900DB5A59 /* cache.c */, @@ -2271,6 +2290,7 @@ buildRules = ( ); dependencies = ( + 713FD6E41393868200E8102E /* PBXTargetDependency */, ); name = soft_raster; productName = soft_raster; @@ -2634,6 +2654,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 71EC88E11396273B004DCB6A /* osmo.icns in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3090,12 +3111,20 @@ 970A26CA13434D2C0007362C /* mpd.c in Sources */, 970A26D713434DAC0007362C /* ringbuffer.c in Sources */, 970A26D813434DAC0007362C /* unicode.c in Sources */, + 97FF0660138CE4C400D6C707 /* os_config_init.c in Sources */, + 97FF0662138CE4E400D6C707 /* carousel.c in Sources */, + 97FBAAE913BB61D700800B2F /* dvb.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 713FD6E41393868200E8102E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 718478371278647200917298 /* dummy_in */; + targetProxy = 713FD6E31393868200E8102E /* PBXContainerItemProxy */; + }; 718477D5127814D600917298 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 71CCF1301277037A00339E12 /* libgpac_static */; @@ -3381,6 +3410,7 @@ GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( GPAC_CONFIG_DARWIN, + GPAC_IPHONE, XP_UNIX, GPAC_HAS_FAAD, ); @@ -3415,6 +3445,7 @@ GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_PREPROCESSOR_DEFINITIONS = ( GPAC_CONFIG_DARWIN, + GPAC_IPHONE, XP_UNIX, GPAC_HAS_FAAD, ); @@ -3505,6 +3536,7 @@ GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( GPAC_CONFIG_DARWIN, + GPAC_IPHONE, XP_UNIX, GPAC_HAS_MAD, ); @@ -3539,6 +3571,7 @@ GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_PREPROCESSOR_DEFINITIONS = ( GPAC_CONFIG_DARWIN, + GPAC_IPHONE, XP_UNIX, GPAC_HAS_MAD, ); @@ -3573,10 +3606,6 @@ EXECUTABLE_PREFIX = gm_; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - GPAC_CONFIG_DARWIN, - XP_UNIX, - ); HEADER_SEARCH_PATHS = ../../include; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -3603,10 +3632,6 @@ EXECUTABLE_EXTENSION = dylib; EXECUTABLE_PREFIX = gm_; GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_PREPROCESSOR_DEFINITIONS = ( - GPAC_CONFIG_DARWIN, - XP_UNIX, - ); HEADER_SEARCH_PATHS = ../../include; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -3690,9 +3715,11 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( + GPAC_CONFIG_DARWIN, + GPAC_IPHONE, + XP_UNIX, GPAC_HAS_SPIDERMONKEY, MOZILLA_1_8_BRANCH, - XP_UNIX, ); HEADER_SEARCH_PATHS = ( ../../include, @@ -3724,9 +3751,11 @@ EXECUTABLE_PREFIX = gm_; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_PREPROCESSOR_DEFINITIONS = ( + GPAC_CONFIG_DARWIN, + GPAC_IPHONE, + XP_UNIX, GPAC_HAS_SPIDERMONKEY, MOZILLA_1_8_BRANCH, - XP_UNIX, ); HEADER_SEARCH_PATHS = ( ../../include, @@ -4213,7 +4242,6 @@ GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = NO; GCC_PREFIX_HEADER = ""; - GCC_PREPROCESSOR_DEFINITIONS = GPAC_IPHONE; HEADER_SEARCH_PATHS = ( ../../include, ../../extra_lib/include/SDL, @@ -4244,7 +4272,6 @@ GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_PRECOMPILE_PREFIX_HEADER = NO; GCC_PREFIX_HEADER = ""; - GCC_PREPROCESSOR_DEFINITIONS = GPAC_IPHONE; HEADER_SEARCH_PATHS = ( ../../include, ../../extra_lib/include/SDL, @@ -4273,11 +4300,6 @@ EXECUTABLE_PREFIX = ""; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - XP_UNIX, - GPAC_CONFIG_DARWIN, - GPAC_IPHONE, - ); GCC_THUMB_SUPPORT = NO; HEADER_SEARCH_PATHS = ( ../../include, @@ -4308,11 +4330,6 @@ COPY_PHASE_STRIP = YES; EXECUTABLE_PREFIX = ""; GCC_ENABLE_FIX_AND_CONTINUE = NO; - GCC_PREPROCESSOR_DEFINITIONS = ( - XP_UNIX, - GPAC_CONFIG_DARWIN, - GPAC_IPHONE, - ); GCC_THUMB_SUPPORT = NO; HEADER_SEARCH_PATHS = ( ../../include, @@ -4351,6 +4368,7 @@ GCC_OBJC_CALL_CXX_CDTORS = NO; GCC_PREPROCESSOR_DEFINITIONS = ( GPAC_CONFIG_DARWIN, + GPAC_IPHONE, XP_UNIX, ); GCC_THUMB_SUPPORT = NO; @@ -4377,6 +4395,7 @@ GCC_OBJC_CALL_CXX_CDTORS = NO; GCC_PREPROCESSOR_DEFINITIONS = ( GPAC_CONFIG_DARWIN, + GPAC_IPHONE, XP_UNIX, ); GCC_THUMB_SUPPORT = NO; diff --git a/build/xcode/libgpac_symbols.h b/build/xcode/libgpac_symbols.h index 1b6e331..92e6e7d 100644 --- a/build/xcode/libgpac_symbols.h +++ b/build/xcode/libgpac_symbols.h @@ -58,7 +58,7 @@ #define gf_cfg_del _gf_cfg_del #define gf_term_get_channel_net_info _gf_term_get_channel_net_info #define gf_term_process_shortcut _gf_term_process_shortcut -#define gf_cfg_new _gf_cfg_new +#define gf_cfg_init _gf_cfg_init #define gf_term_get_download_info _gf_term_get_download_info #define gf_sys_clock _gf_sys_clock #define gf_term_get_object _gf_term_get_object @@ -211,8 +211,8 @@ extern void (*gf_cfg_del)(GF_Config *iniFile); extern Bool (*gf_term_get_channel_net_info)(GF_Terminal *term, GF_ObjectManager *odm, u32 *d_enum, u32 *chid, NetStatCommand *netcom, GF_Err *ret_code); #undef gf_term_process_shortcut extern void (*gf_term_process_shortcut)(GF_Terminal *term, GF_Event *ev); -#undef gf_cfg_new -extern GF_Config *(*gf_cfg_new)(const char *filePath, const char *fileName); +#undef gf_cfg_init +extern GF_Config *(*gf_cfg_init)(const char *fileName, Bool *is_new); #undef gf_term_get_download_info extern Bool (*gf_term_get_download_info)(GF_Terminal *term, GF_ObjectManager *odm, u32 *d_enum, const char **server, const char **path, u32 *bytes_done, u32 *total_bytes, u32 *bytes_per_sec); #undef gf_sys_clock diff --git a/configure b/configure index cf0b5cd..dbe7d88 100755 --- a/configure +++ b/configure @@ -43,6 +43,7 @@ ar="ar" ranlib="ranlib" make="make" strip="strip" +readelf="readelf" install="${INSTALL:=install}" instflags="${INSTFLAGS:=-p}" cpu=`uname -m` @@ -57,6 +58,7 @@ libdir="lib" #GPAC module config js_flags="XP_UNIX" js_lib="-ljs" +lm_lib="" has_mingw_directx="no" has_js="no" has_ft="no" @@ -77,6 +79,7 @@ has_pulseaudio="no" has_oss_audio="no" has_alsa="no" has_jack="no" +has_directfb="no" has_x11="no" has_x11_shm="no" has_x11_xv="no" @@ -161,193 +164,192 @@ is_64="no" #Configure Usage if test x"$1" = x"-h" -o x"$1" = x"--help" ; then -cat << EOF + cat << EOF Usage: configure [options] Options: [defaults in brackets after descriptions] +GPAC configuration options: + --help print this message + --prefix=PREFIX install in PREFIX [$prefix] + --mandir=DIR man documentation in DIR [PREFIX/man] + + --source-path=PATH path of source code [$source_path] + --cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix] + --cc =CC use C compiler CC [$cc] + --cpp=CPP use C++ compiler CPP [$cpp] + --make=MAKE use specified make [$make] + --extra-cflags=ECFLAGS add ECFLAGS to CFLAGS [$CFLAGS] + --extra-ldflags=ELDFLAGS add ELDFLAGS to LDFLAGS [$LDFLAGS] + --extra-libs=ELIBS add ELIBS [$ELIBS] + --cpu=CPU force cpu to CPU [$cpu] + --sdl-cfg=SDL_PATH specify path to sdl-config for local install [$sdl_path] + --enable-sdl-static use static SDL linking [default=no] + --X11-path=X11_PATH specify path for X11 includes and libraries [$X11_PATH] + --dxsdk-path=DX_PATH specify directX SDK for MinGW [$dxsdk_path] + --xulsdk-path=XUL_PATH specify Mozilla XUL (Gecko) SDK include path [$xulsdk_path] + --mozdir=MOZ_PATH specify mozilla main directory path for system install + + --enable-debug produce debug version + --enable-gprof enable profiling + --enable-pic enable Position Independant Code for shared objects + --strip enable strip + --std-allocator uses standard lib memory allocator + --track-memory enable tracking of all memory allocated by gpac + --disable-opt disable GCC optimizations + --disable-ipv6 disable IPV6 support + --disable-wx disable wxWidgets support + --disable-oss-audio disable OSS audio + --disable-x11-shm disable X11 shared memory support + --disable-x11-xv disable X11 Xvideo support + --enable-fixed-point enable fixed-point math + --force-fixed-point force fixed-point math without changing gpac math.h header + --enable-tinygl enable TinyGL support + --enable-joystick enable joystick support + --disable-ssl disable OpenSSL support + --enable-amr-nb-fixed enable AMR NB fixed-point decoder + --enable-amr-nb enable AMR NB library + --enable-amr-wb enable AMR WB library + --enable-amr enable both AMR NB and WB libraries + --static-mp4box configure for static linking of MP4Box. + --enable-depth enables depth handling in the compositor + +Configuration options for libgpac - all options can be enabled with --enable-optname + --disable-all disables all features in libgpac + --disable-3d disable 3D rendering + --disable-svg disable SVG + --disable-vrml disable MPEG-4/VRML/X3D + --disable-x3d disable X3D only + --disable-odf disable full support of MPEG-4 OD Framework + --disable-bifs disable BIFS coder + --disable-laser disable LASeR coder + --disable-beng disable scene encoder engine + --disable-qtvr disable import of Cubic QTVR files + --disable-avi disable AVI + --disable-ogg disable OGG + --disable-m2ps disable MPEG2 PS + --disable-m2ts disable MPEG2 TS + --disable-m2ts-mux disable MPEG2 TS Multiplexer + --disable-parsers disable AV parsers + --disable-import disable media importers + --disable-export disable media exporters + --disable-swf disable SWF import + --disable-scene-stats disable scene graph statistics + --disable-scene-dump disable scene graph dump + --disable-od-dump disable OD dump + --disable-mcrypt disable mcrypt + --disable-scene-encode disable BIFS & LASeR to ISO File Format encoding + --disable-loader-isoff disable scene loading from ISO File Format + --disable-loader-bt disable scene loading from ISO File Format + --disable-loader-xmt disable scene loading from ISO File Format + --disable-isoff disable ISO File Format + --disable-isoff-write disable ISO File Format edit/write + --disable-isoff-hint disable ISO File Format hinting + --disable-isoff-frag disable fragments in ISO File Format + --disable-streaming disable RTP/RTSP/SDP + +Extra libraries configuration. You can turn a libray off or force using the local version in gpac/extra_lib/ + --use-js=OPT force SpiderMonkey ECMAScript OPT=[no,local] + --use-ft=OPT force FreeType OPT=[no,local] + --use-jpeg=OPT force JPEG OPT=[no,local] + --use-png=OPT force PNG OPT=[no,local] + --use-faad=OPT force FAAD OPT=[no,local] + --use-mad=OPT force MAD OPT=[no,local] + --use-xvid=OPT force XVID OPT=[no,local] + --use-ffmpeg=OPT force FFMPEG OPT=[no,local] + --use-ogg=OPT force OGG OPT=[no,system,local] + --use-vorbis=OPT force vorbis OPT=[no,system,local] + --use-theora=OPT force theora OPT=[no,system,local] + --use-openjpeg=OPT force openjpeg OPT=[no,system,local] + +NOTE: The object files are build at the place where configure is launched EOF -echo "GPAC configuration options:" -echo " --help print this message" -echo " --prefix=PREFIX install in PREFIX [$prefix]" -echo " --mandir=DIR man documentation in DIR [PREFIX/man]" -echo "" -echo " --source-path=PATH path of source code [$source_path]" -echo " --cross_prefix=PREFIX use PREFIX for compile tools [$cross_prefix]" -echo " --cc =CC use C compiler CC [$cc]" -echo " --cpp=CPP use C++ compiler CPP [$cpp]" -echo " --make=MAKE use specified make [$make]" -echo " --extra-cflags=ECFLAGS add ECFLAGS to CFLAGS [$CFLAGS]" -echo " --extra-ldflags=ELDFLAGS add ELDFLAGS to LDFLAGS [$LDFLAGS]" -echo " --extra-libs=ELIBS add ELIBS [$ELIBS]" -echo " --cpu=CPU force cpu to CPU [$cpu]" -echo " --sdl-cfg=SDL_PATH specify path to sdl-config for local install [$sdl_path]" -echo " --enable-sdl-static use static SDL linking [default=no]" -echo " --X11-path=X11_PATH specify path for X11 includes and libraries [$X11_PATH]" -echo " --dxsdk-path=DX_PATH specify directX SDK for MinGW [$dxsdk_path]" -echo " --xulsdk-path=XUL_PATH specify Mozilla XUL (Gecko) SDK include path [$xulsdk_path]" -echo " --mozdir=MOZ_PATH specify mozilla main directory path for system install" -echo "" -echo " --enable-debug produce debug version" -echo " --enable-gprof enable profiling" -echo " --enable-pic enable Position Independant Code for shared objects" -echo " --strip enable strip" -echo " --std-allocator uses standard lib memory allocator" -echo " --track-memory enable tracking of all memory allocated by gpac" -echo " --disable-opt disable GCC optimizations" -echo " --disable-ipv6 disable IPV6 support" -echo " --disable-wx disable wxWidgets support" -echo " --disable-oss-audio disable OSS audio" -echo " --disable-x11-shm disable X11 shared memory support" -echo " --disable-x11-xv disable X11 Xvideo support" -echo " --enable-fixed-point enable fixed-point math" -echo " --force-fixed-point force fixed-point math without changing gpac math.h header" -echo " --enable-tinygl enable TinyGL support" -echo " --enable-joystick enable joystick support" -echo " --disable-ssl disable OpenSSL support" -echo " --enable-amr-nb-fixed enable AMR NB fixed-point decoder" -echo " --enable-amr-nb enable AMR NB library" -echo " --enable-amr-wb enable AMR WB library" -echo " --enable-amr enable both AMR NB and WB libraries" -echo " --static-mp4box configure for static linking of MP4Box." -echo " --enable-depth enables depth handling in the compositor" - -echo "" -echo "Configuration options for libgpac - all options can be enabled with --enable-optname" -echo " --disable-all disables all features in libgpac" -echo " --disable-3d disable 3D rendering" -echo " --disable-svg disable SVG" -echo " --disable-vrml disable MPEG-4/VRML/X3D" -echo " --disable-x3d disable X3D only" -echo " --disable-odf disable full support of MPEG-4 OD Framework" -echo " --disable-bifs disable BIFS coder" -echo " --disable-laser disable LASeR coder" -echo " --disable-beng disable scene encoder engine" -echo " --disable-qtvr disable import of Cubic QTVR files" -echo " --disable-avi disable AVI" -echo " --disable-ogg disable OGG" -echo " --disable-m2ps disable MPEG2 PS" -echo " --disable-m2ts disable MPEG2 TS" -echo " --disable-m2ts-mux disable MPEG2 TS Multiplexer" -echo " --disable-parsers disable AV parsers" -echo " --disable-import disable media importers" -echo " --disable-export disable media exporters" -echo " --disable-swf disable SWF import" -echo " --disable-scene-stats disable scene graph statistics" -echo " --disable-scene-dump disable scene graph dump" -echo " --disable-od-dump disable OD dump" -echo " --disable-mcrypt disable mcrypt" -echo " --disable-scene-encode disable BIFS & LASeR to ISO File Format encoding" -echo " --disable-loader-isoff disable scene loading from ISO File Format" -echo " --disable-loader-bt disable scene loading from ISO File Format" -echo " --disable-loader-xmt disable scene loading from ISO File Format" -echo " --disable-isoff disable ISO File Format" -echo " --disable-isoff-write disable ISO File Format edit/write" -echo " --disable-isoff-hint disable ISO File Format hinting" -echo " --disable-isoff-frag disable fragments in ISO File Format" -echo " --disable-streaming disable RTP/RTSP/SDP" -echo "" -echo "Extra libraries configuration. You can turn a libray off or force using the local version in gpac/extra_lib/" -echo " --use-js=OPT force SpiderMonkey ECMAScript OPT=[no,local]" -echo " --use-ft=OPT force FreeType OPT=[no,local]" -echo " --use-jpeg=OPT force JPEG OPT=[no,local]" -echo " --use-png=OPT force PNG OPT=[no,local]" -echo " --use-faad=OPT force FAAD OPT=[no,local]" -echo " --use-mad=OPT force MAD OPT=[no,local]" -echo " --use-xvid=OPT force XVID OPT=[no,local]" -echo " --use-ffmpeg=OPT force FFMPEG OPT=[no,local]" -echo " --use-ogg=OPT force OGG OPT=[no,system,local]" -echo " --use-vorbis=OPT force vorbis OPT=[no,system,local]" -echo " --use-theora=OPT force theora OPT=[no,system,local]" -echo " --use-openjpeg=OPT force openjpeg OPT=[no,system,local]" -echo "" -echo "NOTE: The object files are build at the place where configure is launched" exit 1 fi for opt do - case "$opt" in - --prefix=*) prefix=`echo $opt | cut -d '=' -f 2` - ;; - --mandir=*) mandir=`echo $opt | cut -d '=' -f 2` - ;; - --source-path=*) source_path=`echo $opt | cut -d '=' -f 2` - ;; - --cross-prefix=*) cross_prefix=`echo $opt | cut -d '=' -f 2` - ;; - --cc=*) cc=`echo $opt | cut -d '=' -f 2` - ;; - --make=*) make=`echo $opt | cut -d '=' -f 2` - ;; - --extra-cflags=*) CFLAGS="$CFLAGS ${opt#--extra-cflags=}" - ;; - --extra-ldflags=*) LDFLAGS="$LDFLAGS ${opt#--extra-ldflags=}" - ;; - --extra-libs=*) extralibs=${opt#--extra-libs=} - ;; - --cpu=*) cpu=`echo $opt | cut -d '=' -f 2` - ;; - esac + case "$opt" in + --prefix=*) prefix=`echo $opt | cut -d '=' -f 2` + ;; + --mandir=*) mandir=`echo $opt | cut -d '=' -f 2` + ;; + --source-path=*) source_path=`echo $opt | cut -d '=' -f 2` + ;; + --cross-prefix=*) cross_prefix=`echo $opt | cut -d '=' -f 2` && echo "cross-prefix detected: $cross_prefix" + ;; + --cc=*) cc=`echo $opt | cut -d '=' -f 2` + ;; + --make=*) make=`echo $opt | cut -d '=' -f 2` + ;; + --extra-cflags=*) CFLAGS="$CFLAGS ${opt#--extra-cflags=}" + ;; + --extra-ldflags=*) LDFLAGS="$LDFLAGS ${opt#--extra-ldflags=}" + ;; + --extra-libs=*) extralibs=${opt#--extra-libs=} + ;; + --cpu=*) cpu=`echo $opt | cut -d '=' -f 2` + ;; + esac done case "$cpu" in - i386|i486|i586|i686|i86pc|BePC) - cpu="x86" - ;; - x86_64|amd64) - cpu="x86" - if test "$linux" = "yes" ; then - is_64="yes" - fi - case `uname -s` in - SunOS) - canon_arch=`isainfo -n` - ;; - *) - canon_arch="`$cc -dumpmachine | sed -e 's,\([^-]*\)-.*,\1,'`" - ;; - esac - - if [ x"$canon_arch" = x"x86_64" -o x"$canon_arch" = x"amd64" ]; then - if [ -z "`echo $CFLAGS | grep -- -m32`" ]; then - cpu="x86_64" - if test "$linux" = "yes" ; then - libdir="lib64" + i386|i486|i586|i686|i86pc|BePC) + cpu="x86" + ;; + x86_64|amd64) + cpu="x86" + if [ "$linux" = "yes" -o "$darwin" = "yes" ] ; then + is_64="yes" fi - want_pic="yes" - fi - fi - ;; - armv4l|arm) - cpu="armv4l" - ;; - alpha) - cpu="alpha" - ;; - ppc64) - cpu="powerpc" - libdir="lib64" - ;; - "Power Macintosh"|ppc) - cpu="powerpc" - ;; - mips) - cpu="mips" - ;; - sh4|sh4a|sh) - cpu="sh4" - ;; - sun4u|sun4v) - cpu="sparc" - if [ -z "`echo $CFLAGS | grep -- -m32`" ]; then - is_64="yes" - PIC_CFLAGS="-fPIC -DPIC" - want_pic="yes" - fi - ;; - *) - cpu="unknown" - ;; + case `uname -s` in + SunOS) + canon_arch=`isainfo -n` + ;; + *) + canon_arch="`$cc -dumpmachine | sed -e 's,\([^-]*\)-.*,\1,'`" + ;; + esac + + if [ x"$canon_arch" = x"x86_64" -o x"$canon_arch" = x"amd64" ]; then + if [ -z "`echo $CFLAGS | grep -- -m32`" ]; then + cpu="x86_64" + if test "$linux" = "yes" ; then + libdir="lib64" + fi + want_pic="yes" + fi + fi + ;; + armv4l|arm) + cpu="armv4l" + ;; + alpha) + cpu="alpha" + ;; + ppc64) + cpu="powerpc" + libdir="lib64" + ;; + "Power Macintosh"|ppc) + cpu="powerpc" + ;; + mips) + cpu="mips" + ;; + sh4|sh4a|sh) + cpu="sh4" + ;; + sun4u|sun4v) + cpu="sparc" + if [ -z "`echo $CFLAGS | grep -- -m32`" ]; then + is_64="yes" + PIC_CFLAGS="-fPIC -DPIC" + want_pic="yes" + fi + ;; + *) + cpu="unknown" + ;; esac # Checking for CFLAGS @@ -366,6 +368,7 @@ fi cc="${cross_prefix}${cc}" #for ccache cc="${cc}" +cpp="${cross_prefix}${cpp}" ar="${cross_prefix}${ar}" ranlib="${cross_prefix}${ranlib}" strip="${cross_prefix}${strip}" @@ -383,137 +386,151 @@ fi # OS specific targetos=`uname -s` case $targetos in -BeOS) -js_flags=-DXP_BEOS -xul_flags=-DXP_BEOS -prefix="/boot/home/config" -CFLAGS="$CFLAGS -DPIC -fomit-frame-pointer" -# 3 gcc releases known for BeOS, each with ugly bugs -gcc_version="$($cc -v 2>&1 | grep version | cut -d ' ' -f3-)" -case "$gcc_version" in -2.9-beos-991026*|2.9-beos-000224*) echo "R5/GG gcc" -;; -*20010315*) echo "BeBits gcc" -CFLAGS="$CFLAGS -fno-expensive-optimizations" -;; -esac + BeOS) + js_flags=-DXP_BEOS + xul_flags=-DXP_BEOS + prefix="/boot/home/config" + CFLAGS="$CFLAGS -DPIC -fomit-frame-pointer" + # 3 gcc releases known for BeOS, each with ugly bugs + gcc_version="$($cc -v 2>&1 | grep version | cut -d ' ' -f3-)" + case "$gcc_version" in + 2.9-beos-991026*|2.9-beos-000224*) echo "R5/GG gcc" + ;; + *20010315*) echo "BeBits gcc" + CFLAGS="$CFLAGS -fno-expensive-optimizations" + ;; + esac + + SHFLAGS=-nostart + # no need for libm, but the inet stuff + # Check for BONE + if (echo $BEINCLUDES|grep 'headers/be/bone' >/dev/null); then + extralibs="-lbind -lsocket" + else + need_inet_aton="yes" + extralibs="-lnet" + fi + ;; -SHFLAGS=-nostart -# no need for libm, but the inet stuff -# Check for BONE -if (echo $BEINCLUDES|grep 'headers/be/bone' >/dev/null); then -extralibs="-lbind -lsocket" -else -need_inet_aton="yes" -extralibs="-lnet" -fi ;; - -SunOS) -make="gmake" -LDFLAGS="${opt#--extra-ldflags=}" -instflags="" -if test "$is_64" = "yes"; then - if test "$cpu" = "x86_64"; then - libdir=lib/amd64 - elif test "$cpu" = "sparc"; then - libdir=lib/sparcv9 - fi -fi -sunos="yes" -need_inet_aton="yes" -extralibs="$extralibs -lsocket -lnsl" -;; - -FreeBSD) -make="gmake" -LDFLAGS="$LDFLAGS -export-dynamic" -CFLAGS="$CFLAGS -pthread" -GPAC_SH_FLAGS=-pthread -freebsd="yes" -js_flags="-DXP_UNIX -I/usr/include/js" -;; - -BSD/OS) -extralibs="-lpoll -lgnugetopt -lm" -make="gmake" -;; - -Darwin) -js_flags=-DXP_MAC -xul_flags=-DXP_MAC -if test -d /sw/bin ; then - alt_macosx_dir="/sw" - CFLAGS="-I/sw/include $CFLAGS" - LDFLAGS="-L/sw/lib $LDFLAGS" -elif test -d /opt/local/bin ; then - alt_macosx_dir="/opt/local" - CFLAGS="-I/opt/local/include $CFLAGS" - LDFLAGS="-L/opt/local/lib $LDFLAGS" -fi -cc="cc" -Mac_Applications="/Applications" -SHFLAGS="-dynamiclib" -DYN_LIB_SUFFIX="dylib" -extralibs="" -GPAC_SH_FLAGS="" -strip="strip -x" -LDFLAGS="$LDFLAGS -read_only_relocs warning" -darwin="yes" -gcc_version=`$cc -v 2>&1 | grep version | cut -d ' ' -f3` -case "$gcc_version" in -*2.95*) -CFLAGS="$CFLAGS -no-cpp-precomp -pipe -fomit-frame-pointer" -;; -3.*) -CFLAGS="$CFLAGS -no-cpp-precomp -pipe -fomit-frame-pointer -mdynamic-no-pic -fno-common" -;; -4.*) -CFLAGS="$CFLAGS -pipe -fomit-frame-pointer -fno-common" -;; -esac -;; - -MINGW32*) -js_flags="-DXP_PC -D_declspec=__declspec" -mingw32="yes" -win32="yes" -extralibs="$extralibs -lws2_32 -lwinmm" -;; - -CYGWIN*) -js_flags=-DXP_PC -extralibs="$extralibs -lws2_32 -lwinmm" -cygwin="yes" -win32="yes" -;; - -Linux) -js_flags="-DXP_UNIX -I/usr/include/js" -LDFLAGS="$LDFLAGS -Wl,--warn-common" -#OSS_LDFLAGS="-laoss" -linux="yes" -case "$cpu" in -sh4) -CFLAGS="$CFLAGS -isystem \"$prefix/include\"" -#LDFLAGS="$LDFLAGS -L$prefix/lib" -;; -esac -;; -*) ;; + SunOS) + make="gmake" + readelf="greadelf" + LDFLAGS="${opt#--extra-ldflags=}" + instflags="" + # check for 64-bit +cat > $TMPC << EOF +#include +int main( void ) { return 0; } +EOF + CFLAGS_NO_LTO=$(echo ${CFLAGS} | sed -e 's/\ -flto[-A-Za-z0-9=]*//g') + $cc ${CFLAGS_NO_LTO} -o $TMPO $TMPC 2>/dev/null && $($readelf -h $TMPO | grep "Class:.*ELF64$" >/dev/null 2>&1) + if test $? -eq 0; then + is_64="yes" + fi + if test "$is_64" = "yes"; then + if test "$cpu" = "x86_64"; then + libdir=lib/amd64 + elif test "$cpu" = "sparc"; then + libdir=lib/sparcv9 + fi + fi + sunos="yes" + need_inet_aton="yes" + extralibs="$extralibs -lsocket -lnsl" + ;; + + FreeBSD) + make="gmake" + LDFLAGS="$LDFLAGS -export-dynamic" + CFLAGS="$CFLAGS -pthread" + GPAC_SH_FLAGS=-pthread + freebsd="yes" + js_flags="-DXP_UNIX -I/usr/include/js" + ;; + + BSD/OS) + extralibs="-lpoll -lgnugetopt -lm" + make="gmake" + ;; + + Darwin) + js_flags=-DXP_MAC + xul_flags=-DXP_MAC + if test -d /sw/bin ; then + alt_macosx_dir="/sw" + CFLAGS="-I/sw/include $CFLAGS" + LDFLAGS="-L/sw/lib $LDFLAGS" + elif test -d /opt/local/bin ; then + alt_macosx_dir="/opt/local" + CFLAGS="-I/opt/local/include $CFLAGS" + LDFLAGS="-L/opt/local/lib $LDFLAGS" + fi + cc="cc" + Mac_Applications="/Applications" + SHFLAGS="-dynamiclib" + DYN_LIB_SUFFIX="dylib" + extralibs="" + GPAC_SH_FLAGS="" + strip="strip -x" + if test "$is_64" = "yes" ; then + LDFLAGS="$LDFLAGS -read_only_relocs warning" + fi + darwin="yes" + gcc_version=`$cc -v 2>&1 | grep version | cut -d ' ' -f3` + case "$gcc_version" in + *2.95*) + CFLAGS="$CFLAGS -no-cpp-precomp -pipe -fomit-frame-pointer" + ;; + 3.*) + CFLAGS="$CFLAGS -no-cpp-precomp -pipe -fomit-frame-pointer -mdynamic-no-pic -fno-common" + ;; + 4.*) + CFLAGS="$CFLAGS -pipe -fomit-frame-pointer -fno-common" + ;; + esac + ;; + + MINGW32*) + js_flags="-DXP_PC -D_declspec=__declspec" + mingw32="yes" + win32="yes" + extralibs="$extralibs -lws2_32 -lwinmm" + ;; + + CYGWIN*) + js_flags=-DXP_PC + extralibs="$extralibs -lws2_32 -lwinmm" + cygwin="yes" + win32="yes" + ;; + + Linux) + js_flags="-DXP_UNIX -I/usr/include/js" + LDFLAGS="$LDFLAGS -Wl,--warn-common" + #OSS_LDFLAGS="-laoss" + linux="yes" + case "$cpu" in + sh4) + CFLAGS="$CFLAGS -isystem \"$prefix/include\"" + #LDFLAGS="$LDFLAGS -L$prefix/lib" + ;; + esac + ;; + *) ;; esac # Defines directory for binaries and libs (ex. for TinyGL) target_bin_dir="" if test "$cross_prefix" = "" ; then -target_bin_dir=`${cc} -v 2>&1 | sed -n '2p' | awk ' {print $2}'`-${cc_orig} + target_bin_dir=`${cc} -v 2>&1 | sed -n '2p' | awk ' {print $2}'`-${cc_orig} else -target_bin_dir=${cross_prefix}${cc_orig} + target_bin_dir=${cross_prefix}${cc_orig} fi #if test "$source_path_used" = "yes" ; then - mkdir -p extra_lib - mkdir -p extra_lib/lib - mkdir -p extra_lib/lib/gcc +mkdir -p extra_lib +mkdir -p extra_lib/lib +mkdir -p extra_lib/lib/gcc #fi #OK check for all local & systems lib @@ -527,11 +544,11 @@ cat > $TMPC << EOF int main( void ) { return 0; } EOF if $cc -o $TMPO $TMPC -fno-strict-aliasing 2> /dev/null ; then -CFLAGS="$CFLAGS -fno-strict-aliasing" + CFLAGS="$CFLAGS -fno-strict-aliasing" fi CPPFLAGS="$CFLAGS" if $cc -o $TMPO $TMPC -lz -Wno-pointer-sign 2> /dev/null ; then -CFLAGS="$CFLAGS -Wno-pointer-sign" + CFLAGS="$CFLAGS -Wno-pointer-sign" fi #look for zlib @@ -541,12 +558,12 @@ int main( void ) { if (zlibVersion() != ZLIB_VERSION) { puts("zlib version diffe EOF has_zlib="no" if $cc -o $TMPO $TMPC -lz 2> /dev/null ; then - has_zlib="system" + has_zlib="system" elif $cc -o $TMPO $TMPC -I"$local_inc/zlib" -L$local_lib -lz 2> /dev/null ; then - has_zlib="local" + has_zlib="local" else - echo "error: zlib not found on system or in local libs" - exit 1 + echo "error: zlib not found on system or in local libs" + exit 1 fi @@ -557,14 +574,14 @@ int main( void ) { return (int) dlopen("foo", 0); } EOF if $cc -o $TMPE $TMPC > /dev/null 2>&1 ; then -dlopen="yes" + dlopen="yes" elif $cc -o $TMPE $TMPC -ldl > /dev/null 2>&1 ; then -GPAC_SH_FLAGS="$GPAC_SH_FLAGS -ldl" + GPAC_SH_FLAGS="$GPAC_SH_FLAGS -ldl" else - if test "$win32" = "no"; then - echo "error: dlopen not found on system" - exit 1 - fi + if test "$win32" = "no"; then + echo "error: dlopen not found on system" + exit 1 + fi fi @@ -573,150 +590,153 @@ fi #spidermonkey test for new API if test "$has_js" = "no" ; then - cat > $TMPCPP << EOF - #include - int main( void ) { JSContext *cx; jsval *rp; return JS_AddValueRoot(cx, rp); } + cat > $TMPCPP << EOF +#include +int main( void ) { JSContext *cx; jsval *rp; return JS_AddValueRoot(cx, rp); } EOF - #try local - js_inc="$local_inc/js" - js_flags="-DXP_UNIX -I$local_inc/js" - if $cpp -o $TMPO $TMPCPP $js_flags -L$local_lib -ljs -lpthread 2> /dev/null ; then - has_js="local" - #dc added - else + #try local + js_inc="$local_inc/js" + js_flags="-DXP_UNIX -I$local_inc/js" + if $cpp -o $TMPO $TMPCPP $js_flags -L$local_lib -ljs -lpthread 2> /dev/null ; then + has_js="local" + #dc added + else -if pkg-config --exists mozilla-js 2> /dev/null ; then - js_flags=`pkg-config --cflags mozilla-js` - js_lib_pkg=`pkg-config --libs mozilla-js` - if $cpp -o $TMPO $TMPCPP $js_flags $js_lib_pkg -lpthread 2> /dev/null ; then - has_js="system" - js_lib=`pkg-config --libs mozilla-js` - fi -fi + if pkg-config --exists mozilla-js 2> /dev/null ; then + js_flags=`pkg-config --cflags mozilla-js` + js_lib_pkg=`pkg-config --libs mozilla-js` + if $cpp -o $TMPO $TMPCPP $js_flags $js_lib_pkg -lpthread 2> /dev/null ; then + has_js="system" + js_lib=`pkg-config --libs mozilla-js` + fi + fi -if test "$has_js" = "no" ; then - #try prefix (DC) - js_inc="$prefix/include/js" - js_flags="-DXP_UNIX -I$prefix/include/js" - if $cpp -o $TMPO $TMPCPP $js_flags -L$prefix/lib -ljs -lpthread 2> /dev/null ; then - has_js="prefix" - #dc added end - else - if $cpp -o $TMPO $TMPCPP $js_flags -ljs -lpthread 2> /dev/null ; then - js_inc="/usr/include" - has_js="system" - elif $cpp -o $TMPO $TMPCPP -DXP_UNIX -I$alt_macosx_dir/include/js -L$alt_macosx_dir/lib -ljs -lpthread 2> /dev/null ; then - has_js="system" - js_flags="-DXP_UNIX -I$alt_macosx_dir/include/js" - js_lib="-L$alt_macosx_dir/lib -ljs" - js_inc="$alt_macosx_dir/include/js" - else - #debian spidermonkey (smjs) - js_flags="-DXP_UNIX -I/usr/include/smjs" - js_inc="/usr/include/smjs" - if $cpp -o $TMPO $TMPCPP $js_flags -lsmjs -lpthread 2> /dev/null ; then - has_js="system" - js_lib="-lsmjs" - else - #debian spidermonkey (mozjs) - js_flags="-DXP_UNIX -I/usr/include/mozjs" - js_inc="/usr/include/mozjs" - if $cpp -o $TMPO $TMPCPP $js_flags -lmozjs -lpthread 2> /dev/null ; then - has_js="system" - js_lib="-lmozjs" - fi + if test "$has_js" = "no" ; then + #try prefix (DC) + js_inc="$prefix/include/js" + js_flags="-DXP_UNIX -I$prefix/include/js" + if $cpp -o $TMPO $TMPCPP $js_flags -L$prefix/lib -ljs -lpthread 2> /dev/null ; then + has_js="prefix" + #dc added end + else + if $cpp -o $TMPO $TMPCPP $js_flags -ljs -lpthread 2> /dev/null ; then + js_inc="/usr/include" + has_js="system" + elif $cpp -o $TMPO $TMPCPP -DXP_UNIX -I$alt_macosx_dir/include/js -L$alt_macosx_dir/lib -ljs -lpthread 2> /dev/null ; then + has_js="system" + js_flags="-DXP_UNIX -I$alt_macosx_dir/include/js" + js_lib="-L$alt_macosx_dir/lib -ljs" + js_inc="$alt_macosx_dir/include/js" + else + #debian spidermonkey (smjs) + js_flags="-DXP_UNIX -I/usr/include/smjs" + js_inc="/usr/include/smjs" + if $cpp -o $TMPO $TMPCPP $js_flags -lsmjs -lpthread 2> /dev/null ; then + has_js="system" + js_lib="-lsmjs" + else + #debian spidermonkey (mozjs) + js_flags="-DXP_UNIX -I/usr/include/mozjs" + js_inc="/usr/include/mozjs" + if $cpp -o $TMPO $TMPCPP $js_flags -lmozjs -lpthread 2> /dev/null ; then + has_js="system" + js_lib="-lmozjs" + fi + fi + fi + fi + fi fi - fi - fi - fi -fi fi if test "$has_js" != "no" ; then -js_flags="-DSPIDERMONKEY_NEW_API $js_flags" -echo "SpiderMonkey new API detected" # (version > 1.8.0rc1) + js_flags="-DSPIDERMONKEY_NEW_API $js_flags" + echo "SpiderMonkey new API detected" # (version > 1.8.0rc1) fi #spidermonkey test for regular API if test "$has_js" = "no" ; then - cat > $TMPC << EOF - #include - int main( void ) { return 0; } + cat > $TMPC << EOF +#include +int main( void ) { return 0; } EOF - #try local - js_inc="$local_inc/js" - js_flags="-DXP_UNIX -I$local_inc/js" - if $cc -o $TMPO $TMPC $js_flags -L$local_lib -ljs 2> /dev/null ; then - has_js="local" - #dc added - else - #try prefix (DC) - js_inc="$prefix/include/js" - js_flags="-DXP_UNIX -I$prefix/include/js" - if $cc -o $TMPO $TMPC $js_flags -L$prefix/lib -ljs 2> /dev/null ; then - has_js="prefix" - #dc added end - else - if pkg-config --exists mozilla-js 2> /dev/null ; then - js_flags=`pkg-config --cflags mozilla-js` - js_lib_pkg=`pkg-config --libs mozilla-js` - if $cc -o $TMPO $TMPC $js_flags $js_lib_pkg -lpthread 2> /dev/null ; then - has_js="system" - js_lib=`pkg-config --libs mozilla-js` + #try local + js_inc="$local_inc/js" + js_flags="-DXP_UNIX -I$local_inc/js" + if test "$cpu" = "sh4" ; then + lm_lib="-lm" fi - fi - if test "$has_js" = "no" ; then - if $cc -o $TMPO $TMPC $js_flags -ljs 2> /dev/null ; then - js_inc="/usr/include" - has_js="system" - elif $cc -o $TMPO $TMPC -DXP_UNIX -I$alt_macosx_dir/include/js -L$alt_macosx_dir/lib -ljs 2> /dev/null ; then - has_js="system" - js_flags="-DXP_UNIX -I$alt_macosx_dir/include/js" - js_lib="-L$alt_macosx_dir/lib -ljs" - js_inc="$alt_macosx_dir/include/js" + if $cc -o $TMPO $TMPC $js_flags $lm_lib -L$local_lib -ljs 2> /dev/null ; then + has_js="local" + #dc added else - #debian spidermonkey (smjs) - js_flags="-DXP_UNIX -I/usr/include/smjs" - js_inc="/usr/include/smjs" - if $cc -o $TMPO $TMPC $js_flags -lsmjs 2> /dev/null ; then - has_js="system" - js_lib="-lsmjs" - else - #debian spidermonkey (mozjs) - js_flags="-DXP_UNIX -I/usr/include/mozjs" - js_inc="/usr/include/mozjs" - if $cc -o $TMPO $TMPC $js_flags -lmozjs 2> /dev/null ; then - has_js="system" - js_lib="-lmozjs" - fi - fi + #try prefix (DC) + js_inc="$prefix/include/js" + js_flags="-DXP_UNIX -I$prefix/include/js" + if $cc -o $TMPO $TMPC $js_flags -L$prefix/lib -ljs 2> /dev/null ; then + has_js="prefix" + #dc added end + else + if pkg-config --exists mozilla-js 2> /dev/null ; then + js_flags=`pkg-config --cflags mozilla-js` + js_lib_pkg=`pkg-config --libs mozilla-js` + if $cc -o $TMPO $TMPC $js_flags $js_lib_pkg -lpthread 2> /dev/null ; then + has_js="system" + js_lib=`pkg-config --libs mozilla-js` + fi + fi + if test "$has_js" = "no" ; then + if $cc -o $TMPO $TMPC $js_flags -ljs 2> /dev/null ; then + js_inc="/usr/include" + has_js="system" + elif $cc -o $TMPO $TMPC -DXP_UNIX -I$alt_macosx_dir/include/js -L$alt_macosx_dir/lib -ljs 2> /dev/null ; then + has_js="system" + js_flags="-DXP_UNIX -I$alt_macosx_dir/include/js" + js_lib="-L$alt_macosx_dir/lib -ljs" + js_inc="$alt_macosx_dir/include/js" + else + #debian spidermonkey (smjs) + js_flags="-DXP_UNIX -I/usr/include/smjs" + js_inc="/usr/include/smjs" + if $cc -o $TMPO $TMPC $js_flags -lsmjs 2> /dev/null ; then + has_js="system" + js_lib="-lsmjs" + else + #debian spidermonkey (mozjs) + js_flags="-DXP_UNIX -I/usr/include/mozjs" + js_inc="/usr/include/mozjs" + if $cc -o $TMPO $TMPC $js_flags -lmozjs 2> /dev/null ; then + has_js="system" + js_lib="-lmozjs" + fi + fi + fi + fi + fi fi - fi - fi - fi fi if test "$has_js" != "no" ; then -if test "$linux" = "yes" ; then -if test "$cpu" != "sh4"; then + if test "$linux" = "yes" ; then + if test "$cpu" != "sh4"; then -#WARNING: there is a bug in MOZJS packages, the MOZILLA_1_8_BRANCH macro is not signaled, there is no way of knowing -#if the lib has been compiled with or without the macro. We currently just decide that if the macro is present -#in the header, it was enabled in the build -if grep "MOZILLA_1_8_BRANCH" $js_inc/jsapi.h > /dev/null 2>&1 ; then -js_flags="-DMOZILLA_1_8_BRANCH $js_flags" -echo "WARNING: Turning on MOZILLA_1_8_BRANCH SpiderMonkey macro" -echo "If you have troubles with scripts in GPAC, disable this macro and recompile" -fi + #WARNING: there is a bug in MOZJS packages, the MOZILLA_1_8_BRANCH macro is not signaled, there is no way of knowing + #if the lib has been compiled with or without the macro. We currently just decide that if the macro is present + #in the header, it was enabled in the build + if grep "MOZILLA_1_8_BRANCH" $js_inc/jsapi.h > /dev/null 2>&1 ; then + js_flags="-DMOZILLA_1_8_BRANCH $js_flags" + echo "WARNING: Turning on MOZILLA_1_8_BRANCH SpiderMonkey macro" + echo "If you have troubles with scripts in GPAC, disable this macro and recompile" + fi -fi -fi + fi + fi fi #fi @@ -734,31 +754,31 @@ cat > $TMPC << EOF int main( void ) { return 0; } EOF if test "$cross_prefix" != "" ; then - ft_cflags="-I$prefix/include " - ft_lflags="-L$prefix/lib -lfreetype" - if $cc -o $TMPO $TMPC $ft_cflags $ft_lflags 2> /dev/null ; then - has_ft="system" - else - ft_cflags="-I$local_inc/freetype" - ft_lflags="-L$local_lib -lfreetype" - if $cc -o $TMPO $TMPC $ft_cflags $ft_lflags 2> /dev/null ; then - has_ft="local" - fi - fi -else - if test "`which freetype-config`" != ""; then - ft_cflags="`freetype-config --cflags`" - ft_lflags="`freetype-config --libs`" + ft_cflags="-I$prefix/include " + ft_lflags="-L$prefix/lib -lfreetype" if $cc -o $TMPO $TMPC $ft_cflags $ft_lflags 2> /dev/null ; then - has_ft="system" + has_ft="system" else - ft_cflags="-I$local_inc/freetype" - ft_lflags="-L$local_lib -lfreetype" - if $cc -o $TMPO $TMPC $ft_cflags $ft_lflags 2> /dev/null ; then - has_ft="local" - fi + ft_cflags="-I$local_inc/freetype" + ft_lflags="-L$local_lib -lfreetype" + if $cc -o $TMPO $TMPC $ft_cflags $ft_lflags 2> /dev/null ; then + has_ft="local" + fi + fi +else + if test "`which freetype-config`" != ""; then + ft_cflags="`freetype-config --cflags`" + ft_lflags="`freetype-config --libs`" + if $cc -o $TMPO $TMPC $ft_cflags $ft_lflags 2> /dev/null ; then + has_ft="system" + else + ft_cflags="-I$local_inc/freetype" + ft_lflags="-L$local_lib -lfreetype" + if $cc -o $TMPO $TMPC $ft_cflags $ft_lflags 2> /dev/null ; then + has_ft="local" + fi + fi fi - fi fi #end freetype test @@ -774,13 +794,13 @@ int main( void ) { return 0; } EOF if test "$win32" = "yes" ; then -LINK_SSL="-lssleay32 -leay32" + LINK_SSL="-lssleay32 -leay32" else -LINK_SSL="-lssl -lcrypto" + LINK_SSL="-lssl -lcrypto" fi if $cc -o $TMPO $TMPC $LINK_SSL 2> /dev/null ; then -has_ssl="yes" + has_ssl="yes" fi @@ -792,41 +812,41 @@ int main( void ) { return 0; } EOF if test "$cross_prefix" != "" ; then - if test "`which $prefix/bin/jpeg-config`" != ""; then - jpeg_cflags="`$prefix/bin/jpeg-config --cflags`" - jpeg_lflags="`$prefix/bin/jpeg-config --libs`" - if $cc -o $TMPO $TMPC $jpeg_cflags $jpeg_lflags 2> /dev/null ; then - has_jpeg="system" - else - jpeg_cflags="-I$local_inc/jpeg" - jpeg_lflags="-L$local_lib -ljpeg" - if $cc -o $TMPO $TMPC $jpeg_cflags $jpeg_lflags 2> /dev/null ; then - has_jpeg="local" - fi - fi - else - jpeg_cflags="-I$prefix/include" - jpeg_lflags="-L$prefix/lib -ljpeg" - if $cc -o $TMPO $TMPC $jpeg_cflags $jpeg_lflags 2> /dev/null ; then - has_jpeg="system" + if test "`which $prefix/bin/jpeg-config`" != ""; then + jpeg_cflags="`$prefix/bin/jpeg-config --cflags`" + jpeg_lflags="`$prefix/bin/jpeg-config --libs`" + if $cc -o $TMPO $TMPC $jpeg_cflags $jpeg_lflags 2> /dev/null ; then + has_jpeg="system" + else + jpeg_cflags="-I$local_inc/jpeg" + jpeg_lflags="-L$local_lib -ljpeg" + if $cc -o $TMPO $TMPC $jpeg_cflags $jpeg_lflags 2> /dev/null ; then + has_jpeg="local" + fi + fi else - jpeg_cflags="-I$local_inc/jpeg" - jpeg_lflags="-L$local_lib -ljpeg" - if $cc -o $TMPO $TMPC $jpeg_cflags $jpeg_lflags 2> /dev/null ; then - has_jpeg="local" - fi + jpeg_cflags="-I$prefix/include" + jpeg_lflags="-L$prefix/lib -ljpeg" + if $cc -o $TMPO $TMPC $jpeg_cflags $jpeg_lflags 2> /dev/null ; then + has_jpeg="system" + else + jpeg_cflags="-I$local_inc/jpeg" + jpeg_lflags="-L$local_lib -ljpeg" + if $cc -o $TMPO $TMPC $jpeg_cflags $jpeg_lflags 2> /dev/null ; then + has_jpeg="local" + fi + fi fi - fi else - if $cc -o $TMPO $TMPC -ljpeg 2> /dev/null ; then - has_jpeg="system" - elif test "$alt_macosx_dir" != "" ; then - if cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -ljpeg 2> /dev/null ; then - has_jpeg="system" - fi - elif $cc -o $TMPO $TMPC -I$local_inc/jpeg -L$local_lib -ljpeg 2> /dev/null ; then - has_jpeg="local" - fi + if $cc -o $TMPO $TMPC -ljpeg 2> /dev/null ; then + has_jpeg="system" + elif test "$alt_macosx_dir" != "" ; then + if cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -ljpeg 2> /dev/null ; then + has_jpeg="system" + fi + elif $cc -o $TMPO $TMPC -I$local_inc/jpeg -L$local_lib -ljpeg 2> /dev/null ; then + has_jpeg="local" + fi fi #look for OpenJPEG support @@ -837,13 +857,13 @@ int main( void ) { return 0; } EOF if $cc -o $TMPO $TMPC -lopenjpeg 2> /dev/null ; then -has_openjpeg="system" + has_openjpeg="system" elif test "$alt_macosx_dir" != "" ; then - if cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -ljpeg 2> /dev/null ; then - has_openjpeg="system" - fi + if cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -ljpeg 2> /dev/null ; then + has_openjpeg="system" + fi elif $cc -o $TMPO $TMPC -I$local_inc/openjpeg -L$local_lib -lopenjpeg 2> /dev/null ; then -has_openjpeg="local" + has_openjpeg="local" fi #look for PNG support @@ -853,29 +873,29 @@ int main( void ) { return 0; } EOF if test "$cross_prefix" != "" ; then - png_cflags="-I$prefix/include" - png_lflags="-L$prefix/lib -lpng -lz" - #-nostdlib prevents from searching standard compiler libraries - #if $cc -o $TMPO $TMPC -nostdlib $png_cflags $png_lflags 2> /dev/null ; then - if $cc -o $TMPO $TMPC $png_cflags $png_lflags 2> /dev/null ; then - has_png="system" - else - png_cflags="-I$local_inc/png" - png_lflags="-L$local_lib -lpng" - if $cc -o $TMPO $TMPC $png_cflags $png_lflags 2> /dev/null ; then - has_png="local" - fi - fi + png_cflags="-I$prefix/include" + png_lflags="-L$prefix/lib -lpng -lz" + #-nostdlib prevents from searching standard compiler libraries + #if $cc -o $TMPO $TMPC -nostdlib $png_cflags $png_lflags 2> /dev/null ; then + if $cc -o $TMPO $TMPC $png_cflags $png_lflags 2> /dev/null ; then + has_png="system" + else + png_cflags="-I$local_inc/png" + png_lflags="-L$local_lib -lpng" + if $cc -o $TMPO $TMPC $png_cflags $png_lflags 2> /dev/null ; then + has_png="local" + fi + fi else - if $cc -o $TMPO $TMPC -lpng -lz 2> /dev/null ; then - has_png="system" - elif test "$alt_macosx_dir" != "" ; then - if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -lpng 2> /dev/null ; then - has_png="system" - fi - elif $cc -o $TMPO $TMPC -I$local_inc/png -L$local_lib -lpng 2> /dev/null ; then - has_png="local" - fi + if $cc -o $TMPO $TMPC -lpng -lz 2> /dev/null ; then + has_png="system" + elif test "$alt_macosx_dir" != "" ; then + if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -lpng 2> /dev/null ; then + has_png="system" + fi + elif $cc -o $TMPO $TMPC -I$local_inc/png -L$local_lib -lpng 2> /dev/null ; then + has_png="local" + fi fi #look for MAD support @@ -885,13 +905,13 @@ int main( void ) { return 0; } EOF if $cc -o $TMPO $TMPC -lmad 2> /dev/null ; then -has_mad="system" + has_mad="system" elif test "$alt_macosx_dir" != "" ; then - if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -lmad 2> /dev/null ; then - has_mad="system" - fi + if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -lmad 2> /dev/null ; then + has_mad="system" + fi elif $cc -o $TMPO $TMPC -I$local_inc/mad -L$local_lib -lmad 2> /dev/null ; then -has_mad="local" + has_mad="local" fi #look for A52DEC support @@ -904,13 +924,13 @@ int main( void ) { return 0; } EOF if $cc -o $TMPO $TMPC -la52 2> /dev/null ; then -has_a52="system" + has_a52="system" elif test "$alt_macosx_dir" != "" ; then - if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -la52 2> /dev/null ; then - has_a52="system" - fi + if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -la52 2> /dev/null ; then + has_a52="system" + fi elif $cc -o $TMPO $TMPC -I$local_inc -L$local_lib -la52 2> /dev/null ; then -has_a52="local" + has_a52="local" fi #look for XVID support @@ -920,21 +940,21 @@ int main( void ) { return 0; } EOF if test "$cross_prefix" != "" ; then - if $cc -o $TMPO $TMPC -I$prefix/include -L$prefix/lib -lxvidcore -lpthread 2> /dev/null ; then - has_xvid="system" - elif $cc -o $TMPO $TMPC -I$local_inc/xvid -L$local_lib -lxvidcore -lpthread 2> /dev/null ; then - has_xvid="local" - fi + if $cc -o $TMPO $TMPC -I$prefix/include -L$prefix/lib -lxvidcore -lpthread 2> /dev/null ; then + has_xvid="system" + elif $cc -o $TMPO $TMPC -I$local_inc/xvid -L$local_lib -lxvidcore -lpthread 2> /dev/null ; then + has_xvid="local" + fi else - if $cc -o $TMPO $TMPC -lxvidcore -lpthread 2> /dev/null ; then - has_xvid="system" - elif test "$alt_macosx_dir" != "" ; then - if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -lxvidcore -lpthread 2> /dev/null ; then - has_xvid="system" - fi - elif $cc -o $TMPO $TMPC -I$local_inc/xvid -L$local_lib -lxvidcore -lpthread 2> /dev/null ; then - has_xvid="local" - fi + if $cc -o $TMPO $TMPC -lxvidcore -lpthread 2> /dev/null ; then + has_xvid="system" + elif test "$alt_macosx_dir" != "" ; then + if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -lxvidcore -lpthread 2> /dev/null ; then + has_xvid="system" + fi + elif $cc -o $TMPO $TMPC -I$local_inc/xvid -L$local_lib -lxvidcore -lpthread 2> /dev/null ; then + has_xvid="local" + fi fi #look for FAAD support @@ -944,75 +964,69 @@ int main( void ) { return 0; } EOF if $cc -o $TMPO $TMPC -lfaad -lm 2> /dev/null ; then -has_faad="system" + has_faad="system" elif test "$alt_macosx_dir" != "" ; then - if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -lfaad 2> /dev/null ; then - has_faad="system" - fi + if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -lfaad 2> /dev/null ; then + has_faad="system" + fi elif $cc -o $TMPO $TMPC -I$local_inc/faad -L$local_lib -lfaad -lm 2> /dev/null ; then -has_faad="local" + has_faad="local" fi #look for FFMPEG support if pkg-config --exists libavcodec libavformat libswscale 2> /dev/null ; then - - ffmpeg_cflags=`pkg-config --cflags libavcodec libavformat libswscale libavutil` - ffmpeg_lflags=`pkg-config --libs libavcodec libavformat libswscale libavutil` - has_ffmpeg="system" - -else + ffmpeg_cflags=`pkg-config --cflags libavcodec libavformat libswscale libavutil` + ffmpeg_lflags=`pkg-config --libs libavcodec libavformat libswscale libavutil` + has_ffmpeg="system" +fi cat > $TMPC << EOF #include int main( void ) { return 0; } EOF -if $cc -o $TMPO $TMPC 2> /dev/null ; then -old_ffmpeg_inc="no" +if $cc -o $TMPO $TMPC $ffmpeg_cflags $ffmpeg_lflags 2> /dev/null ; then + old_ffmpeg_inc="no" else + old_ffmpeg_inc="yes" -old_ffmpeg_inc="yes" - -cat > $TMPC << EOF + cat > $TMPC << EOF #include int main( void ) { return 0; } EOF - fi - -if test "$cross_prefix" != "" ; then - if $cc -o $TMPO $TMPC -I$prefix/include -L$prefix/lib -lz -lavcodec -lavformat -lavutil 2> /dev/null ; then - has_ffmpeg="system" - ffmpeg_cflags="-I$prefix/include" - ffmpeg_lflags="-L$prefix/lib -lz -lavcodec -lavformat -lavutil" - else - if $cc -o $TMPO $TMPC -I$local_inc -L$local_lib -lz -lavcodec -lavformat 2> /dev/null ; then - has_ffmpeg="local" - ffmpeg_cflags="-I$local_inc/include" - ffmpeg_lflags="-L$local_lib/lib -lz -lavcodec -lavformat -lavutil" - echo OK - fi - fi +if test "$cross_prefix" != "" ; then + if $cc -o $TMPO $TMPC -I$prefix/include -L$prefix/lib -lz -lavcodec -lavformat -lavutil 2> /dev/null ; then + has_ffmpeg="system" + ffmpeg_cflags="-I$prefix/include" + ffmpeg_lflags="-L$prefix/lib -lz -lavcodec -lavformat -lavutil" + else + if $cc -o $TMPO $TMPC -I$local_inc -L$local_lib -lz -lavcodec -lavformat 2> /dev/null ; then + has_ffmpeg="local" + ffmpeg_cflags="-I$local_inc/include" + ffmpeg_lflags="-L$local_lib/lib -lz -lavcodec -lavformat -lavutil" + echo OK + fi + fi else - if $cc -o $TMPO $TMPC -lz -lavcodec -lavformat 2> /dev/null ; then - has_ffmpeg="system" - elif test "$alt_macosx_dir" != "" ; then - if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -lz -lavcodec -lavformat 2> /dev/null ; then - has_ffmpeg="system" - ffmpeg_cflags="-I$alt_macosx_dir/include" - ffmpeg_lflags="-L$alt_macosx_dir/lib -lz -lavcodec -lavformat" + if $cc -o $TMPO $TMPC -lz -lavcodec -lavformat 2> /dev/null ; then + has_ffmpeg="system" + elif test "$alt_macosx_dir" != "" ; then + if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -lz -lavcodec -lavformat 2> /dev/null ; then + has_ffmpeg="system" + ffmpeg_cflags="-I$alt_macosx_dir/include" + ffmpeg_lflags="-L$alt_macosx_dir/lib -lz -lavcodec -lavformat" + fi + elif $cc -o $TMPO $TMPC -I$local_inc -L$local_lib -lz -lavcodec -lavformat 2> /dev/null ; then + has_ffmpeg="local" + ffmpeg_cflags="-I$local_inc" + ffmpeg_lflags="-L$local_lib -lz -lavcodec -lavformat -lavutil" fi - elif $cc -o $TMPO $TMPC -I$local_inc -L$local_lib -lz -lavcodec -lavformat 2> /dev/null ; then - has_ffmpeg="local" - ffmpeg_cflags="-I$local_inc" - ffmpeg_lflags="-L$local_lib -lz -lavcodec -lavformat -lavutil" - fi fi -fi #look for vorbis support cat > $TMPC << EOF @@ -1021,13 +1035,13 @@ int main( void ) { return 0; } EOF if $cc -o $TMPO $TMPC -lvorbis 2> /dev/null ; then -has_vorbis="system" + has_vorbis="system" elif test "$alt_macosx_dir" != "" ; then - if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -lvorbis 2> /dev/null ; then - has_vorbis="system" - fi + if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -lvorbis 2> /dev/null ; then + has_vorbis="system" + fi elif $cc -o $TMPO $TMPC -I$local_inc -L$local_lib -lvorbis -lm 2> /dev/null ; then -has_vorbis="local" + has_vorbis="local" fi #look for theora support @@ -1037,13 +1051,13 @@ int main( void ) { return 0; } EOF if $cc -o $TMPO $TMPC -ltheora 2> /dev/null ; then -has_theora="system" + has_theora="system" elif test "$alt_macosx_dir" != "" ; then - if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -ltheora -logg 2> /dev/null ; then - has_theora="system" - fi + if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -ltheora -logg 2> /dev/null ; then + has_theora="system" + fi elif $cc -o $TMPO $TMPC -I$local_inc -L$local_lib -ltheora -logg -lm 2> /dev/null ; then -has_theora="local" + has_theora="local" fi #look for OGG support @@ -1053,16 +1067,16 @@ int main( void ) { return 0; } EOF if $cc -o $TMPO $TMPC -logg 2> /dev/null ; then -has_ogg="system" + has_ogg="system" elif test "$alt_macosx_dir" != "" ; then - if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -logg 2> /dev/null ; then - has_ogg="system" - fi + if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -logg 2> /dev/null ; then + has_ogg="system" + fi elif $cc -o $TMPO $TMPC -I$local_inc -L$local_lib -logg -lm 2> /dev/null ; then -has_ogg="local" + has_ogg="local" else -has_vorbis=no -has_theora=no + has_vorbis=no + has_theora=no fi @@ -1070,19 +1084,19 @@ fi if test "$darwin" = "yes" ; then -cat > $TMPC << EOF + cat > $TMPC << EOF #include int main( void ) { return 0; } EOF -if $cc -o $TMPO $TMPC -DLIBOSS_INTERNAL -I$alt_macosx_dir/include/ -I$alt_macosx_dir/include/liboss -L$alt_macosx_dir/lib -loss 2> /dev/null ; then -has_oss_audio="SYS" -OSS_CFLAGS="-DLIBOSS_INTERNAL -I$alt_macosx_dir/include/ -I$alt_macosx_dir/include/liboss" -OSS_LDFLAGS="-L$alt_macosx_dir/lib -loss" -fi + if $cc -o $TMPO $TMPC -DLIBOSS_INTERNAL -I$alt_macosx_dir/include/ -I$alt_macosx_dir/include/liboss -L$alt_macosx_dir/lib -loss 2> /dev/null ; then + has_oss_audio="SYS" + OSS_CFLAGS="-DLIBOSS_INTERNAL -I$alt_macosx_dir/include/ -I$alt_macosx_dir/include/liboss" + OSS_LDFLAGS="-L$alt_macosx_dir/lib -loss" + fi else -cat > $TMPC << EOF + cat > $TMPC << EOF #include #include #include @@ -1090,20 +1104,20 @@ cat > $TMPC << EOF int main( void ) { return 0; } EOF -if $cc -o $TMPO $TMPC 2> /dev/null ; then -has_oss_audio="SYS" -else -cat > $TMPC << EOF + if $cc -o $TMPO $TMPC 2> /dev/null ; then + has_oss_audio="SYS" + else + cat > $TMPC << EOF #include #include #include #include int main( void ) { return 0; } EOF -if $cc -o $TMPO $TMPC 2> /dev/null ; then -has_oss_audio="YES" -fi -fi + if $cc -o $TMPO $TMPC 2> /dev/null ; then + has_oss_audio="YES" + fi + fi fi @@ -1114,53 +1128,53 @@ wx_too_old="no" if type wx-config >/dev/null 2>&1; then -wx_version=`wx-config --version | sed 's/[^0-9]//g'` + wx_version=`wx-config --version | sed 's/[^0-9]//g'` -if test "$wx_version" -lt 250 ; then -wx_too_old="yes" -has_wx="yes" -else -if test "$wx_version" -lt 260 ; then -has_wx="yes" -wx_cflags=`wx-config --cppflags` -wx_lflags=`wx-config --libs` -else -has_wx="yes" -wx_cflags=`wx-config --cppflags core, base` -wx_lflags=`wx-config --libs core, base` -fi + if test "$wx_version" -lt 250 ; then + wx_too_old="yes" + has_wx="yes" + else + if test "$wx_version" -lt 260 ; then + has_wx="yes" + wx_cflags=`wx-config --cppflags` + wx_lflags=`wx-config --libs` + else + has_wx="yes" + wx_cflags=`wx-config --cppflags core, base` + wx_lflags=`wx-config --libs core, base` + fi -if test "$darwin" = "yes" ; then -wx_lflags="-Wl,-bind_at_load $wx_lflags -lstdc++" #10.4 needs it, not sure about 10.3 -fi + if test "$darwin" = "yes" ; then + wx_lflags="-Wl,-bind_at_load $wx_lflags -lstdc++" #10.4 needs it, not sure about 10.3 + fi -fi + fi -cat > $TMPCPP << EOF + cat > $TMPCPP << EOF #include int main( void ) { return 0; } EOF -if $cc $wx_cflags -o $TMPO $TMPCPP $wx_lflags > /dev/null 2>&1 ; then -wx_version=`wx-config --version | sed 's/[^0-9]//g'` -if test "$wx_version" -lt 254 ; then -wx_too_old="yes" -else -has_wx="yes" -fi -fi + if $cc $wx_cflags -o $TMPO $TMPCPP $wx_lflags > /dev/null 2>&1 ; then + wx_version=`wx-config --version | sed 's/[^0-9]//g'` + if test "$wx_version" -lt 254 ; then + wx_too_old="yes" + else + has_wx="yes" + fi + fi fi #end wx test # If svg isn't disabled if test "$disable_svg" != "yes"; then -# Then we check libxm2 presence via pkg-config - if pkg-config libxml-2.0 --exists > /dev/null 2>&1 ; then - libxml2_cflags=`pkg-config libxml-2.0 --cflags` - libxml2_lib_flags=`pkg-config libxml-2.0 --libs` - has_libxml2="yes" - fi + # Then we check libxm2 presence via pkg-config + if pkg-config libxml-2.0 --exists > /dev/null 2>&1 ; then + libxml2_cflags=`pkg-config libxml-2.0 --cflags` + libxml2_lib_flags=`pkg-config libxml-2.0 --libs` + has_libxml2="yes" + fi fi @@ -1171,16 +1185,16 @@ cat > $TMPC << EOF #include #include int main( void ) { - struct sockaddr_storage saddr; - struct ipv6_mreq mreq6; - getaddrinfo(0,0,0,0); - getnameinfo(0,0,0,0,0,0,0); - IN6_IS_ADDR_MULTICAST( (struct in6_addr *) 0); +struct sockaddr_storage saddr; +struct ipv6_mreq mreq6; +getaddrinfo(0,0,0,0); +getnameinfo(0,0,0,0,0,0,0); +IN6_IS_ADDR_MULTICAST( (struct in6_addr *) 0); } EOF if $cc -o $TMPE $TMPC > /dev/null 2>&1 ; then -has_ipv6="yes" + has_ipv6="yes" fi # look for DVB4linux @@ -1192,7 +1206,7 @@ int main( void ) { EOF if $cc -o $TMPE $TMPC > /dev/null 2>&1 ; then -has_dvb4linux="yes" + has_dvb4linux="yes" fi # look for XMLRPC @@ -1205,7 +1219,7 @@ int main( void ) { EOF if $cc -o $TMPE $TMPC > /dev/null 2>&1 ; then -has_xmlrpc="yes" + has_xmlrpc="yes" fi # look for alsa @@ -1216,7 +1230,7 @@ int main( void ) { EOF if $cc -o $TMPE $TMPC > /dev/null 2>&1 ; then -has_alsa="yes" + has_alsa="yes" fi # look for pulseaudio @@ -1226,7 +1240,7 @@ int main( void ) { } EOF if $cc -o $TMPE $TMPC > /dev/null 2>&1 ; then -has_pulseaudio="yes" + has_pulseaudio="yes" fi #look for jack @@ -1236,7 +1250,18 @@ int main( void ) { } EOF if $cc -o $TMPE $TMPC > /dev/null 2>&1 ; then -has_jack="yes" + has_jack="yes" +fi + +#look for directfb support +cat > $TMPC << EOF +#include +int main( void ) { return 0; } +EOF +directfb_inc="/opt/STM/STLinux-2.3/devkit/sh4/target/usr/include/directfb" +directfb_lib="-ldirectfb -lfusion -ldirect" +if $cc -o $TMPO $TMPC -I$directfb_inc -L$directfb_lib 2> /dev/null ; then + has_directfb="yes" fi #look for X11 shared memory support @@ -1245,10 +1270,10 @@ cat > $TMPC << EOF int main( void ) { return 0; } EOF if $cc -o $TMPO $TMPC -I$X11_PATH/include -L$X11_PATH/lib 2> /dev/null ; then -has_x11="yes" + has_x11="yes" -#look for X11 shared memory support -cat > $TMPC << EOF + #look for X11 shared memory support + cat > $TMPC << EOF #include #include #include @@ -1256,271 +1281,271 @@ cat > $TMPC << EOF int main( void ) { return 0; } EOF -if $cc -o $TMPO $TMPC -I$X11_PATH/include -L$X11_PATH/lib 2> /dev/null ; then -has_x11_shm="yes" -fi + if $cc -o $TMPO $TMPC -I$X11_PATH/include -L$X11_PATH/lib 2> /dev/null ; then + has_x11_shm="yes" + fi -#look for XVideo support -cat > $TMPC << EOF + #look for XVideo support + cat > $TMPC << EOF #include #include #include int main( void ) { return 0; } EOF -if $cc -o $TMPO $TMPC -I$X11_PATH/include -L$X11_PATH/lib 2> /dev/null ; then -has_x11_xv="yes" -fi + if $cc -o $TMPO $TMPC -I$X11_PATH/include -L$X11_PATH/lib 2> /dev/null ; then + has_x11_xv="yes" + fi fi for opt do - case "$opt" in - --sdl-cfg=*) sdl_path=`echo $opt | cut -d '=' -f 2`; sdl_local="yes" - ;; - --enable-sdl-static=*) sdl_static="yes" - ;; - --enable-jack=*) has_jack="yes" - ;; - --X11-path=*) X11_PATH=`echo $opt | cut -d '=' -f 2` - ;; - --dxsdk-path=*) dxsdk_path=`echo $opt | cut -d '=' -f 2` - ;; - --xulsdk-path=*) xulsdk_path=`echo $opt | cut -d '=' -f 2` - ;; - --mozdir=*) moz_path=`echo $opt | cut -d '=' -f 2` - ;; - --enable-amr-nb-fixed) has_amr_nb_fixed="yes" - ;; - --disable-pulseaudio=*) has_pulseaudio="no" - ;; - --enable-amr-nb) has_amr_nb="yes" - ;; - --enable-amr-wb) has_amr_wb="yes" - ;; - --enable-amr) has_amr_wb="yes"; has_amr_nb="yes" - ;; - --disable-oggvorbis) has_oggvorbis="no" - ;; - --disable-jack=*) has_jack="no" - ;; - --disable-alsa=*) has_alsa="no" - ;; - --enable-debug) debuginfo="yes"; no_gcc_opt="yes" - ;; - --enable-gprof) gprof_build="yes"; - ;; - --enable-static-bin) static_build="yes"; - ;; - --enable-pic) want_pic="yes"; - ;; - --disable-opt) no_gcc_opt="yes" - ;; - --disable-ipv6) has_ipv6="no" - ;; - --disable-wx) has_wx="no" - ;; - --disable-oss-audio) has_oss_audio="no" - ;; - --disable-x11-shm) has_x11_shm="no" - ;; - --disable-x11-xv) has_x11_xv="no" - ;; - --enable-fixed-point) use_fixed_point="yes" - ;; - --strip) INSTFLAGS="-s $INSTFLAGS" - ;; - --std-allocator) use_std_alloc="yes" - ;; - --track-memory) use_memory_tracking="yes" - ;; - --enable-tinygl) enable_tinygl="yes" - ;; - --disable-ssl) has_ssl="no" - ;; - --enable-depth) enable_depth_compositor="yes" - ;; - --static-mp4box) static_mp4box="yes" - ;; - --use-faad=*) has_faad=${opt#--use-faad=} - ;; - --use-js=*) has_js=${opt#--use-js=} - ;; - --use-ft=*) has_ft=${opt#--use-ft=} - ;; - --use-mad=*) has_mad=${opt#--use-mad=} - ;; - --use-a52=*) has_a52=${opt#--use-a52=} - ;; - --use-xvid=*) has_xvid=${opt#--use-xvid=} - ;; - --use-jpeg=*) has_jpeg=${opt#--use-jpeg=} - ;; - --use-ffmpeg=*) has_ffmpeg=${opt#--use-ffmpeg=} - ;; - --use-png=*) tmp_has_png=${opt#--use-png=} -if test "$tmp_has_png" = "system" ; then - if test "$has_png" != "system" ; then - if test "$cross_prefix" != "" ; then - echo - echo "WARNING: PNG has been forced to system, but we are cross-compiling, it will have to be on target" - echo - else - echo - echo "WARNING!! : PNG has been forced to system even though it hasn't been found in this host" - echo - fi - fi -fi -has_png=$tmp_has_png - ;; - --use-ogg=*) has_ogg=${opt#--use-ogg=} - ;; - --use-vorbis=*) has_vorbis=${opt#--use-vorbis=} - ;; - --use-theora=*) has_theora=${opt#--use-theora=} - ;; - --use-openjpeg=*) has_openjpeg=${opt#--use-openjpeg=} - ;; - --enable-joystick) enable_joystick="yes" - ;; - --enable-pulseaudio=*) has_pulseaudio="yes" - ;; - - --disable-all) has_pulseaudio="no"; disable_3d="yes"; disable_svg="yes"; disable_vrml="yes"; disable_od="yes"; disable_bifs="yes"; disable_bifs_enc="yes"; disable_laser="yes"; disable_beng="yes"; disable_qtvr="yes"; disable_avi="yes"; disable_ogg="yes"; disable_m2ps="yes"; disable_m2ts="yes"; disable_m2ts_mux="yes"; disable_parsers="yes"; disable_import="yes"; disable_export="yes"; disable_swf="yes"; disable_scene_stats="yes"; disable_scene_dump="yes"; disable_scene_encode="yes"; disable_loader_isoff="yes"; disable_od_dump="yes"; disable_mcrypt="yes"; disable_isoff="yes"; disable_isoff_write="yes"; disable_isoff_hint="yes"; disable_isoff_frag="yes"; disable_streaming="yes"; disable_x3d="yes"; disable_loader_bt="yes"; disable_loader_xmt="yes" - ;; - - --disable-3d) disable_3d="yes" - ;; - --enable-3d) disable_3d="no" - ;; - --disable-svg) disable_svg="yes" - ;; - --enable-svg) disable_svg="no" - ;; - --disable-vrml) disable_vrml="yes" - ;; - --enable-vrml) disable_vrml="no" - ;; - --disable-x3d) disable_x3d="yes" - ;; - --enable-x3d) disable_x3d="no" - ;; - --disable-odf) disable_od="yes" - ;; - --enable-odf) disable_od="no" - ;; - --disable-bifs) disable_bifs="yes" - ;; - --enable-bifs) disable_bifs="no" - ;; - --disable-bifs-enc) disable_bifs_enc="yes" - ;; - --enable-bifs-enc) disable_bifs_enc="no" - ;; - --disable-laser) disable_laser="yes" - ;; - --enable-laser) disable_laser="no" - ;; - --disable-beng) disable_beng="yes" - ;; - --enable-beng) disable_beng="no" - ;; - --disable-qtvr) disable_qtvr="yes" - ;; - --enable-qtvr) disable_qtvr="no" - ;; - --disable-avi) disable_avi="yes" - ;; - --enable-avi) disable_avi="no" - ;; - --disable-ogg) disable_ogg="yes" - ;; - --enable-ogg) disable_ogg="no" - ;; - --disable-m2ps) disable_m2ps="yes" - ;; - --enable-m2ps) disable_m2ps="no" - ;; - --disable-m2ts) disable_m2ts="yes" - ;; - --enable-m2ts) disable_m2ts="no" - ;; - --disable-m2ts-mux) disable_m2ts_mux="yes" - ;; - --enable-m2ts-mux) disable_m2ts_mux="no" - ;; - --disable-parsers) disable_parsers="yes" - ;; - --enable-parsers) disable_parsers="no" - ;; - --disable-import) disable_import="yes" - ;; - --enable-import) disable_import="no" - ;; - --disable-export) disable_export="yes" - ;; - --enable-export) disable_export="no" - ;; - --disable-swf) disable_swf="yes" - ;; - --enable-swf) disable_swf="no" - ;; - --disable-scene-stats) disable_scene_stats="yes" - ;; - --enable-scene-stats) disable_scene_stats="no" - ;; - --disable-scene-dump) disable_scene_dump="yes" - ;; - --enable-scene-dump) disable_scene_dump="no" - ;; - --disable-scene-encode) disable_scene_encode="yes" - ;; - --enable-scene-encode) disable_scene_encode="no" - ;; - --disable-loader-isoff) disable_loader_isoff="yes" - ;; - --enable-loader-isoff) disable_loader_isoff="no" - ;; - --disable-loader-bt) disable_loader_bt="yes" - ;; - --enable-loader-bt) disable_loader_bt="no" - ;; - --disable-loader-xmt) disable_loader_xmt="yes" - ;; - --enable-loader-xmt) disable_loader_xmt="no" - ;; - --disable-od-dump) disable_od_dump="yes" - ;; - --enable-od-dump) disable_od_dump="no" - ;; - --disable-mcrypt) disable_mcrypt="yes" - ;; - --enable-mcrypt) disable_mcrypt="no" - ;; - --disable-isoff) disable_isoff="yes" - ;; - --enable-isoff) disable_isoff="no" - ;; - --disable-isoff-write) disable_isoff_write="yes" - ;; - --enable-isoff-write) disable_isoff_write="no" - ;; - --disable-isoff-hint) disable_isoff_hint="yes" - ;; - --enable-isoff-hint) disable_isoff_hint="no" - ;; - --disable-isoff-frag) disable_isoff_frag="yes" - ;; - --enable-isoff-frag) disable_isoff_frag="no" - ;; - --disable-streaming) disable_streaming="yes" - ;; - --enable-streaming) disable_streaming="no" - ;; - - - esac + case "$opt" in + --sdl-cfg=*) sdl_path=`echo $opt | cut -d '=' -f 2`; sdl_local="yes" + ;; + --enable-sdl-static=*) sdl_static="yes" + ;; + --enable-jack=*) has_jack="yes" + ;; + --X11-path=*) X11_PATH=`echo $opt | cut -d '=' -f 2` + ;; + --dxsdk-path=*) dxsdk_path=`echo $opt | cut -d '=' -f 2` + ;; + --xulsdk-path=*) xulsdk_path=`echo $opt | cut -d '=' -f 2` + ;; + --mozdir=*) moz_path=`echo $opt | cut -d '=' -f 2` + ;; + --enable-amr-nb-fixed) has_amr_nb_fixed="yes" + ;; + --disable-pulseaudio=*) has_pulseaudio="no" + ;; + --enable-amr-nb) has_amr_nb="yes" + ;; + --enable-amr-wb) has_amr_wb="yes" + ;; + --enable-amr) has_amr_wb="yes"; has_amr_nb="yes" + ;; + --disable-oggvorbis) has_oggvorbis="no" + ;; + --disable-jack=*) has_jack="no" + ;; + --disable-alsa=*) has_alsa="no" + ;; + --enable-debug) debuginfo="yes"; no_gcc_opt="yes" + ;; + --enable-gprof) gprof_build="yes"; + ;; + --enable-static-bin) static_build="yes"; + ;; + --enable-pic) want_pic="yes"; + ;; + --disable-opt) no_gcc_opt="yes" + ;; + --disable-ipv6) has_ipv6="no" + ;; + --disable-wx) has_wx="no" + ;; + --disable-oss-audio) has_oss_audio="no" + ;; + --disable-x11-shm) has_x11_shm="no" + ;; + --disable-x11-xv) has_x11_xv="no" + ;; + --enable-fixed-point) use_fixed_point="yes" + ;; + --strip) INSTFLAGS="-s $INSTFLAGS" + ;; + --std-allocator) use_std_alloc="yes" + ;; + --track-memory) use_memory_tracking="yes" + ;; + --enable-tinygl) enable_tinygl="yes" + ;; + --disable-ssl) has_ssl="no" + ;; + --enable-depth) enable_depth_compositor="yes" + ;; + --static-mp4box) static_mp4box="yes" + ;; + --use-faad=*) has_faad=${opt#--use-faad=} + ;; + --use-js=*) has_js=${opt#--use-js=} + ;; + --use-ft=*) has_ft=${opt#--use-ft=} + ;; + --use-mad=*) has_mad=${opt#--use-mad=} + ;; + --use-a52=*) has_a52=${opt#--use-a52=} + ;; + --use-xvid=*) has_xvid=${opt#--use-xvid=} + ;; + --use-jpeg=*) has_jpeg=${opt#--use-jpeg=} + ;; + --use-ffmpeg=*) has_ffmpeg=${opt#--use-ffmpeg=} + ;; + --use-png=*) tmp_has_png=${opt#--use-png=} + if test "$tmp_has_png" = "system" ; then + if test "$has_png" != "system" ; then + if test "$cross_prefix" != "" ; then + echo + echo "WARNING: PNG has been forced to system, but we are cross-compiling, it will have to be on target" + echo + else + echo + echo "WARNING!! : PNG has been forced to system even though it hasn't been found in this host" + echo + fi + fi + fi + has_png=$tmp_has_png + ;; + --use-ogg=*) has_ogg=${opt#--use-ogg=} + ;; + --use-vorbis=*) has_vorbis=${opt#--use-vorbis=} + ;; + --use-theora=*) has_theora=${opt#--use-theora=} + ;; + --use-openjpeg=*) has_openjpeg=${opt#--use-openjpeg=} + ;; + --enable-joystick) enable_joystick="yes" + ;; + --enable-pulseaudio=*) has_pulseaudio="yes" + ;; + + --disable-all) has_pulseaudio="no"; disable_3d="yes"; disable_svg="yes"; disable_vrml="yes"; disable_od="yes"; disable_bifs="yes"; disable_bifs_enc="yes"; disable_laser="yes"; disable_beng="yes"; disable_qtvr="yes"; disable_avi="yes"; disable_ogg="yes"; disable_m2ps="yes"; disable_m2ts="yes"; disable_m2ts_mux="yes"; disable_parsers="yes"; disable_import="yes"; disable_export="yes"; disable_swf="yes"; disable_scene_stats="yes"; disable_scene_dump="yes"; disable_scene_encode="yes"; disable_loader_isoff="yes"; disable_od_dump="yes"; disable_mcrypt="yes"; disable_isoff="yes"; disable_isoff_write="yes"; disable_isoff_hint="yes"; disable_isoff_frag="yes"; disable_streaming="yes"; disable_x3d="yes"; disable_loader_bt="yes"; disable_loader_xmt="yes"; has_dvb4linux="no" + ;; + + --disable-3d) disable_3d="yes" + ;; + --enable-3d) disable_3d="no" + ;; + --disable-svg) disable_svg="yes" + ;; + --enable-svg) disable_svg="no" + ;; + --disable-vrml) disable_vrml="yes" + ;; + --enable-vrml) disable_vrml="no" + ;; + --disable-x3d) disable_x3d="yes" + ;; + --enable-x3d) disable_x3d="no" + ;; + --disable-odf) disable_od="yes" + ;; + --enable-odf) disable_od="no" + ;; + --disable-bifs) disable_bifs="yes" + ;; + --enable-bifs) disable_bifs="no" + ;; + --disable-bifs-enc) disable_bifs_enc="yes" + ;; + --enable-bifs-enc) disable_bifs_enc="no" + ;; + --disable-laser) disable_laser="yes" + ;; + --enable-laser) disable_laser="no" + ;; + --disable-beng) disable_beng="yes" + ;; + --enable-beng) disable_beng="no" + ;; + --disable-qtvr) disable_qtvr="yes" + ;; + --enable-qtvr) disable_qtvr="no" + ;; + --disable-avi) disable_avi="yes" + ;; + --enable-avi) disable_avi="no" + ;; + --disable-ogg) disable_ogg="yes" + ;; + --enable-ogg) disable_ogg="no" + ;; + --disable-m2ps) disable_m2ps="yes" + ;; + --enable-m2ps) disable_m2ps="no" + ;; + --disable-m2ts) disable_m2ts="yes" + ;; + --enable-m2ts) disable_m2ts="no" + ;; + --disable-m2ts-mux) disable_m2ts_mux="yes" + ;; + --enable-m2ts-mux) disable_m2ts_mux="no" + ;; + --disable-parsers) disable_parsers="yes" + ;; + --enable-parsers) disable_parsers="no" + ;; + --disable-import) disable_import="yes" + ;; + --enable-import) disable_import="no" + ;; + --disable-export) disable_export="yes" + ;; + --enable-export) disable_export="no" + ;; + --disable-swf) disable_swf="yes" + ;; + --enable-swf) disable_swf="no" + ;; + --disable-scene-stats) disable_scene_stats="yes" + ;; + --enable-scene-stats) disable_scene_stats="no" + ;; + --disable-scene-dump) disable_scene_dump="yes" + ;; + --enable-scene-dump) disable_scene_dump="no" + ;; + --disable-scene-encode) disable_scene_encode="yes" + ;; + --enable-scene-encode) disable_scene_encode="no" + ;; + --disable-loader-isoff) disable_loader_isoff="yes" + ;; + --enable-loader-isoff) disable_loader_isoff="no" + ;; + --disable-loader-bt) disable_loader_bt="yes" + ;; + --enable-loader-bt) disable_loader_bt="no" + ;; + --disable-loader-xmt) disable_loader_xmt="yes" + ;; + --enable-loader-xmt) disable_loader_xmt="no" + ;; + --disable-od-dump) disable_od_dump="yes" + ;; + --enable-od-dump) disable_od_dump="no" + ;; + --disable-mcrypt) disable_mcrypt="yes" + ;; + --enable-mcrypt) disable_mcrypt="no" + ;; + --disable-isoff) disable_isoff="yes" + ;; + --enable-isoff) disable_isoff="no" + ;; + --disable-isoff-write) disable_isoff_write="yes" + ;; + --enable-isoff-write) disable_isoff_write="no" + ;; + --disable-isoff-hint) disable_isoff_hint="yes" + ;; + --enable-isoff-hint) disable_isoff_hint="no" + ;; + --disable-isoff-frag) disable_isoff_frag="yes" + ;; + --enable-isoff-frag) disable_isoff_frag="no" + ;; + --disable-streaming) disable_streaming="yes" + ;; + --enable-streaming) disable_streaming="no" + ;; + + + esac done #look for OpenGL support or for TinyGL support @@ -1530,13 +1555,13 @@ INCL3D="" DarwinGL="no" if test "$darwin" = "yes" ; then -cat > $TMPC << EOF + cat > $TMPC << EOF #include #include int main( void ) { glEnable(GL_NORMALIZE); return 0; } EOF else -cat > $TMPC << EOF + cat > $TMPC << EOF #include #include int main( void ) { glEnable(GL_NORMALIZE); return 0; } @@ -1544,28 +1569,28 @@ EOF fi if test "$disable_3d" = "no" ; then - if test "$win32" = "yes" ; then - if test "$cygwin" = "yes" ; then - LINK3D="-lw32api/opengl32 -lw32api/glu32" + if test "$win32" = "yes" ; then + if test "$cygwin" = "yes" ; then + LINK3D="-lw32api/opengl32 -lw32api/glu32" + else + LINK3D="-lopengl32 -lglu32" + fi + elif test "$darwin" = "yes" ; then + LINK3D="-framework OpenGL -framework GLUT" + DarwinGL="yes" else - LINK3D="-lopengl32 -lglu32" + LINK3D="-lGL -lGLU -lX11" + fi + if $cc -o $TMPO $TMPC $LINK3D 2> /dev/null ; then + has_opengl="yes" + elif $cc -o $TMPO $TMPC -I$X11_PATH/include -L$X11_PATH/lib 2> /dev/null ; then + has_opengl="yes" + INCL3D="-I$X11_PATH/include" + LINK3D="-L$X11_PATH/lib $LINK3D" + fi + if test "$has_opengl" = "no" ; then + LINK3D="" fi - elif test "$darwin" = "yes" ; then - LINK3D="-framework OpenGL -framework GLUT" - DarwinGL="yes" - else - LINK3D="-lGL -lGLU -lX11" - fi - if $cc -o $TMPO $TMPC $LINK3D 2> /dev/null ; then - has_opengl="yes" - elif $cc -o $TMPO $TMPC -I$X11_PATH/include -L$X11_PATH/lib 2> /dev/null ; then - has_opengl="yes" - INCL3D="-I$X11_PATH/include" - LINK3D="-L$X11_PATH/lib $LINK3D" - fi - if test "$has_opengl" = "no" ; then - LINK3D="" - fi fi cat > $TMPC << EOF @@ -1573,36 +1598,36 @@ cat > $TMPC << EOF int main( void ) { int a ; a = TINYGL ; } EOF if test "$enable_tinygl" = "yes" ;then - if $cc -o $TMPO $TMPC -lTinyGL 2> /dev/null ; then - has_tinygl="yes" - has_opengl="yes" - LINK3D="-lTinyGL" -fi + if $cc -o $TMPO $TMPC -lTinyGL 2> /dev/null ; then + has_tinygl="yes" + has_opengl="yes" + LINK3D="-lTinyGL" + fi fi #look for GECKO support cat > $TMPCPP << EOF -#include +#include int main( void ) { return 0; } EOF -if $cc -o $TMPO $TMPCPP -I$xulsdk_path 2> /dev/null ; then -has_xul="system" -xul_flags="-I$xulsdk_path $xul_flags" -else -if $cc -o $TMPO $TMPCPP $xul_flags -I$local_inc/gecko-sdk/include 2> /dev/null ; then -has_xul="local" -xul_flags="-I$local_inc/gecko-sdk/include $xul_flags" +if $cc -o $TMPO $TMPCPP -I$xulsdk_path $CFLAGS $LDFLAGS 2> /dev/null ; then + has_xul="system" + xul_flags="-I$xulsdk_path $xul_flags" else -#xulrunner directories are sometimes included through js packages -if test "$has_js" = "system" ;then - if $cpp -o $TMPO $TMPCPP $js_flags $js_lib_pkg 2> /dev/null ; then - xul_flags=`pkg-config --cflags mozilla-js` - has_xul="system" - fi -fi -fi + if $cc -o $TMPO $TMPCPP $xul_flags -I$local_inc/gecko-sdk/include 2> /dev/null ; then + has_xul="local" + xul_flags="-I$local_inc/gecko-sdk/include $xul_flags" + else + #xulrunner directories are sometimes included through js packages + if test "$has_js" = "system" ;then + if $cpp -o $TMPO $TMPCPP $js_flags $js_lib_pkg 2> /dev/null ; then + xul_flags=`pkg-config --cflags mozilla-js` + has_xul="system" + fi + fi + fi fi @@ -1613,20 +1638,20 @@ int main( void ) { return 0; } EOF if test "$enable_joystick" = "yes" ;then if $cc -o $TMPO $TMPC 2> /dev/null ; then - has_joystick="yes" + has_joystick="yes" fi fi #GCC opt if test "$no_gcc_opt" = "no"; then -if $cc --version | grep 'sbox-arm-linux-gcc (GCC) 3.4.4' -then - echo "Detected buggy arm GCC (diablo), using -O2" - CFLAGS="-O2 $CFLAGS" -else - CFLAGS="-O3 $CFLAGS" -fi + if $cc --version | grep 'sbox-arm-linux-gcc (GCC) 3.4.4' + then + echo "Detected buggy arm GCC (diablo), using -O2" + CFLAGS="-O2 $CFLAGS" + else + CFLAGS="-O3 $CFLAGS" + fi fi #look for DX support @@ -1634,19 +1659,19 @@ dx_path="system" has_mingw_directx="no" if test "$win32" = "yes" ; then -cat > $TMPC << EOF + cat > $TMPC << EOF #include int main( void ) { return 0; } EOF -if $cc -o $TMPO $TMPC 2> /dev/null ; then -has_mingw_directx="yes" -else -dx_path="$dxsdk_path" -if $cc -o $TMPO $TMPC -I$dxsdk_path/include -L$dxsdk_path/lib -lddraw 2> /dev/null ; then -has_mingw_directx="yes" -fi -fi + if $cc -o $TMPO $TMPC 2> /dev/null ; then + has_mingw_directx="yes" + else + dx_path="$dxsdk_path" + if $cc -o $TMPO $TMPC -I$dxsdk_path/include -L$dxsdk_path/lib -lddraw 2> /dev/null ; then + has_mingw_directx="yes" + fi + fi fi @@ -1656,33 +1681,33 @@ sdl_too_old=no has_sdl=no sdl_config="sdl-config" if test "$sdl_local" = "yes"; then -sdl_config="$sdl_path/sdl-config" -sdl_static="yes" + sdl_config="$sdl_path/sdl-config" + sdl_static="yes" fi if type $sdl_config >/dev/null 2>&1; then -cat > $TMPC << EOF + cat > $TMPC << EOF #include #undef main int main( void ) { return SDL_Init (SDL_INIT_VIDEO); } EOF -if test "$sdl_static" = "yes"; then -sdl_lib_flags=`$sdl_config --static-libs` -else -sdl_lib_flags=`$sdl_config --libs` -fi -sdl_cflags=`$sdl_config --cflags` - -if $cc -o $TMPO $sdl_cflags $TMPC $sdl_lib_flags > /dev/null 2>&1 ; then -_sdlversion=`$sdl_config --version | sed 's/[^0-9]//g'` -if test "$_sdlversion" -lt 121 ; then -sdl_too_old=yes -else -has_sdl=yes -fi -fi + if test "$sdl_static" = "yes"; then + sdl_lib_flags=`$sdl_config --static-libs` + else + sdl_lib_flags=`$sdl_config --libs` + fi + sdl_cflags=`$sdl_config --cflags` + + if $cc -o $TMPO $sdl_cflags $TMPC $sdl_lib_flags > /dev/null 2>&1 ; then + _sdlversion=`$sdl_config --version | sed 's/[^0-9]//g'` + if test "$_sdlversion" -lt 121 ; then + sdl_too_old=yes + else + has_sdl=yes + fi + fi fi #end SDL check @@ -1690,48 +1715,49 @@ fi if test -z "$cross_prefix" ; then -# big/little endian test -cat > $TMPC << EOF + # big/little endian test + cat > $TMPC << EOF #include int main(int argc, char ** argv){ - volatile uint32_t i=0x01234567; - return (*((uint8_t*)(&i))) == 0x67; +volatile uint32_t i=0x01234567; +return (*((uint8_t*)(&i))) == 0x67; } EOF -if $cc -o $TMPO $TMPC 2>/dev/null ; then -$TMPO && bigendian="yes" -else -echo big/little endian test failed -fi + if $cc -o $TMPO $TMPC 2>/dev/null ; then + $TMPO && bigendian="yes" + else + echo big/little endian test failed + fi else -# if cross compiling, cannot launch a program, so make a static guess -if test "$cpu" = "powerpc" -o "$cpu" = "mips" ; then - bigendian="yes" -fi + # if cross compiling, cannot launch a program, so make a static guess + if test "$cpu" = "powerpc" -o "$cpu" = "mips" ; then + bigendian="yes" + fi fi + if test x"$mandir" = x""; then -mandir="${prefix}/man" + mandir="${prefix}/man" fi if test "$static_mp4box" = "yes"; then -has_opengl="no" -has_ssl="no" -has_js="no" -has_jpeg="no" -has_png="no" + has_opengl="no" + has_ssl="no" + has_js="no" + has_jpeg="no" + has_png="no" fi if test "$cpu" = "sh4"; then -viren_dir="`ls \"$source_path/modules\" | grep viren_out`" -if test "$viren_dir" = "viren_out"; then -enable_depth_compositor="yes" -enable_renoir="yes" -fi + viren_dir="`ls \"$source_path/modules\" | grep viren_out`" + if test "$viren_dir" = "viren_out"; then + enable_depth_compositor="yes" + enable_renoir="yes" + fi fi #prepare for config.h writing @@ -1746,10 +1772,10 @@ version="`grep '#define GPAC_VERSION ' \"$source_path/include/gpac/tools.h\" | c if which svnversion >/dev/null then - revision="`svnversion \"$source_path\"`" - echo "#define GPAC_SVN_REVISION \"$revision\"" > $source_path/include/gpac/version.h + revision="`svnversion \"$source_path\"`" + echo "#define GPAC_SVN_REVISION \"$revision\"" > $source_path/include/gpac/version.h else - echo "Cannot find SVN revision" + echo "Cannot find SVN revision" fi echo "" @@ -1762,7 +1788,7 @@ echo "make: $make" echo "CPU: $cpu" echo "Big Endian: $bigendian" if test $cpu = "mips"; then -echo "MMI enabled: $mmi" + echo "MMI enabled: $mmi" fi echo "" echo "** GPAC $version rev$revision Core Configuration **" @@ -1776,133 +1802,133 @@ echo "IPV6 Support: $has_ipv6" if test "$disable_svg" = "yes" ; then -echo "SVG disabled" -echo "#define GPAC_DISABLE_SVG" >> $TMPH + echo "SVG disabled" + echo "#define GPAC_DISABLE_SVG" >> $TMPH fi if test "$disable_vrml" = "yes" ; then -echo "MPEG-4/VRML/X3D disabled" -echo "#define GPAC_DISABLE_VRML" >> $TMPH + echo "MPEG-4/VRML/X3D disabled" + echo "#define GPAC_DISABLE_VRML" >> $TMPH fi if test "$disable_x3d" = "yes" ; then -echo "X3D disabled" -echo "#define GPAC_DISABLE_X3D" >> $TMPH + echo "X3D disabled" + echo "#define GPAC_DISABLE_X3D" >> $TMPH fi if test "$disable_od" = "yes" ; then -echo "OD Full support disabled" -echo "#define GPAC_MINIMAL_ODF" >> $TMPH + echo "OD Full support disabled" + echo "#define GPAC_MINIMAL_ODF" >> $TMPH fi if test "$disable_bifs" = "yes" ; then -echo "BIFS coder disabled" -echo "#define GPAC_DISABLE_BIFS" >> $TMPH + echo "BIFS coder disabled" + echo "#define GPAC_DISABLE_BIFS" >> $TMPH fi if test "$disable_bifs_enc" = "yes" ; then -echo "BIFS encoder disabled" -echo "#define GPAC_DISABLE_BIFS_ENC" >> $TMPH + echo "BIFS encoder disabled" + echo "#define GPAC_DISABLE_BIFS_ENC" >> $TMPH fi if test "$disable_laser" = "yes" ; then -echo "LASeR coder disabled" -echo "#define GPAC_DISABLE_LASER" >> $TMPH + echo "LASeR coder disabled" + echo "#define GPAC_DISABLE_LASER" >> $TMPH fi if test "$disable_beng" = "yes" ; then -echo "Scene encoder engine disabled" -echo "#define GPAC_DISABLE_SENG" >> $TMPH + echo "Scene encoder engine disabled" + echo "#define GPAC_DISABLE_SENG" >> $TMPH fi if test "$disable_qtvr" = "yes" ; then -echo "Cubic QTVR import disabled" -echo "#define GPAC_DISABLE_QTVR" >> $TMPH + echo "Cubic QTVR import disabled" + echo "#define GPAC_DISABLE_QTVR" >> $TMPH fi if test "$disable_avi" = "yes" ; then -echo "AVI disabled" -echo "#define GPAC_DISABLE_AVILIB" >> $TMPH + echo "AVI disabled" + echo "#define GPAC_DISABLE_AVILIB" >> $TMPH fi if test "$disable_ogg" = "yes" ; then -echo "OGG disabled" -echo "#define GPAC_DISABLE_OGG" >> $TMPH + echo "OGG disabled" + echo "#define GPAC_DISABLE_OGG" >> $TMPH fi if test "$disable_m2ps" = "yes" ; then -echo "MPEG-2 PS disabled" -echo "#define GPAC_DISABLE_MPEG2PS" >> $TMPH + echo "MPEG-2 PS disabled" + echo "#define GPAC_DISABLE_MPEG2PS" >> $TMPH fi if test "$disable_m2ts" = "yes" ; then -echo "MPEG-2 TS disabled" -echo "#define GPAC_DISABLE_MPEG2TS" >> $TMPH + echo "MPEG-2 TS disabled" + echo "#define GPAC_DISABLE_MPEG2TS" >> $TMPH fi if test "$disable_m2ts_mux" = "yes" ; then -echo "MPEG-2 TS Multiplexer disabled" -echo "#define GPAC_DISABLE_MPEG2TS_MUX" >> $TMPH + echo "MPEG-2 TS Multiplexer disabled" + echo "#define GPAC_DISABLE_MPEG2TS_MUX" >> $TMPH fi if test "$disable_parsers" = "yes" ; then -echo "AV Parsers disabled" -echo "#define GPAC_DISABLE_AV_PARSERS" >> $TMPH + echo "AV Parsers disabled" + echo "#define GPAC_DISABLE_AV_PARSERS" >> $TMPH fi if test "$disable_import" = "yes" ; then -echo "Media importers disabled" -echo "#define GPAC_DISABLE_MEDIA_IMPORT" >> $TMPH + echo "Media importers disabled" + echo "#define GPAC_DISABLE_MEDIA_IMPORT" >> $TMPH fi if test "$disable_export" = "yes" ; then -echo "Media exmporters disabled" -echo "#define GPAC_DISABLE_MEDIA_EXPORT" >> $TMPH + echo "Media exmporters disabled" + echo "#define GPAC_DISABLE_MEDIA_EXPORT" >> $TMPH fi if test "$disable_swf" = "yes" ; then -echo "SWF import disabled" -echo "#define GPAC_DISABLE_SWF_IMPORT" >> $TMPH + echo "SWF import disabled" + echo "#define GPAC_DISABLE_SWF_IMPORT" >> $TMPH fi if test "$disable_scene_stats" = "yes" ; then -echo "Scene statistics disabled" -echo "#define GPAC_DISABLE_SCENE_STATS" >> $TMPH + echo "Scene statistics disabled" + echo "#define GPAC_DISABLE_SCENE_STATS" >> $TMPH fi if test "$disable_scene_dump" = "yes" ; then -echo "Scene dump disabled" -echo "#define GPAC_DISABLE_SCENE_DUMP" >> $TMPH + echo "Scene dump disabled" + echo "#define GPAC_DISABLE_SCENE_DUMP" >> $TMPH fi if test "$disable_scene_encode" = "yes" ; then -echo "Scene encoder to ISO FF disabled" -echo "#define GPAC_DISABLE_SCENE_ENCODER" >> $TMPH + echo "Scene encoder to ISO FF disabled" + echo "#define GPAC_DISABLE_SCENE_ENCODER" >> $TMPH fi if test "$disable_loader_isoff" = "yes" ; then -echo "Scene loader from ISO FF disabled" -echo "#define GPAC_DISABLE_LOADER_ISOM" >> $TMPH + echo "Scene loader from ISO FF disabled" + echo "#define GPAC_DISABLE_LOADER_ISOM" >> $TMPH fi if test "$disable_loader_bt" = "yes" ; then -echo "BT/WRL Scene loader disabled" -echo "#define GPAC_DISABLE_LOADER_BT" >> $TMPH + echo "BT/WRL Scene loader disabled" + echo "#define GPAC_DISABLE_LOADER_BT" >> $TMPH fi if test "$disable_loader_xmt" = "yes" ; then -echo "XMT/X3D Scene loader disabled" -echo "#define GPAC_DISABLE_LOADER_XMT" >> $TMPH + echo "XMT/X3D Scene loader disabled" + echo "#define GPAC_DISABLE_LOADER_XMT" >> $TMPH fi if test "$disable_od_dump" = "yes" ; then -echo "OD dump disabled" -echo "#define GPAC_DISABLE_OD_DUMP" >> $TMPH + echo "OD dump disabled" + echo "#define GPAC_DISABLE_OD_DUMP" >> $TMPH fi if test "$disable_mcrypt" = "yes" ; then -echo "MCrypt disabled" -echo "#define GPAC_DISABLE_MCRYPT" >> $TMPH + echo "MCrypt disabled" + echo "#define GPAC_DISABLE_MCRYPT" >> $TMPH fi if test "$disable_isoff" = "yes" ; then -echo "ISO File Format disabled" -echo "#define GPAC_DISABLE_ISOM" >> $TMPH + echo "ISO File Format disabled" + echo "#define GPAC_DISABLE_ISOM" >> $TMPH fi if test "$disable_isoff_write" = "yes" ; then -echo "ISO File Format write disabled" -echo "#define GPAC_DISABLE_ISOM_WRITE" >> $TMPH + echo "ISO File Format write disabled" + echo "#define GPAC_DISABLE_ISOM_WRITE" >> $TMPH fi if test "$disable_isoff_hint" = "yes" ; then -echo "ISO File Format hinting disabled" -echo "#define GPAC_DISABLE_ISOM_HINTING" >> $TMPH + echo "ISO File Format hinting disabled" + echo "#define GPAC_DISABLE_ISOM_HINTING" >> $TMPH fi if test "$disable_isoff_frag" = "yes" ; then -echo "ISO File Format fragments disabled" -echo "#define GPAC_DISABLE_ISOM_FRAGMENTS" >> $TMPH + echo "ISO File Format fragments disabled" + echo "#define GPAC_DISABLE_ISOM_FRAGMENTS" >> $TMPH fi if test "$disable_streaming" = "yes" ; then -echo "RTP/RTSP/SDP streaming disabled" -echo "#define GPAC_DISABLE_STREAMING" >> $TMPH + echo "RTP/RTSP/SDP streaming disabled" + echo "#define GPAC_DISABLE_STREAMING" >> $TMPH fi if test "$enable_depth_compositor" = "yes" ; then -echo "Depth Compositor enabled" -echo "#define GF_SR_USE_DEPTH" >> $TMPH + echo "Depth Compositor enabled" + echo "#define GF_SR_USE_DEPTH" >> $TMPH fi echo "" @@ -1911,17 +1937,18 @@ echo "** Detected libraries **" echo "zlib: $has_zlib" if test "$win32" != "yes" ; then -echo "OSS Audio: $has_oss_audio" -echo "ALSA Audio: $has_alsa" -echo "Jack Audio: $has_jack" -echo "PulseAudio Audio: $has_pulseaudio" -echo "X11 Shared Memory support: $has_x11_shm (path: $X11_PATH)" -echo "X11 XVideo support: $has_x11_xv" + echo "OSS Audio: $has_oss_audio" + echo "ALSA Audio: $has_alsa" + echo "Jack Audio: $has_jack" + echo "PulseAudio Audio: $has_pulseaudio" + echo "DirectFB support: $has_directfb" + echo "X11 Shared Memory support: $has_x11_shm (path: $X11_PATH)" + echo "X11 XVideo support: $has_x11_xv" fi echo "SDL Support: $has_sdl" if test "$sdl_too_old" = "yes" ; then -echo "SDL Version too old - please upgrade for SDL support" + echo "SDL Version too old - please upgrade for SDL support" fi echo "OpenGL support: $has_opengl" echo "TinyGL support: $has_tinygl" @@ -1930,22 +1957,22 @@ echo "OpenSSL support: $has_ssl" echo "Mozilla XUL/GECKO support: $has_xul" if test "$win32" = "yes" ; then -echo "DirectX Support: $has_mingw_directx" + echo "DirectX Support: $has_mingw_directx" fi if test "$linux" = "yes" ; then -echo "DVB Support: $has_dvb4linux" + echo "DVB Support: $has_dvb4linux" fi echo "XMLPRC Support: $has_xmlrpc" if test "$wx_too_old" = "yes" ; then -has_wx="no" -echo "wxWidgets Version too old - please upgrade to 2.6.0 for wxWidgets support" + has_wx="no" + echo "wxWidgets Version too old - please upgrade to 2.6.0 for wxWidgets support" fi if test "$has_wx" = "yes" ; then -echo "wxWidgets support: Version $wx_version" + echo "wxWidgets support: Version $wx_version" else -echo "wxWidgets support: no" + echo "wxWidgets support: no" fi @@ -1962,66 +1989,66 @@ echo "XVID: $has_xvid" echo "FFMPEG: $has_ffmpeg" echo "Xiph OGG: $has_ogg" if test "$has_ogg" = "no"; then -has_ogg="no" + has_ogg="no" else -echo "Xiph Vorbis: $has_vorbis" -echo "Xiph Theora: $has_theora" + echo "Xiph Vorbis: $has_vorbis" + echo "Xiph Theora: $has_theora" fi echo "A52 (AC3): $has_a52" if test "$enable_renoir" = "yes" ; then -echo "Renoir enabled - make sure the driver libraries are present in modules/viren_out directory" + echo "Renoir enabled - make sure the driver libraries are present in modules/viren_out directory" fi echo "" if test "$has_amr_nb_fixed" = "yes" ; then - echo "*** AMR NB FIXED-POINT NOTICE ***" - echo "Make sure you have downloaded TS26.073 from:" - echo "http://www.3gpp.org/ftp/Specs/archive/26_series/26.073/26073-*.zip" - echo "or through gpac_extra_libs and extracted src to modules/amr_dec/amr_nb" - echo "without overwriting typedefs.h file" - echo "" + echo "*** AMR NB FIXED-POINT NOTICE ***" + echo "Make sure you have downloaded TS26.073 from:" + echo "http://www.3gpp.org/ftp/Specs/archive/26_series/26.073/26073-*.zip" + echo "or through gpac_extra_libs and extracted src to modules/amr_dec/amr_nb" + echo "without overwriting typedefs.h file" + echo "" fi echo "" if test "$has_amr_nb" = "yes" ; then - echo "*** AMR NB NOTICE ***" - echo "Make sure you have downloaded TS26.104 from:" - echo "http://www.3gpp.org/ftp/Specs/archive/26_series/26.104/26104-*.zip" - echo "or through gpac_extra_libs and extracted src to modules/amr_float_dec/amr_nb_ft" - echo "without overwriting typedefs.h file" - echo "" + echo "*** AMR NB NOTICE ***" + echo "Make sure you have downloaded TS26.104 from:" + echo "http://www.3gpp.org/ftp/Specs/archive/26_series/26.104/26104-*.zip" + echo "or through gpac_extra_libs and extracted src to modules/amr_float_dec/amr_nb_ft" + echo "without overwriting typedefs.h file" + echo "" fi echo "" if test "$has_amr_wb" = "yes" ; then - echo "*** AMR WB NOTICE ***" - echo "Make sure you have downloaded TS26.204 from:" - echo "http://www.3gpp.org/ftp/Specs/archive/26_series/26.204/26204-*.zip" - echo "or through gpac_extra_libs and extracted src to modules/amr_float_dec/amr_wb_ft" - echo "without overwriting typedefs.h file" - echo "" + echo "*** AMR WB NOTICE ***" + echo "Make sure you have downloaded TS26.204 from:" + echo "http://www.3gpp.org/ftp/Specs/archive/26_series/26.204/26204-*.zip" + echo "or through gpac_extra_libs and extracted src to modules/amr_float_dec/amr_wb_ft" + echo "without overwriting typedefs.h file" + echo "" fi if test "$use_memory_tracking" = "yes"; then -echo "!! WARNING: GPAC Memory tracking is enabled !!" -echo "!! This may corrupt third-party tools using libgpac !!" -echo "!! Use at your own risk, and only for GPAC benchmarking !!" -echo "" + echo "!! WARNING: GPAC Memory tracking is enabled !!" + echo "!! This may corrupt third-party tools using libgpac !!" + echo "!! Use at your own risk, and only for GPAC benchmarking !!" + echo "" fi #needs gmon for win32 gprof if test "$gprof_build" = "yes"; then -if test "$win32" = "yes"; then -extralibs="$extralibs -lgmon" -fi + if test "$win32" = "yes"; then + extralibs="$extralibs -lgmon" + fi fi if test "$want_pic" = "yes" ; then -CFLAGS="$CFLAGS -fPIC -DPIC" -CPPFLAGS="$CPPFLAGS -fPIC -DPIC" + CFLAGS="$CFLAGS -fPIC -DPIC" + CPPFLAGS="$CPPFLAGS -fPIC -DPIC" fi ldir=`pwd` @@ -2056,76 +2083,76 @@ echo "libdir=$libdir" >> config.mak #for cross-compilation if test "$cross_prefix" != "" ; then -echo "CROSS_COMPILING=yes" >> config.mak + echo "CROSS_COMPILING=yes" >> config.mak fi if test "$cpu" = "x86" ; then - echo "TARGET_ARCH_X86=yes" >> config.mak + echo "TARGET_ARCH_X86=yes" >> config.mak elif test "$cpu" = "armv4l" ; then - echo "TARGET_ARCH_ARMV4L=yes" >> config.mak + echo "TARGET_ARCH_ARMV4L=yes" >> config.mak elif test "$cpu" = "alpha" ; then - echo "TARGET_ARCH_ALPHA=yes" >> config.mak + echo "TARGET_ARCH_ALPHA=yes" >> config.mak elif test "$cpu" = "sparc64" ; then - echo "TARGET_ARCH_SPARC64=yes" >> config.mak + echo "TARGET_ARCH_SPARC64=yes" >> config.mak elif test "$cpu" = "powerpc" ; then - echo "TARGET_ARCH_POWERPC=yes" >> config.mak + echo "TARGET_ARCH_POWERPC=yes" >> config.mak elif test "$cpu" = "mips" ; then - echo "TARGET_ARCH_MIPS=yes" >> config.mak + echo "TARGET_ARCH_MIPS=yes" >> config.mak fi if test "$bigendian" = "yes" ; then - echo "IS_BIGENDIAN=yes" >> config.mak - echo "#define GPAC_BIG_ENDIAN" >> $TMPH + echo "IS_BIGENDIAN=yes" >> config.mak + echo "#define GPAC_BIG_ENDIAN" >> $TMPH fi echo "EXTRALIBS=$extralibs" >> config.mak echo "VERSION=$version" >>config.mak if test "$use_fixed_point" = "yes"; then -echo "#define GPAC_FIXED_POINT" >> $TMPH + echo "#define GPAC_FIXED_POINT" >> $TMPH fi if test "$use_memory_tracking" = "yes"; then -echo "#define GPAC_MEMORY_TRACKING" >> $TMPH + echo "#define GPAC_MEMORY_TRACKING" >> $TMPH elif test "$use_std_alloc" = "yes"; then -echo "#define GPAC_STD_ALLOCATOR" >> $TMPH + echo "#define GPAC_STD_ALLOCATOR" >> $TMPH fi if test "$win32" = "yes" ; then - echo "CONFIG_WIN32=yes" >> config.mak - echo "CONFIG_OS=CONFIG_WIN32" >> config.mak - echo "#define GPAC_CONFIG_WIN32" >> $TMPH + echo "CONFIG_WIN32=yes" >> config.mak + echo "CONFIG_OS=CONFIG_WIN32" >> config.mak + echo "#define GPAC_CONFIG_WIN32" >> $TMPH elif test "$linux" = "yes" ; then - echo "CONFIG_LINUX=yes" >> config.mak - echo "CONFIG_OS=CONFIG_LINUX" >> config.mak - echo "#define GPAC_CONFIG_LINUX" >> $TMPH + echo "CONFIG_LINUX=yes" >> config.mak + echo "CONFIG_OS=CONFIG_LINUX" >> config.mak + echo "#define GPAC_CONFIG_LINUX" >> $TMPH elif test "$freebsd" = "yes" ; then - echo "CONFIG_FREEBSD=yes" >> config.mak - echo "CONFIG_OS=CONFIG_FREEBSD" >> config.mak - echo "#define GPAC_CONFIG_FREEBSD" >> $TMPH + echo "CONFIG_FREEBSD=yes" >> config.mak + echo "CONFIG_OS=CONFIG_FREEBSD" >> config.mak + echo "#define GPAC_CONFIG_FREEBSD" >> $TMPH elif test "$darwin" = "yes" ; then - echo "CONFIG_DARWIN=yes" >> config.mak - echo "CONFIG_OS=CONFIG_DARWIN" >> config.mak - echo "#define GPAC_CONFIG_DARWIN" >> $TMPH - if test "$DarwinGL" = "yes" ; then - echo "#define CONFIG_DARWIN_GL" >> $TMPH - fi - echo "mac_apps=$Mac_Applications" >> config.mak + echo "CONFIG_DARWIN=yes" >> config.mak + echo "CONFIG_OS=CONFIG_DARWIN" >> config.mak + echo "#define GPAC_CONFIG_DARWIN" >> $TMPH + if test "$DarwinGL" = "yes" ; then + echo "#define CONFIG_DARWIN_GL" >> $TMPH + fi + echo "mac_apps=$Mac_Applications" >> config.mak elif test "$sunos" = "yes" ; then - echo "CONFIG_SUNOS=yes" >> config.mak - echo "CONFIG_OS=CONFIG_SUNOS" >> config.mak - echo "#define GPAC_CONFIG_SUNOS" >> $TMPH + echo "CONFIG_SUNOS=yes" >> config.mak + echo "CONFIG_OS=CONFIG_SUNOS" >> config.mak + echo "#define GPAC_CONFIG_SUNOS" >> $TMPH else - echo "CONFIG_OS=CONFIG_GEN" >> config.mak - echo "#define GPAC_CONFIG_GENERIC" >> $TMPH + echo "CONFIG_OS=CONFIG_GEN" >> config.mak + echo "#define GPAC_CONFIG_GENERIC" >> $TMPH fi if test "$win32" = "no" ; then - echo "GPAC_SH_FLAGS=$GPAC_SH_FLAGS" >> config.mak - echo "DYN_LIB_SUFFIX=$DYN_LIB_SUFFIX" >> config.mak + echo "GPAC_SH_FLAGS=$GPAC_SH_FLAGS" >> config.mak + echo "DYN_LIB_SUFFIX=$DYN_LIB_SUFFIX" >> config.mak else - echo "DYN_LIB_SUFFIX=dll" >> config.mak + echo "DYN_LIB_SUFFIX=dll" >> config.mak fi @@ -2133,23 +2160,23 @@ echo "INSTFLAGS=$INSTFLAGS" >> config.mak echo "CONFIG_JS=$has_js" >> config.mak if test "$has_js" = "no" ; then - has_js="no" + has_js="no" else -echo "JS_FLAGS=$js_flags" >> config.mak -echo "JS_LIBS=$js_lib" >> config.mak -echo "#define GPAC_HAS_SPIDERMONKEY" >> $TMPH + echo "JS_FLAGS=$js_flags" >> config.mak + echo "JS_LIBS=$js_lib" >> config.mak + echo "#define GPAC_HAS_SPIDERMONKEY" >> $TMPH fi echo "CONFIG_ZLIB=$has_zlib" >> config.mak echo "CONFIG_FT=$has_ft" >> config.mak echo "CONFIG_JPEG=$has_jpeg" >> config.mak if test "$has_jpeg" != "no" ; then -echo "#define GPAC_HAS_JPEG" >> $TMPH + echo "#define GPAC_HAS_JPEG" >> $TMPH fi echo "CONFIG_PNG=$has_png" >> config.mak if test "$has_png" != "no" ; then -echo "#define GPAC_HAS_PNG" >> $TMPH + echo "#define GPAC_HAS_PNG" >> $TMPH fi echo "CONFIG_JP2=$has_openjpeg" >> config.mak @@ -2162,8 +2189,8 @@ echo "CONFIG_THEORA=$has_theora" >> config.mak echo "CONFIG_FFMPEG=$has_ffmpeg" >> config.mak if test "$has_ffmpeg" != "no" then - echo "ffmpeg_cflags=$ffmpeg_cflags" >> config.mak - echo "ffmpeg_lflags=$ffmpeg_lflags" >> config.mak + echo "ffmpeg_cflags=$ffmpeg_cflags" >> config.mak + echo "ffmpeg_lflags=$ffmpeg_lflags" >> config.mak fi echo "CONFIG_FFMPEG_OLD=$old_ffmpeg_inc" >> config.mak @@ -2176,8 +2203,8 @@ echo "CONFIG_PULSEAUDIO=$has_pulseaudio" >> config.mak echo "DISABLE_SVG=$disable_svg" >> config.mak echo "HAS_LIBXML2=$has_libxml2" >> config.mak if test "$has_libxml2" = "yes"; then - echo "XML2_CFLAGS=$libxml2_cflags" >> config.mak - echo "XML2_LIBS=$libxml2_lib_flags" >> config.mak + echo "XML2_CFLAGS=$libxml2_cflags" >> config.mak + echo "XML2_LIBS=$libxml2_lib_flags" >> config.mak fi @@ -2189,33 +2216,33 @@ echo "DISABLE_ISOFF=$disable_isoff" >> config.mak echo "HAS_OPENGL=$has_opengl" >> config.mak if test "$has_opengl" = "yes" ; then - echo "OGL_LIBS=$LINK3D" >> config.mak + echo "OGL_LIBS=$LINK3D" >> config.mak else - echo "#define GPAC_DISABLE_3D" >> $TMPH + echo "#define GPAC_DISABLE_3D" >> $TMPH fi if test "$has_tinygl" = "yes" ; then -echo "#define GPAC_USE_TINYGL" >> $TMPH + echo "#define GPAC_USE_TINYGL" >> $TMPH fi echo "ENABLE_JOYSTICK=$has_joystick" >> config.mak echo "HAS_OPENSSL=$has_ssl" >> config.mak if test "$has_ssl" = "yes" ; then - echo "SSL_LIBS=$LINK_SSL" >> config.mak - echo "#define GPAC_HAS_SSL" >> $TMPH + echo "SSL_LIBS=$LINK_SSL" >> config.mak + echo "#define GPAC_HAS_SSL" >> $TMPH fi echo "CONFIG_SDL=$has_sdl" >> config.mak if test "$has_sdl" = "yes" ; then - echo "SDL_CFLAGS=$sdl_cflags" >> config.mak - echo "SDL_LIBS=$sdl_lib_flags" >> config.mak + echo "SDL_CFLAGS=$sdl_cflags" >> config.mak + echo "SDL_LIBS=$sdl_lib_flags" >> config.mak fi if test "$has_ft" = "no" ; then - has_ft="no" + has_ft="no" else - echo "FT_CFLAGS=$ft_cflags" >> config.mak - echo "FT_LIBS=$ft_lflags" >> config.mak + echo "FT_CFLAGS=$ft_cflags" >> config.mak + echo "FT_LIBS=$ft_lflags" >> config.mak fi echo "CONFIG_AMR_NB=$has_amr_nb_fixed" >> config.mak echo "CONFIG_AMR_NB_FT=$has_amr_nb" >> config.mak @@ -2226,52 +2253,59 @@ echo "STATICBUILD=$static_build" >> config.mak echo "CONFIG_IPV6=$has_ipv6" >> config.mak if test "$has_ipv6" = "yes" ; then - echo "#define GPAC_HAS_IPV6" >> $TMPH + echo "#define GPAC_HAS_IPV6" >> $TMPH fi if test "$win32" = "yes" ; then -echo "CONFIG_DIRECTX=$has_mingw_directx" >> config.mak -if test "$has_mingw_directx" = "yes" ; then -echo "DX_PATH=$dx_path" >> config.mak -fi + echo "CONFIG_DIRECTX=$has_mingw_directx" >> config.mak + if test "$has_mingw_directx" = "yes" ; then + echo "DX_PATH=$dx_path" >> config.mak + fi fi echo "USE_WXWIDGETS=$has_wx" >> config.mak if test "$has_wx" = "yes"; then -echo "WX_CFLAGS=$wx_cflags" >> config.mak -echo "WX_LFLAGS=$wx_lflags" >> config.mak + echo "WX_CFLAGS=$wx_cflags" >> config.mak + echo "WX_LFLAGS=$wx_lflags" >> config.mak fi echo "MOZILLA_DIR=$moz_path" >> config.mak echo "CONFIG_XUL=$has_xul" >> config.mak if test "$has_xul" != "no"; then -echo "XUL_CFLAGS=$xul_flags" >> config.mak + echo "XUL_CFLAGS=$xul_flags" >> config.mak fi echo "LINUX_DVB=$has_dvb4linux" >> config.mak +if test "$has_dvb4linux" = "yes"; then + echo "#define GPAC_HAS_LINUX_DVB" >> $TMPH +fi echo "XMLRPC_INC=$has_xmlrpc" >> config.mak if test "$has_oss_audio" != "no"; then -echo "OSS_INC_TYPE=$has_oss_audio" >> config.mak -echo "OSS_CFLAGS=$OSS_CFLAGS" >> config.mak -echo "OSS_LDFLAGS=$OSS_LDFLAGS" >> config.mak + echo "OSS_INC_TYPE=$has_oss_audio" >> config.mak + echo "OSS_CFLAGS=$OSS_CFLAGS" >> config.mak + echo "OSS_LDFLAGS=$OSS_LDFLAGS" >> config.mak fi +echo "CONFIG_DIRECTFB=$has_directfb" >> config.mak +echo "DIRECTFB_INC_PATH=$directfb_inc" >> config.mak +echo "DIRECTFB_LIB=$directfb_lib" >> config.mak + echo "CONFIG_X11=$has_x11" >> config.mak if test "$has_x11_shm" = "yes"; then -echo "USE_X11_SHM=$has_x11_shm" >> config.mak + echo "USE_X11_SHM=$has_x11_shm" >> config.mak fi if test "$has_x11_xv" = "yes"; then -echo "USE_X11_XV=$has_x11_xv" >> config.mak + echo "USE_X11_XV=$has_x11_xv" >> config.mak fi if test "$is_64" = "yes"; then -echo "X11_LIB_PATH=$X11_PATH/lib64" >> config.mak + echo "X11_LIB_PATH=$X11_PATH/lib64" >> config.mak else -echo "X11_LIB_PATH=$X11_PATH/lib" >> config.mak + echo "X11_LIB_PATH=$X11_PATH/lib" >> config.mak fi echo "X11_INC_PATH=$X11_PATH/include" >> config.mak @@ -2283,22 +2317,22 @@ GPAC_ENST_INC=no GPAC_ENST=no enst_dir="`ls \"$source_path/src/\" | grep enst`" if test "$enst_dir" = "enst"; then -echo "GPAC Proprietary Extensions enabled" -GPAC_ENST_INC=yes -#we need libiconv for eit & co -cat > $TMPC << EOF + echo "GPAC Proprietary Extensions enabled" + GPAC_ENST_INC=yes + #we need libiconv for eit & co + cat > $TMPC << EOF #include int main( void ) { } EOF -if $cc -o $TMPE $TMPC -L$local_lib -liconv > /dev/null 2>&1 ; then -GPAC_ENST=yes -echo "LIBGPAC_ENST=`cd src; ls enst/*.c | sed -e 's/\.c/.o/' | tr -s '\r\n' ' ' ; cd ..`" >> config.mak -else -echo "Couldn't find libiconv - disabling GPAC ENST extensions" -GPAC_ENST="no" -fi + if $cc -o $TMPE $TMPC -L$local_lib -liconv > /dev/null 2>&1 ; then + GPAC_ENST=yes + echo "LIBGPAC_ENST=`cd src; ls enst/*.c | sed -e 's/\.c/.o/' | tr -s '\r\n' ' ' ; cd ..`" >> config.mak + else + echo "Couldn't find libiconv - disabling GPAC ENST extensions" + GPAC_ENST="no" + fi fi echo "GPAC_ENST=$GPAC_ENST" >> config.mak echo "GPAC_ENST_INC=$GPAC_ENST" >> config.mak @@ -2309,11 +2343,11 @@ if test "$source_path_used" = "yes" ; then echo "Creating compilation tree image" SRC_DIRS="src src/utils src/isomedia src/ietf src/odf src/bifs src/scenegraph src/terminal src/mcrypt src/media_tools src/scene_manager src/compositor src/laser" - + APP_DIRS="applications/mp4box applications/mp4client applications/osmozilla applications/osmo4_wx applications/mp42ts" for dir in $SRC_DIRS ; do - mkdir -p "$dir" + mkdir -p "$dir" done ln -sf "$source_path/Makefile" Makefile ln -sf "$source_path/src/Makefile" src/Makefile @@ -2323,8 +2357,8 @@ if test "$source_path_used" = "yes" ; then mkdir -p applications/testapps for dir in $APP_DIRS ; do - mkdir -p "$dir" - ln -sf "$source_path/$dir/Makefile" "$dir/Makefile" + mkdir -p "$dir" + ln -sf "$source_path/$dir/Makefile" "$dir/Makefile" done @@ -2332,10 +2366,10 @@ if test "$source_path_used" = "yes" ; then cd "$source_path/" MOD_DIRS="`ls -d modules/*/`" cd "$cur_dir" - + mkdir -p modules ln -sf "$source_path/modules/Makefile" modules/Makefile - + for dir in $MOD_DIRS ; do if ls "$source_path/$dir/Makefile" > /dev/null 2>&1; then mkdir -p "$dir" @@ -2343,8 +2377,8 @@ if test "$source_path_used" = "yes" ; then fi done if test "$has_mingw_directx" = "yes"; then - ln -sf "$source_path/modules/dx_hw/hand.cur" modules/dx_hw/hand.cur - ln -sf "$source_path/modules/dx_hw/collide.cur" modules/dx_hw/collide.cur + ln -sf "$source_path/modules/dx_hw/hand.cur" modules/dx_hw/hand.cur + ln -sf "$source_path/modules/dx_hw/collide.cur" modules/dx_hw/collide.cur fi cd "$cur_dir" @@ -2362,22 +2396,22 @@ echo "#endif" >> $TMPH # Do not overwrite config.h if unchanged to avoid superfluous rebuilds. if ! cmp -s $TMPH config.h; then - rm -f config.h - mv -f $TMPH config.h + rm -f config.h + mv -f $TMPH config.h else - echo "config.h is unchanged" + echo "config.h is unchanged" fi rm -f $TMPO $TMPC $TMPE $TMPS $TMPCPP $TMPH if [ ! -d "./bin" ]; then - mkdir ./bin + mkdir ./bin fi if [ ! -d "./bin/gcc" ]; then - mkdir ./bin/gcc + mkdir ./bin/gcc fi if [ ! -d "./bin/gcc/temp" ]; then - mkdir ./bin/gcc/temp + mkdir ./bin/gcc/temp fi echo '%.opic : %.c' >> config.mak diff --git a/doc/configuration.html b/doc/configuration.html index 8b970a1..5ec69ff 100644 --- a/doc/configuration.html +++ b/doc/configuration.html @@ -10,7 +10,7 @@
GPAC Configuration file documentation
Version 0.4.5

-Last Modified $Date: 2010-04-09 16:44:04 $ +Last Modified $LastChangedDate: 2011-06-14 10:39:53 -0400 (Tue, 14 Jun 2011) $



@@ -40,6 +40,7 @@ The config file is based on the win32 .ini file model, thus is ordered by sectio FFMPEG ISOReader DVB +DASH ALSA Shortcuts @@ -348,7 +349,7 @@ Specifies whether text shall be drawn to a texture and then rendered or directly

Read-only option listing the OpenGL extensions supported by the GL driver. Only valid after the 3D renderer has been used.

-StereoType [value: "None", "SideBySide", "TopToBottom", "Anaglyph", "Columns", "Rows", "Custom"] +StereoType [value: "None", "SideBySide", "TopToBottom", "Anaglyph", "Columns", "Rows", "SPV19", "Custom"]

Specifies the stereo output type (default "None"). If your graphic card does not support OpenGL shaders, only SideBySide and TopToBottom modes will be available.

    @@ -357,6 +358,7 @@ Specifies the stereo output type (default "None"). If your graphic card does not
  • "Anaglyph": Standard color anaglyph (red for left view, green and blue for right view) is used.
  • "Columns": images are interleaved by columns, left view on even columns and left view on odd columns.
  • "Rows": images are interleaved by columns, left view on even rows and left view on odd rows.
  • +
  • "SPV19": images are interleaved by for SpatialView 19'' 5 views display, fullscreen mode.
  • "Custom": images are interleaved according to the shader specified by InterleaverShader
@@ -519,9 +521,9 @@ The FreeType module uses this section to cache familly names to font file name a CleanCache [value: "yes" "no"]

Specifies whether downloaded files shall be removed once used.

-RestartFiles [value: "yes" "no"] +DisableCache [value: "yes" "no"]

-Specifies whether incompletely downloaded files shall be removed before redownloading.

+Specifies whether HTTP caching instructions are disabled or not.

MaxRate [value: positive integer]

Specifies a maximum data rate in kilo bits per seconds for file downloading. This is used for simulation purposes. A value of 0 means no rate restriction.

@@ -676,6 +678,21 @@ Specifies the DVB channels configuration file as produced by dvbtools' scan util

+ +Section "DASH" Back to top +

The "DASH" section of the config file holds all configuration options for DASH or HLS/M3U8 playback.

+MaxCachedSegments [value: positive integer] +

+Specifies how many segments should be downloaded at most in the cache.

+KeepFiles [value: yes, no] +

+Specifies whether downloaded files should not be deleted.

+AutoSwitchCount [value: yes, no] +

+For debug purposes, instructs the player to switch representation every N segments. If 0 (default), switching is disabled.

+ +

+ Section "ALSA" Back to top

The "ALSA" section of the config file holds all configuration options of the ALSA audio output module on GNU/Linux systems.

diff --git a/doc/man/mp4box.1 b/doc/man/mp4box.1 index b0647a8..7063fc5 100644 --- a/doc/man/mp4box.1 +++ b/doc/man/mp4box.1 @@ -24,11 +24,23 @@ MP4Box doesn't expect any particular order in options at prompt. .SH GETTING HELP WITH MP4Box .TP .B \-h [type] -prints help screen. "type" can be one of "general", "hint", "import", "encode", "extract", "dump", "swf", "meta", "crypt", "format" for specific help. +prints help screen. "type" can be one of "general", "hint", "import", "encode", "extract", "dump", "swf", "meta", "crypt", "format", "rtp", "live" for specific help. .TP .B \-version prints version of MP4Box. .TP +.B \-noprog +disable progress reports. +.TP +.B \-quiet +quiet mode (no log info). +.TP +.B \-v +verbose mode (more log info). +.TP +.B \-strict-error +exits after the first error is reported. +.TP .B \-nodes lists supported MPEG-4 Systems nodes in MP4Box current build. .TP @@ -39,6 +51,16 @@ prints the node syntax. Each field is listed as .br and field quantization information and quantization bounds if any. . +.TP +.B \-xnodes +lists supported X3D nodes in MP4Box current build. +.TP +.B \-xnode NodeName +prints the X3D node syntax. Each field is listed as +. +.TP +.B \-snodes +lists supported SVG/LASeR nodes in MP4Box current build. . .SH GENERAL OPTIONS .P @@ -46,6 +68,9 @@ and field quantization information and quantization bounds if any. .B \-inter duration interleaves media data in chunks of the maximum specified duration (expressed in milliseconds) and prepare file for HTTP/FTP streaming. By default MP4Box always stores with 0.5 second interleaving. An interleaving value of '0' stores without interleaving (meta-data then track after track). .br +.B \-old-inter duration +same as -inter but without drift adjustment +.br .B NOTE: Track Edit Lists are ignored when performing interleaving. .TP .B \-flat @@ -60,8 +85,14 @@ specifies output file name. .B -tmp\ \ specifies driectory for temporary storage. If not set, temporary storage is OS-dependent. .TP +.B -ffspace size +inserts free space before moof in fragmented files. +.TP .B \-nosys -removes all MPEG-4 Systems information from the file but keeps an empty IOD for MPEG-4 Profile@Level indications. +removes all MPEG-4 Systems information from the file but keeps an empty IOD for MPEG-4 Profile@Level indications. alias: -no-sys +.TP +.B \-no-iod +removes InitialObjectDescriptor from file. .TP .B \-isma rewrites the file as an ISMA 1.0 Audio/Video file (all systems info rewritten) with proper clock references. @@ -74,6 +105,18 @@ rewrites the file as an ISMA 1.0 Audio/Video file (all systems info rewritten) w .B \-3gp rewrites the file as a 3GP file (no more MPEG-4 Systems specific info). This option is turned on by default when input file extension is .3gp or .3g2. .TP +.B \-ipod +rewrites the file for iPod. +.TP +.B \-brand ABCD[:v] +sets major brand of file, with optional version. +.TP +.B \-ab ABCD +adds given brand to file's alternate brand list. +.TP +.B \-rb ABCD +removes given brand to file's alternate brand list. +.TP .B -cprt string adds string copyright notice to file. .TP @@ -83,6 +126,12 @@ adds chapter information contained in chap_file to movie. For more details on ch .B -rem trackID removes given track from file - can be specified multiple times. .TP +.B -enable trackID +enables given track. +.TP +.B -disable trackID +disables given track. +.TP .B -new forces creation of a new destination file. .TP @@ -92,14 +141,75 @@ sets the language of all tracks or the given track. LAN is the ISO 639-2 3 chara .B -delay [tkID=]delay_ms sets the delay in milliseconds of all tracks or the given track. LAN is the ISO 639-2 3 character code. .TP +.B -par tkID=PAR +sets visual track pixel aspect ratio (PAR=Num:Den or "none"). +.TP +.B -name tkID=name +sets track handler name. +.TP +.B -itags tag1[:tag2] +sets iTunes tags to file - more info: MP4Box -tag-list. +.TP .B \-split time_in_seconds splits in files of desired maximum duration. This will remove all MPEG-4 Systems media. .TP -.B \-splits size_in_kilobytes -splits in files of desired maximum size. This will remove all MPEG-4 Systems media. +.B \-split-size size_in_kilobytes +splits in files of desired maximum size. This will remove all MPEG-4 Systems media. Alias: -splits +.TP +.B \-split-chunk start:end +extracts a new file from specified start to end times (in seconds). This will remove all MPEG-4 Systems media. Alias: -splitx .TP -.B \-splitx start:end -extracts a new file from specified start to end times (in seconds). This will remove all MPEG-4 Systems media. +.B \-split-rap start:end +splits in files begining at each RAP. This will remove all MPEG-4 Systems media. Alias: -splitr +.TP +.B \-group-add fmt +creates a new grouping information in the file. Format is a colon-separated list of following options: +.br +refTrack=ID: ID of the track used as a group reference. If not set, the track will belong to the same group as the previous trackID specified. If 0 or no previous track specified, a new alternate group will be created. +.br +switchID=ID: ID of the switch group to create. If 0, a new ID will be computed for you. If <0, disables SwitchGroup. +.br +criteria=string: list of space-separated 4CCs. +.br +trackID=ID: ID of the track to add to this group. +.br +*WARNING* Options modify state as they are parsed: trackID=1:criteria=lang:trackID=2 is different from: criteria=lang:trackID=1:trackID=2. +.B \-group-rem-track ID +removes track from its group. +.TP +.B \-group-rem ID +removes the track's group. +.TP +.B \-group-clean +removes all group information from all tracks. +.TP +.B \-ref id:XXXX:refID +adds a reference of type 4CC from track ID to track refID. +.TP +.B \-dash DUR +enables DASH-ing of the file with a segment duration of DUR. +.TP +.B \-rap +segments begin with random access points. +.TP +.B \-frags-per-sidx N +sets the number of segments to be written in each SIDX box. +.TP +.B \-segment-name name +sets the segment name for generated segments. +.TP +.B \-segment-ext name +sets the segment extension name. Default is m4s. +.TP +.B \-url-template +uses UrlTemplate instead of explicit sources in segments. +.TP +.B \-daisy-chain +Uses daisy-chain SIDX instead of hierarchical. Ignored if frags/sidx is 0. +.TP +.B \-dash-ctx FILE +Stores/restore DASH timing from FILE. + .B When input file is an ISO-Media file (QT, MP4, 3GP), if no output is specified THE INPUT FILE IS OVERWRITTEN. . . @@ -157,7 +267,7 @@ enables Access Units concatenation in RTP packets (-ts, -size and -idx are selec prevents system tracks embedding in IOD (ISMA-like IOD) when generating in SDP. MP4Box automatically detects ambiguous (ISMA/non-ISMA) files but nobody's perfect. This shouldn't be used with -isma option. . .TP -.B \-sdp_ex string +.B \-add-sdp string adds string to movie SDP or track SDP (tkID:string, where tkID is the OD of the hint track or its media track). This takes care of SDP line reordering, but not of SDP content validity. .TP .B \-unhint @@ -181,10 +291,14 @@ file#trackID=ID or file#ID: imports given trackfrom src_file. To get a listing o .B \-cat concatenates all src_file tracks to input file, creating it if not exisiting. Media samples are added at the end of existing compatible tracks. If no compatible track is found for a media it is created. Up to 20 cumulated -cat operations can be used. Syntax is the same as -add. .TP +.B \-force-cat +skips media configuration check when concatenating file. +.TP .B \-keepsys by default all MPEG-4 systems media are removed with -add and -cat. This option will avoid removing them from final file. .TP -. +.B \-keep-all +keeps all existing tracks when add file. .TP .B \-dref keeps media data in original file an only imports meta-data (frame timing, size and random access). @@ -193,7 +307,7 @@ keeps media data in original file an only imports meta-data (frame timing, size .B NOTE Data referencing may fail with some AVI because it requires the framed data (eg an MP4 sample) to be continuous in the original file, which is not always the case depending on the original interleaving. .TP -.B \-nodrop +.B \-no-drop forces constant FPS when importing AVI video. By default non coded frames (n-vop) are removed at import time, resulting in a variable frame-rate media. .TP .B \-packed @@ -204,6 +318,15 @@ imports AAC as AAC-SBR, with backward compatible signaling (non AAC-SBR decoders .TP .B \-sbrx imports AAC as AAC-SBR, with non-backward compatible signaling (non AAC-SBR decoders will not be able to play it). +.TP +.B \-ovsbr +imports AAC as AAC-SBR with oversample SBR. +.TP +.B \-ps +imports AAC as AAC-PS, with backward compatible signaling of AAC-PS. +.TP +.B \-psx +imports AAC as AAC-PS, with non-backward compatible signaling (non AAC-PS decoders will not be able to play it). .TP .B \-fps FrameRate overrides the input video frame rate or specifies it for SUB subtitles. @@ -235,12 +358,59 @@ forces BIFS random access point generation every time milliseconds. Cannot be us .B \-shadow time forces BIFS shadow random access points generation every time milliseconds. Shadow samples are random access points that can be used instead of non random access points when seeking. WARNING: this may be not supported by some players (EXPERTS ONLY - DANGEROUS). Cannot be used with -sync. .TP -.B \-inctx file +.B \-ctx-in file specifies initial context (MP4/BT/XMTA) for chunk processing. Input file must then be a command-only file: no IOD, and no implicit commands (commands without 'AT'). .TP -.B \-outctx file +.B \-ctx-out file specifies output file of updated context (MP4/BT/XMTA) in chunk processing mode. This is optional, chunk processing doesn't need to store the final context. +.TP +.B \-resolution res +LASeR resolution factor (-8 to 7, default 0). All coords are multiplied by 2^res before truncation. +.TP +.B \-coord-bits bits +bits used for encoding truncated coordinates in LASeR. (0 to 31, default 12) +.TP +.B \-scale-bits bits +bits used for encoding truncated scales in LASeR. (0 to 4, default 0) +.TP +.B \-auto-quant res +Use automatic LASeR quantification. resolution is given as if using -resolution but coord-bits and scale-bits are infered. . +.SH ISMACRYPT OPTIONS +.TP +.B \-crypt drm_file +crypts a specific track using ISMA AES CTR 128. +.TP +.B \-decrypt [drm_file] +decrypts a specific track using ISMA AES CTR 128. drm_file can be omitted if keys are in file. +.TP +.B \-set-kms [tkID=]kms_uri +changes KMS location for all tracks or a given one if tkID is specified. +.TP +.B \DRM file syntax for GPAC ISMACryp +File is XML and shall start with xml header. File root is an "ISMACryp" element. File is a list of "ISMACrypTrack" elements. +.br +ISMACrypTrack attributes: +.br +TrackID: ID of track to en/decrypt. +.br +key: AES-128 key formatted (hex string 0x +32 chars. +.br +salt: CTR IV salt key (64 bits) (hex string 0x +16 chars. +.br +Encryption only attributes +.br +Scheme_URI: URI of scheme used. +.br +KMS_URI: URI of key management system - \'self\' writes key and salt in the file. +.br +selectiveType selective encryption type - understood values are "None": all samples encrypted (default), "RAP": only encrypts random access units, "Non-RAP": only encrypts non-random access units, "Rand": random selection is performed", "X": Encrypts every first sample out of X, "RandX": Encrypts one random sample out of X. +.br +ipmpType: IPMP Signaling Type: None, IPMP, IPMPX. +.br +ipmpDescriptorID: IPMP_Descriptor ID to use if IPMP(X) is used. If not set MP4Box will generate one for you. +. + .SH EXTRACTING OPTIONS .TP .B \-raw TrackID @@ -252,6 +422,9 @@ extract each track sample to a file. Note: 'TrackID:N' extracts Nth sample of th .B \-nhnt TrackID extracts given track in NHNT format. All track types except ObjectDescriptors tracks can be exported. .TP +.B \-nhml TrackID +extracts track in nhml format (XML nhnt). All track types except ObjectDescriptors tracks can be exported. +.TP .B \-single TrackID extracts given track to a new mp4 file with a single track. .TP @@ -263,6 +436,15 @@ same as '-raw' but defaults to QCP file format for AVRC and SMV audio codecs. .TP .B \-aviraw TK extracts AVI track to its raw format. TK can be one of "video", "audio" or "audioN" for multi-track avi files (cf '-info'). +.TP +.B \-saf +remux file to SAF multiplex. +.TP +.B \-dvbhdemux +demux DVB-H file into IP Datagrams. +.TP +.B \-diod +extracts file IOD in raw format when supported. . .SH DUMP OPTIONS .TP @@ -284,18 +466,30 @@ dumps complete scene in an X3D XML file. This will remove unknown X3D nodes. .B \-x3dv dumps complete scene in an X3D Text (VRML) file. This will remove unknown X3D nodes. .TP +.B \-lsr +dumps complete scene in a LASeR+XML file. +.TP .B \-diso creates XML image of the file atoms. .TP .B \-drtp creates XML image of all hint tracks samples of a hinted mp4 file. .TP +.B \-dts +prints sample timing to text output. +.TP .B \-dcr creates XML image of all ISMACryp tracks samples of an mp4 file. .TP .B \-sdp creates SDP file associated with a hinted mp4 file. .TP +.B \-dump-cover +Extracts cover art if any. +.TP +.B \-dump-chap +Extracts chapter list to file if any. +.TP .B \-ttxt converts input subtitle to GPAC TTXT format. .TP @@ -319,6 +513,9 @@ generates statistic report on node/field usage per BIFS Access Unit. .TP .B \-statx generates statistic report on node/field usage in the scene graph after each BIFS Access Unit. +.TP +.B \-hash +generates SHA-1 Hash of the input file. . .SH Meta OPTIONS . @@ -361,28 +558,103 @@ dumps the XML data of the given meta to a file. .TP .B \-dump-item itemID[;tk=ID][;path=fileName] dumps the given item of the the given meta to a file. By default the item name is used as the output file name. +.TP +.B \-package +packages input XML file into an ISO container. all media referenced except hyperlinks are added to file. +.TP +.B \-mgt +packages input XML file into an MPEG-U widget in ISO container. All files contained in the current folder are added to the widget package. +. +.SH RTP STREAMER OPTIONS +. +.LP +MP4Box can stream ISO files to RTP. The streamer currently doesn't support data carrouselling and will therefore not handle BIFS and OD streams properly. +.TP +.B \-rtp +enables rtp file streamer. +.TP +.B \-noloop +disables looping when streaming. +.TP +.B \-mpeg4 +forces MPEG-4 ES Generic for all RTP streams. +.TP +.B \-dst=IP +IP destination (uni/multi-cast). Default: 127.0.0.1. +.TP +.B \-port=PORT +output port of the first stream. Default: 7000. +.TP +.B \-mtu=MTU +path MTU for RTP packets. Default is 1450 bytes. +.TP +.B \-ifce=IP +IP address of the physical interface to use. Default: NULL (ANY). +.TP +.B \-ttl=N +time to live for multicast packets. Default: 1. +.TP +.B \-sdp=FILE +file name of the generated SDP. Default is session.sdp. +. +.SH LIVE SCENE STREAMER OPTIONS +. +.LP +MP4Box can stream BIFS or DIMS content to RTP with carousel generation and updates. The streamer currently doesn't support audio/video/image streaming at the same time. All options supported by the file streamer are supported. +.TP +.B \-live +enables rtp live streamer. +.TP +.B \-dims +turns on DIMS mode for SVG input - default: off. +.TP +.B \-src=FILE +source of updates - default: null. +.TP +.B \-rap=TIME +duration in ms of base carousel - default: 0 (off). you can specify the RAP period of a single ESID (not in DIMS) with -rap=ESID=X:time. +.TP +.B \Runtime Options +The following options can be used at prompt: +.br +q: quits +.br +u: inputs some commands to be sent +.br +U: same as u but signals the updates as critical +.br +e: inputs some commands to be sent without being aggregated +.br +E: same as e but signals the updates as critical +.br +f: forces RAP sending +.br +F: forces RAP regeneration and sending +.br +p: dumps current scene +. . .SH SWF OPTIONS . .LP MP4Box can import very simple Macromedia Flash files (".SWF"). You can specify a SWF input file with -bt, xmt and -mp4 switches. .TP -.B \-static +.B \-global all SWF defines are placed in first scene replace. By default SWF defines are sent when needed. .TP -.B \-ctrl -uses a dedicated stream for movie control (forces -static option). +.B \-no-ctrl +uses a dedicated stream for movie control. This will disable ActionScript. .TP -.B \-notext +.B \-no-text removes all SWF text. .TP -.B \-nofont +.B \-no-font removes all embedded SWF Fonts, forcing usage of MPEG-4 Text and terminal fonts. .TP -.B \-noline +.B \-no-line removes all lines from SWF shapes. .TP -.B \-nograd +.B \-no-grad removes all gradients from swf shapes. .TP .B \-quad @@ -523,7 +795,7 @@ For bug reports, more information on BT or XMT-A formats or GPAC TTXT files or I . .SH "AUTHORS" .LP -Jean Le Feuvre - GPAC (c) 2000-2005 +Jean Le Feuvre - GPAC (c) 2000-2005 - (c) Telecom ParisTech 2005-2011 . .SH "SEE ALSO" .LP diff --git a/doc/man/mp4client.1 b/doc/man/mp4client.1 index 14bbc04..c7e58e1 100644 --- a/doc/man/mp4client.1 +++ b/doc/man/mp4client.1 @@ -25,6 +25,9 @@ logs run-time information to file. Information logged is: FPS, CPU, Memory usage .TP .B \-quiet removes script message, buffering and downloading status. +.TP +.B \-strict-error +exits after the first error is reported. . .SH PLAYBACK OPTIONS A file can be controled during playback by typing one of the following key at prompt. @@ -193,7 +196,7 @@ Mouse: Horizontal move: Y-Axis rotate - Vertical move: X-Axis rotate Keys: left/right: Y-Axis rotate - up/down: X-Axis rotate .TP .B SHIFT -.Speeds up movement +Speeds up movement . .SH VISUAL EXTRACTION OPTIONS When used to dump a visual presentation, the client is no longer interactive. All GPAC features are supported during capture, except audio-related ones. The following options can be passed at prompt: diff --git a/extra_lib/include/ffmpeg_android/.classpath b/extra_lib/include/ffmpeg_android/.classpath new file mode 100644 index 0000000..609aa00 --- /dev/null +++ b/extra_lib/include/ffmpeg_android/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/extra_lib/include/ffmpeg_android/.project b/extra_lib/include/ffmpeg_android/.project new file mode 100644 index 0000000..1e7da8d --- /dev/null +++ b/extra_lib/include/ffmpeg_android/.project @@ -0,0 +1,33 @@ + + + ffmpeg + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/extra_lib/include/ffmpeg_android/libavcodec/avcodec.h b/extra_lib/include/ffmpeg_android/libavcodec/avcodec.h new file mode 100644 index 0000000..add4b10 --- /dev/null +++ b/extra_lib/include/ffmpeg_android/libavcodec/avcodec.h @@ -0,0 +1,3952 @@ +/* + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg 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.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AVCODEC_H +#define AVCODEC_AVCODEC_H + +/** + * @file libavcodec/avcodec.h + * external API header + */ + +#include +#include "libavutil/avutil.h" + +#define LIBAVCODEC_VERSION_MAJOR 52 +#define LIBAVCODEC_VERSION_MINOR 66 +#define LIBAVCODEC_VERSION_MICRO 0 + +#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ + LIBAVCODEC_VERSION_MINOR, \ + LIBAVCODEC_VERSION_MICRO) +#define LIBAVCODEC_VERSION AV_VERSION(LIBAVCODEC_VERSION_MAJOR, \ + LIBAVCODEC_VERSION_MINOR, \ + LIBAVCODEC_VERSION_MICRO) +#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT + +#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) + +#define AV_NOPTS_VALUE INT64_C(0x8000000000000000) +#define AV_TIME_BASE 1000000 +#define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE} + +/** + * Identifies the syntax and semantics of the bitstream. + * The principle is roughly: + * Two decoders with the same ID can decode the same streams. + * Two encoders with the same ID can encode compatible streams. + * There may be slight deviations from the principle due to implementation + * details. + * + * If you add a codec ID to this list, add it so that + * 1. no value of a existing codec ID changes (that would break ABI), + * 2. it is as close as possible to similar codecs. + */ +enum CodecID { + CODEC_ID_NONE, + + /* video codecs */ + CODEC_ID_MPEG1VIDEO, + CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding + CODEC_ID_MPEG2VIDEO_XVMC, + CODEC_ID_H261, + CODEC_ID_H263, + CODEC_ID_RV10, + CODEC_ID_RV20, + CODEC_ID_MJPEG, + CODEC_ID_MJPEGB, + CODEC_ID_LJPEG, + CODEC_ID_SP5X, + CODEC_ID_JPEGLS, + CODEC_ID_MPEG4, + CODEC_ID_RAWVIDEO, + CODEC_ID_MSMPEG4V1, + CODEC_ID_MSMPEG4V2, + CODEC_ID_MSMPEG4V3, + CODEC_ID_WMV1, + CODEC_ID_WMV2, + CODEC_ID_H263P, + CODEC_ID_H263I, + CODEC_ID_FLV1, + CODEC_ID_SVQ1, + CODEC_ID_SVQ3, + CODEC_ID_DVVIDEO, + CODEC_ID_HUFFYUV, + CODEC_ID_CYUV, + CODEC_ID_H264, + CODEC_ID_INDEO3, + CODEC_ID_VP3, + CODEC_ID_THEORA, + CODEC_ID_ASV1, + CODEC_ID_ASV2, + CODEC_ID_FFV1, + CODEC_ID_4XM, + CODEC_ID_VCR1, + CODEC_ID_CLJR, + CODEC_ID_MDEC, + CODEC_ID_ROQ, + CODEC_ID_INTERPLAY_VIDEO, + CODEC_ID_XAN_WC3, + CODEC_ID_XAN_WC4, + CODEC_ID_RPZA, + CODEC_ID_CINEPAK, + CODEC_ID_WS_VQA, + CODEC_ID_MSRLE, + CODEC_ID_MSVIDEO1, + CODEC_ID_IDCIN, + CODEC_ID_8BPS, + CODEC_ID_SMC, + CODEC_ID_FLIC, + CODEC_ID_TRUEMOTION1, + CODEC_ID_VMDVIDEO, + CODEC_ID_MSZH, + CODEC_ID_ZLIB, + CODEC_ID_QTRLE, + CODEC_ID_SNOW, + CODEC_ID_TSCC, + CODEC_ID_ULTI, + CODEC_ID_QDRAW, + CODEC_ID_VIXL, + CODEC_ID_QPEG, +#if LIBAVCODEC_VERSION_MAJOR < 53 + CODEC_ID_XVID, +#endif + CODEC_ID_PNG, + CODEC_ID_PPM, + CODEC_ID_PBM, + CODEC_ID_PGM, + CODEC_ID_PGMYUV, + CODEC_ID_PAM, + CODEC_ID_FFVHUFF, + CODEC_ID_RV30, + CODEC_ID_RV40, + CODEC_ID_VC1, + CODEC_ID_WMV3, + CODEC_ID_LOCO, + CODEC_ID_WNV1, + CODEC_ID_AASC, + CODEC_ID_INDEO2, + CODEC_ID_FRAPS, + CODEC_ID_TRUEMOTION2, + CODEC_ID_BMP, + CODEC_ID_CSCD, + CODEC_ID_MMVIDEO, + CODEC_ID_ZMBV, + CODEC_ID_AVS, + CODEC_ID_SMACKVIDEO, + CODEC_ID_NUV, + CODEC_ID_KMVC, + CODEC_ID_FLASHSV, + CODEC_ID_CAVS, + CODEC_ID_JPEG2000, + CODEC_ID_VMNC, + CODEC_ID_VP5, + CODEC_ID_VP6, + CODEC_ID_VP6F, + CODEC_ID_TARGA, + CODEC_ID_DSICINVIDEO, + CODEC_ID_TIERTEXSEQVIDEO, + CODEC_ID_TIFF, + CODEC_ID_GIF, + CODEC_ID_FFH264, + CODEC_ID_DXA, + CODEC_ID_DNXHD, + CODEC_ID_THP, + CODEC_ID_SGI, + CODEC_ID_C93, + CODEC_ID_BETHSOFTVID, + CODEC_ID_PTX, + CODEC_ID_TXD, + CODEC_ID_VP6A, + CODEC_ID_AMV, + CODEC_ID_VB, + CODEC_ID_PCX, + CODEC_ID_SUNRAST, + CODEC_ID_INDEO4, + CODEC_ID_INDEO5, + CODEC_ID_MIMIC, + CODEC_ID_RL2, + CODEC_ID_8SVX_EXP, + CODEC_ID_8SVX_FIB, + CODEC_ID_ESCAPE124, + CODEC_ID_DIRAC, + CODEC_ID_BFI, + CODEC_ID_CMV, + CODEC_ID_MOTIONPIXELS, + CODEC_ID_TGV, + CODEC_ID_TGQ, + CODEC_ID_TQI, + CODEC_ID_AURA, + CODEC_ID_AURA2, + CODEC_ID_V210X, + CODEC_ID_TMV, + CODEC_ID_V210, + CODEC_ID_DPX, + CODEC_ID_MAD, + CODEC_ID_FRWU, + CODEC_ID_FLASHSV2, + CODEC_ID_CDGRAPHICS, + CODEC_ID_R210, + CODEC_ID_ANM, + CODEC_ID_BINKVIDEO, + CODEC_ID_IFF_ILBM, + CODEC_ID_IFF_BYTERUN1, + CODEC_ID_KGV1, + CODEC_ID_YOP, + + /* various PCM "codecs" */ + CODEC_ID_PCM_S16LE= 0x10000, + CODEC_ID_PCM_S16BE, + CODEC_ID_PCM_U16LE, + CODEC_ID_PCM_U16BE, + CODEC_ID_PCM_S8, + CODEC_ID_PCM_U8, + CODEC_ID_PCM_MULAW, + CODEC_ID_PCM_ALAW, + CODEC_ID_PCM_S32LE, + CODEC_ID_PCM_S32BE, + CODEC_ID_PCM_U32LE, + CODEC_ID_PCM_U32BE, + CODEC_ID_PCM_S24LE, + CODEC_ID_PCM_S24BE, + CODEC_ID_PCM_U24LE, + CODEC_ID_PCM_U24BE, + CODEC_ID_PCM_S24DAUD, + CODEC_ID_PCM_ZORK, + CODEC_ID_PCM_S16LE_PLANAR, + CODEC_ID_PCM_DVD, + CODEC_ID_PCM_F32BE, + CODEC_ID_PCM_F32LE, + CODEC_ID_PCM_F64BE, + CODEC_ID_PCM_F64LE, + CODEC_ID_PCM_BLURAY, + + /* various ADPCM codecs */ + CODEC_ID_ADPCM_IMA_QT= 0x11000, + CODEC_ID_ADPCM_IMA_WAV, + CODEC_ID_ADPCM_IMA_DK3, + CODEC_ID_ADPCM_IMA_DK4, + CODEC_ID_ADPCM_IMA_WS, + CODEC_ID_ADPCM_IMA_SMJPEG, + CODEC_ID_ADPCM_MS, + CODEC_ID_ADPCM_4XM, + CODEC_ID_ADPCM_XA, + CODEC_ID_ADPCM_ADX, + CODEC_ID_ADPCM_EA, + CODEC_ID_ADPCM_G726, + CODEC_ID_ADPCM_CT, + CODEC_ID_ADPCM_SWF, + CODEC_ID_ADPCM_YAMAHA, + CODEC_ID_ADPCM_SBPRO_4, + CODEC_ID_ADPCM_SBPRO_3, + CODEC_ID_ADPCM_SBPRO_2, + CODEC_ID_ADPCM_THP, + CODEC_ID_ADPCM_IMA_AMV, + CODEC_ID_ADPCM_EA_R1, + CODEC_ID_ADPCM_EA_R3, + CODEC_ID_ADPCM_EA_R2, + CODEC_ID_ADPCM_IMA_EA_SEAD, + CODEC_ID_ADPCM_IMA_EA_EACS, + CODEC_ID_ADPCM_EA_XAS, + CODEC_ID_ADPCM_EA_MAXIS_XA, + CODEC_ID_ADPCM_IMA_ISS, + + /* AMR */ + CODEC_ID_AMR_NB= 0x12000, + CODEC_ID_AMR_WB, + + /* RealAudio codecs*/ + CODEC_ID_RA_144= 0x13000, + CODEC_ID_RA_288, + + /* various DPCM codecs */ + CODEC_ID_ROQ_DPCM= 0x14000, + CODEC_ID_INTERPLAY_DPCM, + CODEC_ID_XAN_DPCM, + CODEC_ID_SOL_DPCM, + + /* audio codecs */ + CODEC_ID_MP2= 0x15000, + CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3 + CODEC_ID_AAC, + CODEC_ID_AC3, + CODEC_ID_DTS, + CODEC_ID_VORBIS, + CODEC_ID_DVAUDIO, + CODEC_ID_WMAV1, + CODEC_ID_WMAV2, + CODEC_ID_MACE3, + CODEC_ID_MACE6, + CODEC_ID_VMDAUDIO, + CODEC_ID_SONIC, + CODEC_ID_SONIC_LS, + CODEC_ID_FLAC, + CODEC_ID_MP3ADU, + CODEC_ID_MP3ON4, + CODEC_ID_SHORTEN, + CODEC_ID_ALAC, + CODEC_ID_WESTWOOD_SND1, + CODEC_ID_GSM, ///< as in Berlin toast format + CODEC_ID_QDM2, + CODEC_ID_COOK, + CODEC_ID_TRUESPEECH, + CODEC_ID_TTA, + CODEC_ID_SMACKAUDIO, + CODEC_ID_QCELP, + CODEC_ID_WAVPACK, + CODEC_ID_DSICINAUDIO, + CODEC_ID_IMC, + CODEC_ID_MUSEPACK7, + CODEC_ID_MLP, + CODEC_ID_GSM_MS, /* as found in WAV */ + CODEC_ID_ATRAC3, + CODEC_ID_VOXWARE, + CODEC_ID_APE, + CODEC_ID_NELLYMOSER, + CODEC_ID_MUSEPACK8, + CODEC_ID_SPEEX, + CODEC_ID_WMAVOICE, + CODEC_ID_WMAPRO, + CODEC_ID_WMALOSSLESS, + CODEC_ID_ATRAC3P, + CODEC_ID_EAC3, + CODEC_ID_SIPR, + CODEC_ID_MP1, + CODEC_ID_TWINVQ, + CODEC_ID_TRUEHD, + CODEC_ID_MP4ALS, + CODEC_ID_ATRAC1, + CODEC_ID_BINKAUDIO_RDFT, + CODEC_ID_BINKAUDIO_DCT, + + /* subtitle codecs */ + CODEC_ID_DVD_SUBTITLE= 0x17000, + CODEC_ID_DVB_SUBTITLE, + CODEC_ID_TEXT, ///< raw UTF-8 text + CODEC_ID_XSUB, + CODEC_ID_SSA, + CODEC_ID_MOV_TEXT, + CODEC_ID_HDMV_PGS_SUBTITLE, + CODEC_ID_DVB_TELETEXT, + + /* other specific kind of codecs (generally used for attachments) */ + CODEC_ID_TTF= 0x18000, + + CODEC_ID_PROBE= 0x19000, ///< codec_id is not known (like CODEC_ID_NONE) but lavf should attempt to identify it + + CODEC_ID_MPEG2TS= 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS + * stream (only used by libavformat) */ +}; + +#if LIBAVCODEC_VERSION_MAJOR < 53 +#define CodecType AVMediaType + +#define CODEC_TYPE_UNKNOWN AVMEDIA_TYPE_UNKNOWN +#define CODEC_TYPE_VIDEO AVMEDIA_TYPE_VIDEO +#define CODEC_TYPE_AUDIO AVMEDIA_TYPE_AUDIO +#define CODEC_TYPE_DATA AVMEDIA_TYPE_DATA +#define CODEC_TYPE_SUBTITLE AVMEDIA_TYPE_SUBTITLE +#define CODEC_TYPE_ATTACHMENT AVMEDIA_TYPE_ATTACHMENT +#define CODEC_TYPE_NB AVMEDIA_TYPE_NB +#endif + +/** + * all in native-endian format + */ +enum SampleFormat { + SAMPLE_FMT_NONE = -1, + SAMPLE_FMT_U8, ///< unsigned 8 bits + SAMPLE_FMT_S16, ///< signed 16 bits + SAMPLE_FMT_S32, ///< signed 32 bits + SAMPLE_FMT_FLT, ///< float + SAMPLE_FMT_DBL, ///< double + SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if dynamically linking to libavcodec +}; + +/* Audio channel masks */ +#define CH_FRONT_LEFT 0x00000001 +#define CH_FRONT_RIGHT 0x00000002 +#define CH_FRONT_CENTER 0x00000004 +#define CH_LOW_FREQUENCY 0x00000008 +#define CH_BACK_LEFT 0x00000010 +#define CH_BACK_RIGHT 0x00000020 +#define CH_FRONT_LEFT_OF_CENTER 0x00000040 +#define CH_FRONT_RIGHT_OF_CENTER 0x00000080 +#define CH_BACK_CENTER 0x00000100 +#define CH_SIDE_LEFT 0x00000200 +#define CH_SIDE_RIGHT 0x00000400 +#define CH_TOP_CENTER 0x00000800 +#define CH_TOP_FRONT_LEFT 0x00001000 +#define CH_TOP_FRONT_CENTER 0x00002000 +#define CH_TOP_FRONT_RIGHT 0x00004000 +#define CH_TOP_BACK_LEFT 0x00008000 +#define CH_TOP_BACK_CENTER 0x00010000 +#define CH_TOP_BACK_RIGHT 0x00020000 +#define CH_STEREO_LEFT 0x20000000 ///< Stereo downmix. +#define CH_STEREO_RIGHT 0x40000000 ///< See CH_STEREO_LEFT. + +/** Channel mask value used for AVCodecContext.request_channel_layout + to indicate that the user requests the channel order of the decoder output + to be the native codec channel order. */ +#define CH_LAYOUT_NATIVE 0x8000000000000000LL + +/* Audio channel convenience macros */ +#define CH_LAYOUT_MONO (CH_FRONT_CENTER) +#define CH_LAYOUT_STEREO (CH_FRONT_LEFT|CH_FRONT_RIGHT) +#define CH_LAYOUT_2_1 (CH_LAYOUT_STEREO|CH_BACK_CENTER) +#define CH_LAYOUT_SURROUND (CH_LAYOUT_STEREO|CH_FRONT_CENTER) +#define CH_LAYOUT_4POINT0 (CH_LAYOUT_SURROUND|CH_BACK_CENTER) +#define CH_LAYOUT_2_2 (CH_LAYOUT_STEREO|CH_SIDE_LEFT|CH_SIDE_RIGHT) +#define CH_LAYOUT_QUAD (CH_LAYOUT_STEREO|CH_BACK_LEFT|CH_BACK_RIGHT) +#define CH_LAYOUT_5POINT0 (CH_LAYOUT_SURROUND|CH_SIDE_LEFT|CH_SIDE_RIGHT) +#define CH_LAYOUT_5POINT1 (CH_LAYOUT_5POINT0|CH_LOW_FREQUENCY) +#define CH_LAYOUT_5POINT0_BACK (CH_LAYOUT_SURROUND|CH_BACK_LEFT|CH_BACK_RIGHT) +#define CH_LAYOUT_5POINT1_BACK (CH_LAYOUT_5POINT0_BACK|CH_LOW_FREQUENCY) +#define CH_LAYOUT_7POINT0 (CH_LAYOUT_5POINT0|CH_BACK_LEFT|CH_BACK_RIGHT) +#define CH_LAYOUT_7POINT1 (CH_LAYOUT_5POINT1|CH_BACK_LEFT|CH_BACK_RIGHT) +#define CH_LAYOUT_7POINT1_WIDE (CH_LAYOUT_5POINT1_BACK|\ + CH_FRONT_LEFT_OF_CENTER|CH_FRONT_RIGHT_OF_CENTER) +#define CH_LAYOUT_STEREO_DOWNMIX (CH_STEREO_LEFT|CH_STEREO_RIGHT) + +/* in bytes */ +#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio + +/** + * Required number of additionally allocated bytes at the end of the input bitstream for decoding. + * This is mainly needed because some optimized bitstream readers read + * 32 or 64 bit at once and could read over the end.
+ * Note: If the first 23 bits of the additional bytes are not 0, then damaged + * MPEG bitstreams could cause overread and segfault. + */ +#define FF_INPUT_BUFFER_PADDING_SIZE 8 + +/** + * minimum encoding buffer size + * Used to avoid some checks during header writing. + */ +#define FF_MIN_BUFFER_SIZE 16384 + + +/** + * motion estimation type. + */ +enum Motion_Est_ID { + ME_ZERO = 1, ///< no search, that is use 0,0 vector whenever one is needed + ME_FULL, + ME_LOG, + ME_PHODS, + ME_EPZS, ///< enhanced predictive zonal search + ME_X1, ///< reserved for experiments + ME_HEX, ///< hexagon based search + ME_UMH, ///< uneven multi-hexagon search + ME_ITER, ///< iterative search + ME_TESA, ///< transformed exhaustive search algorithm +}; + +enum AVDiscard{ + /* We leave some space between them for extensions (drop some + * keyframes for intra-only or drop just some bidir frames). */ + AVDISCARD_NONE =-16, ///< discard nothing + AVDISCARD_DEFAULT= 0, ///< discard useless packets like 0 size packets in avi + AVDISCARD_NONREF = 8, ///< discard all non reference + AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames + AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes + AVDISCARD_ALL = 48, ///< discard all +}; + +enum AVColorPrimaries{ + AVCOL_PRI_BT709 =1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B + AVCOL_PRI_UNSPECIFIED=2, + AVCOL_PRI_BT470M =4, + AVCOL_PRI_BT470BG =5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM + AVCOL_PRI_SMPTE170M =6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC + AVCOL_PRI_SMPTE240M =7, ///< functionally identical to above + AVCOL_PRI_FILM =8, + AVCOL_PRI_NB , ///< Not part of ABI +}; + +enum AVColorTransferCharacteristic{ + AVCOL_TRC_BT709 =1, ///< also ITU-R BT1361 + AVCOL_TRC_UNSPECIFIED=2, + AVCOL_TRC_GAMMA22 =4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM + AVCOL_TRC_GAMMA28 =5, ///< also ITU-R BT470BG + AVCOL_TRC_NB , ///< Not part of ABI +}; + +enum AVColorSpace{ + AVCOL_SPC_RGB =0, + AVCOL_SPC_BT709 =1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B + AVCOL_SPC_UNSPECIFIED=2, + AVCOL_SPC_FCC =4, + AVCOL_SPC_BT470BG =5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 + AVCOL_SPC_SMPTE170M =6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above + AVCOL_SPC_SMPTE240M =7, + AVCOL_SPC_NB , ///< Not part of ABI +}; + +enum AVColorRange{ + AVCOL_RANGE_UNSPECIFIED=0, + AVCOL_RANGE_MPEG =1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges + AVCOL_RANGE_JPEG =2, ///< the normal 2^n-1 "JPEG" YUV ranges + AVCOL_RANGE_NB , ///< Not part of ABI +}; + +/** + * X X 3 4 X X are luma samples, + * 1 2 1-6 are possible chroma positions + * X X 5 6 X 0 is undefined/unknown position + */ +enum AVChromaLocation{ + AVCHROMA_LOC_UNSPECIFIED=0, + AVCHROMA_LOC_LEFT =1, ///< mpeg2/4, h264 default + AVCHROMA_LOC_CENTER =2, ///< mpeg1, jpeg, h263 + AVCHROMA_LOC_TOPLEFT =3, ///< DV + AVCHROMA_LOC_TOP =4, + AVCHROMA_LOC_BOTTOMLEFT =5, + AVCHROMA_LOC_BOTTOM =6, + AVCHROMA_LOC_NB , ///< Not part of ABI +}; + +typedef struct RcOverride{ + int start_frame; + int end_frame; + int qscale; // If this is 0 then quality_factor will be used instead. + float quality_factor; +} RcOverride; + +#define FF_MAX_B_FRAMES 16 + +/* encoding support + These flags can be passed in AVCodecContext.flags before initialization. + Note: Not everything is supported yet. +*/ + +#define CODEC_FLAG_QSCALE 0x0002 ///< Use fixed qscale. +#define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / advanced prediction for H.263. +#define CODEC_FLAG_QPEL 0x0010 ///< Use qpel MC. +#define CODEC_FLAG_GMC 0x0020 ///< Use GMC. +#define CODEC_FLAG_MV0 0x0040 ///< Always try a MB with MV=<0,0>. +#define CODEC_FLAG_PART 0x0080 ///< Use data partitioning. +/** + * The parent program guarantees that the input for B-frames containing + * streams is not written to for at least s->max_b_frames+1 frames, if + * this is not set the input will be copied. + */ +#define CODEC_FLAG_INPUT_PRESERVED 0x0100 +#define CODEC_FLAG_PASS1 0x0200 ///< Use internal 2pass ratecontrol in first pass mode. +#define CODEC_FLAG_PASS2 0x0400 ///< Use internal 2pass ratecontrol in second pass mode. +#define CODEC_FLAG_EXTERN_HUFF 0x1000 ///< Use external Huffman table (for MJPEG). +#define CODEC_FLAG_GRAY 0x2000 ///< Only decode/encode grayscale. +#define CODEC_FLAG_EMU_EDGE 0x4000 ///< Don't draw edges. +#define CODEC_FLAG_PSNR 0x8000 ///< error[?] variables will be set during encoding. +#define CODEC_FLAG_TRUNCATED 0x00010000 /** Input bitstream might be truncated at a random + location instead of only at frame boundaries. */ +#define CODEC_FLAG_NORMALIZE_AQP 0x00020000 ///< Normalize adaptive quantization. +#define CODEC_FLAG_INTERLACED_DCT 0x00040000 ///< Use interlaced DCT. +#define CODEC_FLAG_LOW_DELAY 0x00080000 ///< Force low delay. +#define CODEC_FLAG_ALT_SCAN 0x00100000 ///< Use alternate scan. +#define CODEC_FLAG_GLOBAL_HEADER 0x00400000 ///< Place global headers in extradata instead of every keyframe. +#define CODEC_FLAG_BITEXACT 0x00800000 ///< Use only bitexact stuff (except (I)DCT). +/* Fx : Flag for h263+ extra options */ +#define CODEC_FLAG_AC_PRED 0x01000000 ///< H.263 advanced intra coding / MPEG-4 AC prediction +#define CODEC_FLAG_H263P_UMV 0x02000000 ///< unlimited motion vector +#define CODEC_FLAG_CBP_RD 0x04000000 ///< Use rate distortion optimization for cbp. +#define CODEC_FLAG_QP_RD 0x08000000 ///< Use rate distortion optimization for qp selectioon. +#define CODEC_FLAG_H263P_AIV 0x00000008 ///< H.263 alternative inter VLC +#define CODEC_FLAG_OBMC 0x00000001 ///< OBMC +#define CODEC_FLAG_LOOP_FILTER 0x00000800 ///< loop filter +#define CODEC_FLAG_H263P_SLICE_STRUCT 0x10000000 +#define CODEC_FLAG_INTERLACED_ME 0x20000000 ///< interlaced motion estimation +#define CODEC_FLAG_SVCD_SCAN_OFFSET 0x40000000 ///< Will reserve space for SVCD scan offset user data. +#define CODEC_FLAG_CLOSED_GOP 0x80000000 +#define CODEC_FLAG2_FAST 0x00000001 ///< Allow non spec compliant speedup tricks. +#define CODEC_FLAG2_STRICT_GOP 0x00000002 ///< Strictly enforce GOP size. +#define CODEC_FLAG2_NO_OUTPUT 0x00000004 ///< Skip bitstream encoding. +#define CODEC_FLAG2_LOCAL_HEADER 0x00000008 ///< Place global headers at every keyframe instead of in extradata. +#define CODEC_FLAG2_BPYRAMID 0x00000010 ///< H.264 allow B-frames to be used as references. +#define CODEC_FLAG2_WPRED 0x00000020 ///< H.264 weighted biprediction for B-frames +#define CODEC_FLAG2_MIXED_REFS 0x00000040 ///< H.264 one reference per partition, as opposed to one reference per macroblock +#define CODEC_FLAG2_8X8DCT 0x00000080 ///< H.264 high profile 8x8 transform +#define CODEC_FLAG2_FASTPSKIP 0x00000100 ///< H.264 fast pskip +#define CODEC_FLAG2_AUD 0x00000200 ///< H.264 access unit delimiters +#define CODEC_FLAG2_BRDO 0x00000400 ///< B-frame rate-distortion optimization +#define CODEC_FLAG2_INTRA_VLC 0x00000800 ///< Use MPEG-2 intra VLC table. +#define CODEC_FLAG2_MEMC_ONLY 0x00001000 ///< Only do ME/MC (I frames -> ref, P frame -> ME+MC). +#define CODEC_FLAG2_DROP_FRAME_TIMECODE 0x00002000 ///< timecode is in drop frame format. +#define CODEC_FLAG2_SKIP_RD 0x00004000 ///< RD optimal MB level residual skipping +#define CODEC_FLAG2_CHUNKS 0x00008000 ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries. +#define CODEC_FLAG2_NON_LINEAR_QUANT 0x00010000 ///< Use MPEG-2 nonlinear quantizer. +#define CODEC_FLAG2_BIT_RESERVOIR 0x00020000 ///< Use a bit reservoir when encoding if possible +#define CODEC_FLAG2_MBTREE 0x00040000 ///< Use macroblock tree ratecontrol (x264 only) +#define CODEC_FLAG2_PSY 0x00080000 ///< Use psycho visual optimizations. +#define CODEC_FLAG2_SSIM 0x00100000 ///< Compute SSIM during encoding, error[] values are undefined. + +/* Unsupported options : + * Syntax Arithmetic coding (SAC) + * Reference Picture Selection + * Independent Segment Decoding */ +/* /Fx */ +/* codec capabilities */ + +#define CODEC_CAP_DRAW_HORIZ_BAND 0x0001 ///< Decoder can use draw_horiz_band callback. +/** + * Codec uses get_buffer() for allocating buffers and supports custom allocators. + * If not set, it might not use get_buffer() at all or use operations that + * assume the buffer was allocated by avcodec_default_get_buffer. + */ +#define CODEC_CAP_DR1 0x0002 +/* If 'parse_only' field is true, then avcodec_parse_frame() can be used. */ +#define CODEC_CAP_PARSE_ONLY 0x0004 +#define CODEC_CAP_TRUNCATED 0x0008 +/* Codec can export data for HW decoding (XvMC). */ +#define CODEC_CAP_HWACCEL 0x0010 +/** + * Codec has a nonzero delay and needs to be fed with NULL at the end to get the delayed data. + * If this is not set, the codec is guaranteed to never be fed with NULL data. + */ +#define CODEC_CAP_DELAY 0x0020 +/** + * Codec can be fed a final frame with a smaller size. + * This can be used to prevent truncation of the last audio samples. + */ +#define CODEC_CAP_SMALL_LAST_FRAME 0x0040 +/** + * Codec can export data for HW decoding (VDPAU). + */ +#define CODEC_CAP_HWACCEL_VDPAU 0x0080 +/** + * Codec can output multiple frames per AVPacket + * Normally demuxers return one frame at a time, demuxers which do not do + * are connected to a parser to split what they return into proper frames. + * This flag is reserved to the very rare category of codecs which have a + * bitstream that cannot be split into frames without timeconsuming + * operations like full decoding. Demuxers carring such bitstreams thus + * may return multiple frames in a packet. This has many disadvantages like + * prohibiting stream copy in many cases thus it should only be considered + * as a last resort. + */ +#define CODEC_CAP_SUBFRAMES 0x0100 + +//The following defines may change, don't expect compatibility if you use them. +#define MB_TYPE_INTRA4x4 0x0001 +#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific +#define MB_TYPE_INTRA_PCM 0x0004 //FIXME H.264-specific +#define MB_TYPE_16x16 0x0008 +#define MB_TYPE_16x8 0x0010 +#define MB_TYPE_8x16 0x0020 +#define MB_TYPE_8x8 0x0040 +#define MB_TYPE_INTERLACED 0x0080 +#define MB_TYPE_DIRECT2 0x0100 //FIXME +#define MB_TYPE_ACPRED 0x0200 +#define MB_TYPE_GMC 0x0400 +#define MB_TYPE_SKIP 0x0800 +#define MB_TYPE_P0L0 0x1000 +#define MB_TYPE_P1L0 0x2000 +#define MB_TYPE_P0L1 0x4000 +#define MB_TYPE_P1L1 0x8000 +#define MB_TYPE_L0 (MB_TYPE_P0L0 | MB_TYPE_P1L0) +#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1) +#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1) +#define MB_TYPE_QUANT 0x00010000 +#define MB_TYPE_CBP 0x00020000 +//Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...) + +/** + * Pan Scan area. + * This specifies the area which should be displayed. + * Note there may be multiple such areas for one frame. + */ +typedef struct AVPanScan{ + /** + * id + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int id; + + /** + * width and height in 1/16 pel + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int width; + int height; + + /** + * position of the top left corner in 1/16 pel for up to 3 fields/frames + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int16_t position[3][2]; +}AVPanScan; + +#define FF_COMMON_FRAME \ + /**\ + * pointer to the picture planes.\ + * This might be different from the first allocated byte\ + * - encoding: \ + * - decoding: \ + */\ + uint8_t *data[4];\ + int linesize[4];\ + /**\ + * pointer to the first allocated byte of the picture. Can be used in get_buffer/release_buffer.\ + * This isn't used by libavcodec unless the default get/release_buffer() is used.\ + * - encoding: \ + * - decoding: \ + */\ + uint8_t *base[4];\ + /**\ + * 1 -> keyframe, 0-> not\ + * - encoding: Set by libavcodec.\ + * - decoding: Set by libavcodec.\ + */\ + int key_frame;\ +\ + /**\ + * Picture type of the frame, see ?_TYPE below.\ + * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\ + * - decoding: Set by libavcodec.\ + */\ + int pict_type;\ +\ + /**\ + * presentation timestamp in time_base units (time when frame should be shown to user)\ + * If AV_NOPTS_VALUE then frame_rate = 1/time_base will be assumed.\ + * - encoding: MUST be set by user.\ + * - decoding: Set by libavcodec.\ + */\ + int64_t pts;\ +\ + /**\ + * picture number in bitstream order\ + * - encoding: set by\ + * - decoding: Set by libavcodec.\ + */\ + int coded_picture_number;\ + /**\ + * picture number in display order\ + * - encoding: set by\ + * - decoding: Set by libavcodec.\ + */\ + int display_picture_number;\ +\ + /**\ + * quality (between 1 (good) and FF_LAMBDA_MAX (bad)) \ + * - encoding: Set by libavcodec. for coded_picture (and set by user for input).\ + * - decoding: Set by libavcodec.\ + */\ + int quality; \ +\ + /**\ + * buffer age (1->was last buffer and dint change, 2->..., ...).\ + * Set to INT_MAX if the buffer has not been used yet.\ + * - encoding: unused\ + * - decoding: MUST be set by get_buffer().\ + */\ + int age;\ +\ + /**\ + * is this picture used as reference\ + * The values for this are the same as the MpegEncContext.picture_structure\ + * variable, that is 1->top field, 2->bottom field, 3->frame/both fields.\ + * Set to 4 for delayed, non-reference frames.\ + * - encoding: unused\ + * - decoding: Set by libavcodec. (before get_buffer() call)).\ + */\ + int reference;\ +\ + /**\ + * QP table\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + int8_t *qscale_table;\ + /**\ + * QP store stride\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + int qstride;\ +\ + /**\ + * mbskip_table[mb]>=1 if MB didn't change\ + * stride= mb_width = (width+15)>>4\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + uint8_t *mbskip_table;\ +\ + /**\ + * motion vector table\ + * @code\ + * example:\ + * int mv_sample_log2= 4 - motion_subsample_log2;\ + * int mb_width= (width+15)>>4;\ + * int mv_stride= (mb_width << mv_sample_log2) + 1;\ + * motion_val[direction][x + y*mv_stride][0->mv_x, 1->mv_y];\ + * @endcode\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + int16_t (*motion_val[2])[2];\ +\ + /**\ + * macroblock type table\ + * mb_type_base + mb_width + 2\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + uint32_t *mb_type;\ +\ + /**\ + * log2 of the size of the block which a single vector in motion_val represents: \ + * (4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2)\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + uint8_t motion_subsample_log2;\ +\ + /**\ + * for some private data of the user\ + * - encoding: unused\ + * - decoding: Set by user.\ + */\ + void *opaque;\ +\ + /**\ + * error\ + * - encoding: Set by libavcodec. if flags&CODEC_FLAG_PSNR.\ + * - decoding: unused\ + */\ + uint64_t error[4];\ +\ + /**\ + * type of the buffer (to keep track of who has to deallocate data[*])\ + * - encoding: Set by the one who allocates it.\ + * - decoding: Set by the one who allocates it.\ + * Note: User allocated (direct rendering) & internal buffers cannot coexist currently.\ + */\ + int type;\ + \ + /**\ + * When decoding, this signals how much the picture must be delayed.\ + * extra_delay = repeat_pict / (2*fps)\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + int repeat_pict;\ + \ + /**\ + * \ + */\ + int qscale_type;\ + \ + /**\ + * The content of the picture is interlaced.\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec. (default 0)\ + */\ + int interlaced_frame;\ + \ + /**\ + * If the content is interlaced, is top field displayed first.\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + int top_field_first;\ + \ + /**\ + * Pan scan.\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + AVPanScan *pan_scan;\ + \ + /**\ + * Tell user application that palette has changed from previous frame.\ + * - encoding: ??? (no palette-enabled encoder yet)\ + * - decoding: Set by libavcodec. (default 0).\ + */\ + int palette_has_changed;\ + \ + /**\ + * codec suggestion on buffer type if != 0\ + * - encoding: unused\ + * - decoding: Set by libavcodec. (before get_buffer() call)).\ + */\ + int buffer_hints;\ +\ + /**\ + * DCT coefficients\ + * - encoding: unused\ + * - decoding: Set by libavcodec.\ + */\ + short *dct_coeff;\ +\ + /**\ + * motion reference frame index\ + * the order in which these are stored can depend on the codec.\ + * - encoding: Set by user.\ + * - decoding: Set by libavcodec.\ + */\ + int8_t *ref_index[2];\ +\ + /**\ + * reordered opaque 64bit number (generally a PTS) from AVCodecContext.reordered_opaque\ + * output in AVFrame.reordered_opaque\ + * - encoding: unused\ + * - decoding: Read by user.\ + */\ + int64_t reordered_opaque;\ +\ + /**\ + * hardware accelerator private data (FFmpeg allocated)\ + * - encoding: unused\ + * - decoding: Set by libavcodec\ + */\ + void *hwaccel_picture_private;\ + + +#define FF_QSCALE_TYPE_MPEG1 0 +#define FF_QSCALE_TYPE_MPEG2 1 +#define FF_QSCALE_TYPE_H264 2 +#define FF_QSCALE_TYPE_VP56 3 + +#define FF_BUFFER_TYPE_INTERNAL 1 +#define FF_BUFFER_TYPE_USER 2 ///< direct rendering buffers (image is (de)allocated by user) +#define FF_BUFFER_TYPE_SHARED 4 ///< Buffer from somewhere else; don't deallocate image (data/base), all other tables are not shared. +#define FF_BUFFER_TYPE_COPY 8 ///< Just a (modified) copy of some other buffer, don't deallocate anything. + + +#define FF_I_TYPE 1 ///< Intra +#define FF_P_TYPE 2 ///< Predicted +#define FF_B_TYPE 3 ///< Bi-dir predicted +#define FF_S_TYPE 4 ///< S(GMC)-VOP MPEG4 +#define FF_SI_TYPE 5 ///< Switching Intra +#define FF_SP_TYPE 6 ///< Switching Predicted +#define FF_BI_TYPE 7 + +#define FF_BUFFER_HINTS_VALID 0x01 // Buffer hints value is meaningful (if 0 ignore). +#define FF_BUFFER_HINTS_READABLE 0x02 // Codec will read from buffer. +#define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content. +#define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update). + +typedef struct AVPacket { + /** + * Presentation timestamp in AVStream->time_base units; the time at which + * the decompressed packet will be presented to the user. + * Can be AV_NOPTS_VALUE if it is not stored in the file. + * pts MUST be larger or equal to dts as presentation cannot happen before + * decompression, unless one wants to view hex dumps. Some formats misuse + * the terms dts and pts/cts to mean something different. Such timestamps + * must be converted to true pts/dts before they are stored in AVPacket. + */ + int64_t pts; + /** + * Decompression timestamp in AVStream->time_base units; the time at which + * the packet is decompressed. + * Can be AV_NOPTS_VALUE if it is not stored in the file. + */ + int64_t dts; + uint8_t *data; + int size; + int stream_index; + int flags; + /** + * Duration of this packet in AVStream->time_base units, 0 if unknown. + * Equals next_pts - this_pts in presentation order. + */ + int duration; + void (*destruct)(struct AVPacket *); + void *priv; + int64_t pos; ///< byte position in stream, -1 if unknown + + /** + * Time difference in AVStream->time_base units from the pts of this + * packet to the point at which the output from the decoder has converged + * independent from the availability of previous frames. That is, the + * frames are virtually identical no matter if decoding started from + * the very first frame or from this keyframe. + * Is AV_NOPTS_VALUE if unknown. + * This field is not the display duration of the current packet. + * + * The purpose of this field is to allow seeking in streams that have no + * keyframes in the conventional sense. It corresponds to the + * recovery point SEI in H.264 and match_time_delta in NUT. It is also + * essential for some types of subtitle streams to ensure that all + * subtitles are correctly displayed after seeking. + */ + int64_t convergence_duration; +} AVPacket; +#define AV_PKT_FLAG_KEY 0x0001 +#if LIBAVCODEC_VERSION_MAJOR < 53 +#define PKT_FLAG_KEY AV_PKT_FLAG_KEY +#endif + +/** + * Audio Video Frame. + * New fields can be added to the end of FF_COMMON_FRAME with minor version + * bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. No fields should be added into AVFrame before or after + * FF_COMMON_FRAME! + * sizeof(AVFrame) must not be used outside libav*. + */ +typedef struct AVFrame { + FF_COMMON_FRAME +} AVFrame; + +/** + * main external API structure. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(AVCodecContext) must not be used outside libav*. + */ +typedef struct AVCodecContext { + /** + * information on struct for av_log + * - set by avcodec_alloc_context + */ + const AVClass *av_class; + /** + * the average bitrate + * - encoding: Set by user; unused for constant quantizer encoding. + * - decoding: Set by libavcodec. 0 or some bitrate if this info is available in the stream. + */ + int bit_rate; + + /** + * number of bits the bitstream is allowed to diverge from the reference. + * the reference can be CBR (for CBR pass1) or VBR (for pass2) + * - encoding: Set by user; unused for constant quantizer encoding. + * - decoding: unused + */ + int bit_rate_tolerance; + + /** + * CODEC_FLAG_*. + * - encoding: Set by user. + * - decoding: Set by user. + */ + int flags; + + /** + * Some codecs need additional format info. It is stored here. + * If any muxer uses this then ALL demuxers/parsers AND encoders for the + * specific codec MUST set it correctly otherwise stream copy breaks. + * In general use of this field by muxers is not recommanded. + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. (FIXME: Is this OK?) + */ + int sub_id; + + /** + * Motion estimation algorithm used for video coding. + * 1 (zero), 2 (full), 3 (log), 4 (phods), 5 (epzs), 6 (x1), 7 (hex), + * 8 (umh), 9 (iter), 10 (tesa) [7, 8, 10 are x264 specific, 9 is snow specific] + * - encoding: MUST be set by user. + * - decoding: unused + */ + int me_method; + + /** + * some codecs need / can use extradata like Huffman tables. + * mjpeg: Huffman tables + * rv10: additional flags + * mpeg4: global headers (they can be in the bitstream or here) + * The allocated memory should be FF_INPUT_BUFFER_PADDING_SIZE bytes larger + * than extradata_size to avoid prolems if it is read with the bitstream reader. + * The bytewise contents of extradata must not depend on the architecture or CPU endianness. + * - encoding: Set/allocated/freed by libavcodec. + * - decoding: Set/allocated/freed by user. + */ + uint8_t *extradata; + int extradata_size; + + /** + * This is the fundamental unit of time (in seconds) in terms + * of which frame timestamps are represented. For fixed-fps content, + * timebase should be 1/framerate and timestamp increments should be + * identically 1. + * - encoding: MUST be set by user. + * - decoding: Set by libavcodec. + */ + AVRational time_base; + + /* video only */ + /** + * picture width / height. + * - encoding: MUST be set by user. + * - decoding: Set by libavcodec. + * Note: For compatibility it is possible to set this instead of + * coded_width/height before decoding. + */ + int width, height; + +#define FF_ASPECT_EXTENDED 15 + + /** + * the number of pictures in a group of pictures, or 0 for intra_only + * - encoding: Set by user. + * - decoding: unused + */ + int gop_size; + + /** + * Pixel format, see PIX_FMT_xxx. + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + enum PixelFormat pix_fmt; + + /** + * Frame rate emulation. If not zero, the lower layer (i.e. format handler) + * has to read frames at native frame rate. + * - encoding: Set by user. + * - decoding: unused + */ + int rate_emu; + + /** + * If non NULL, 'draw_horiz_band' is called by the libavcodec + * decoder to draw a horizontal band. It improves cache usage. Not + * all codecs can do that. You must check the codec capabilities + * beforehand. + * The function is also used by hardware acceleration APIs. + * It is called at least once during frame decoding to pass + * the data needed for hardware render. + * In that mode instead of pixel data, AVFrame points to + * a structure specific to the acceleration API. The application + * reads the structure and can change some fields to indicate progress + * or mark state. + * - encoding: unused + * - decoding: Set by user. + * @param height the height of the slice + * @param y the y position of the slice + * @param type 1->top field, 2->bottom field, 3->frame + * @param offset offset into the AVFrame.data from which the slice should be read + */ + void (*draw_horiz_band)(struct AVCodecContext *s, + const AVFrame *src, int offset[4], + int y, int type, int height); + + /* audio only */ + int sample_rate; ///< samples per second + int channels; ///< number of audio channels + + /** + * audio sample format + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + enum SampleFormat sample_fmt; ///< sample format + + /* The following data should not be initialized. */ + /** + * Samples per packet, initialized when calling 'init'. + */ + int frame_size; + int frame_number; ///< audio or video frame number +#if LIBAVCODEC_VERSION_MAJOR < 53 + int real_pict_num; ///< Returns the real picture number of previous encoded frame. +#endif + + /** + * Number of frames the decoded output will be delayed relative to + * the encoded input. + * - encoding: Set by libavcodec. + * - decoding: unused + */ + int delay; + + /* - encoding parameters */ + float qcompress; ///< amount of qscale change between easy & hard scenes (0.0-1.0) + float qblur; ///< amount of qscale smoothing over time (0.0-1.0) + + /** + * minimum quantizer + * - encoding: Set by user. + * - decoding: unused + */ + int qmin; + + /** + * maximum quantizer + * - encoding: Set by user. + * - decoding: unused + */ + int qmax; + + /** + * maximum quantizer difference between frames + * - encoding: Set by user. + * - decoding: unused + */ + int max_qdiff; + + /** + * maximum number of B-frames between non-B-frames + * Note: The output will be delayed by max_b_frames+1 relative to the input. + * - encoding: Set by user. + * - decoding: unused + */ + int max_b_frames; + + /** + * qscale factor between IP and B-frames + * If > 0 then the last P-frame quantizer will be used (q= lastp_q*factor+offset). + * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset). + * - encoding: Set by user. + * - decoding: unused + */ + float b_quant_factor; + + /** obsolete FIXME remove */ + int rc_strategy; +#define FF_RC_STRATEGY_XVID 1 + + int b_frame_strategy; + + /** + * hurry up amount + * - encoding: unused + * - decoding: Set by user. 1-> Skip B-frames, 2-> Skip IDCT/dequant too, 5-> Skip everything except header + * @deprecated Deprecated in favor of skip_idct and skip_frame. + */ + int hurry_up; + + struct AVCodec *codec; + + void *priv_data; + + int rtp_payload_size; /* The size of the RTP payload: the coder will */ + /* do its best to deliver a chunk with size */ + /* below rtp_payload_size, the chunk will start */ + /* with a start code on some codecs like H.263. */ + /* This doesn't take account of any particular */ + /* headers inside the transmitted RTP payload. */ + + + /* The RTP callback: This function is called */ + /* every time the encoder has a packet to send. */ + /* It depends on the encoder if the data starts */ + /* with a Start Code (it should). H.263 does. */ + /* mb_nb contains the number of macroblocks */ + /* encoded in the RTP payload. */ + void (*rtp_callback)(struct AVCodecContext *avctx, void *data, int size, int mb_nb); + + /* statistics, used for 2-pass encoding */ + int mv_bits; + int header_bits; + int i_tex_bits; + int p_tex_bits; + int i_count; + int p_count; + int skip_count; + int misc_bits; + + /** + * number of bits used for the previously encoded frame + * - encoding: Set by libavcodec. + * - decoding: unused + */ + int frame_bits; + + /** + * Private data of the user, can be used to carry app specific stuff. + * - encoding: Set by user. + * - decoding: Set by user. + */ + void *opaque; + + char codec_name[32]; + enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */ + enum CodecID codec_id; /* see CODEC_ID_xxx */ + + /** + * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). + * This is used to work around some encoder bugs. + * A demuxer should set this to what is stored in the field used to identify the codec. + * If there are multiple such fields in a container then the demuxer should choose the one + * which maximizes the information about the used codec. + * If the codec tag field in a container is larger then 32 bits then the demuxer should + * remap the longer ID to 32 bits with a table or other structure. Alternatively a new + * extra_codec_tag + size could be added but for this a clear advantage must be demonstrated + * first. + * - encoding: Set by user, if not then the default based on codec_id will be used. + * - decoding: Set by user, will be converted to uppercase by libavcodec during init. + */ + unsigned int codec_tag; + + /** + * Work around bugs in encoders which sometimes cannot be detected automatically. + * - encoding: Set by user + * - decoding: Set by user + */ + int workaround_bugs; +#define FF_BUG_AUTODETECT 1 ///< autodetection +#define FF_BUG_OLD_MSMPEG4 2 +#define FF_BUG_XVID_ILACE 4 +#define FF_BUG_UMP4 8 +#define FF_BUG_NO_PADDING 16 +#define FF_BUG_AMV 32 +#define FF_BUG_AC_VLC 0 ///< Will be removed, libavcodec can now handle these non-compliant files by default. +#define FF_BUG_QPEL_CHROMA 64 +#define FF_BUG_STD_QPEL 128 +#define FF_BUG_QPEL_CHROMA2 256 +#define FF_BUG_DIRECT_BLOCKSIZE 512 +#define FF_BUG_EDGE 1024 +#define FF_BUG_HPEL_CHROMA 2048 +#define FF_BUG_DC_CLIP 4096 +#define FF_BUG_MS 8192 ///< Work around various bugs in Microsoft's broken decoders. +#define FF_BUG_TRUNCATED 16384 +//#define FF_BUG_FAKE_SCALABILITY 16 //Autodetection should work 100%. + + /** + * luma single coefficient elimination threshold + * - encoding: Set by user. + * - decoding: unused + */ + int luma_elim_threshold; + + /** + * chroma single coeff elimination threshold + * - encoding: Set by user. + * - decoding: unused + */ + int chroma_elim_threshold; + + /** + * strictly follow the standard (MPEG4, ...). + * - encoding: Set by user. + * - decoding: Set by user. + * Setting this to STRICT or higher means the encoder and decoder will + * generally do stupid things. While setting it to inofficial or lower + * will mean the encoder might use things that are not supported by all + * spec compliant decoders. Decoders make no difference between normal, + * inofficial and experimental, that is they always try to decode things + * when they can unless they are explicitly asked to behave stupid + * (=strictly conform to the specs) + */ + int strict_std_compliance; +#define FF_COMPLIANCE_VERY_STRICT 2 ///< Strictly conform to a older more strict version of the spec or reference software. +#define FF_COMPLIANCE_STRICT 1 ///< Strictly conform to all the things in the spec no matter what consequences. +#define FF_COMPLIANCE_NORMAL 0 +#define FF_COMPLIANCE_INOFFICIAL -1 ///< Allow inofficial extensions. +#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< Allow nonstandardized experimental things. + + /** + * qscale offset between IP and B-frames + * - encoding: Set by user. + * - decoding: unused + */ + float b_quant_offset; + + /** + * Error recognization; higher values will detect more errors but may + * misdetect some more or less valid parts as errors. + * - encoding: unused + * - decoding: Set by user. + */ + int error_recognition; +#define FF_ER_CAREFUL 1 +#define FF_ER_COMPLIANT 2 +#define FF_ER_AGGRESSIVE 3 +#define FF_ER_VERY_AGGRESSIVE 4 + + /** + * Called at the beginning of each frame to get a buffer for it. + * If pic.reference is set then the frame will be read later by libavcodec. + * avcodec_align_dimensions2() should be used to find the required width and + * height, as they normally need to be rounded up to the next multiple of 16. + * if CODEC_CAP_DR1 is not set then get_buffer() must call + * avcodec_default_get_buffer() instead of providing buffers allocated by + * some other means. + * - encoding: unused + * - decoding: Set by libavcodec., user can override. + */ + int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * Called to release buffers which were allocated with get_buffer. + * A released buffer can be reused in get_buffer(). + * pic.data[*] must be set to NULL. + * - encoding: unused + * - decoding: Set by libavcodec., user can override. + */ + void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * Size of the frame reordering buffer in the decoder. + * For MPEG-2 it is 1 IPB or 0 low delay IP. + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. + */ + int has_b_frames; + + /** + * number of bytes per packet if constant and known or 0 + * Used by some WAV based audio codecs. + */ + int block_align; + + int parse_only; /* - decoding only: If true, only parsing is done + (function avcodec_parse_frame()). The frame + data is returned. Only MPEG codecs support this now. */ + + /** + * 0-> h263 quant 1-> mpeg quant + * - encoding: Set by user. + * - decoding: unused + */ + int mpeg_quant; + + /** + * pass1 encoding statistics output buffer + * - encoding: Set by libavcodec. + * - decoding: unused + */ + char *stats_out; + + /** + * pass2 encoding statistics input buffer + * Concatenated stuff from stats_out of pass1 should be placed here. + * - encoding: Allocated/set/freed by user. + * - decoding: unused + */ + char *stats_in; + + /** + * ratecontrol qmin qmax limiting method + * 0-> clipping, 1-> use a nice continous function to limit qscale wthin qmin/qmax. + * - encoding: Set by user. + * - decoding: unused + */ + float rc_qsquish; + + float rc_qmod_amp; + int rc_qmod_freq; + + /** + * ratecontrol override, see RcOverride + * - encoding: Allocated/set/freed by user. + * - decoding: unused + */ + RcOverride *rc_override; + int rc_override_count; + + /** + * rate control equation + * - encoding: Set by user + * - decoding: unused + */ + const char *rc_eq; + + /** + * maximum bitrate + * - encoding: Set by user. + * - decoding: unused + */ + int rc_max_rate; + + /** + * minimum bitrate + * - encoding: Set by user. + * - decoding: unused + */ + int rc_min_rate; + + /** + * decoder bitstream buffer size + * - encoding: Set by user. + * - decoding: unused + */ + int rc_buffer_size; + float rc_buffer_aggressivity; + + /** + * qscale factor between P and I-frames + * If > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset). + * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset). + * - encoding: Set by user. + * - decoding: unused + */ + float i_quant_factor; + + /** + * qscale offset between P and I-frames + * - encoding: Set by user. + * - decoding: unused + */ + float i_quant_offset; + + /** + * initial complexity for pass1 ratecontrol + * - encoding: Set by user. + * - decoding: unused + */ + float rc_initial_cplx; + + /** + * DCT algorithm, see FF_DCT_* below + * - encoding: Set by user. + * - decoding: unused + */ + int dct_algo; +#define FF_DCT_AUTO 0 +#define FF_DCT_FASTINT 1 +#define FF_DCT_INT 2 +#define FF_DCT_MMX 3 +#define FF_DCT_MLIB 4 +#define FF_DCT_ALTIVEC 5 +#define FF_DCT_FAAN 6 + + /** + * luminance masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float lumi_masking; + + /** + * temporary complexity masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float temporal_cplx_masking; + + /** + * spatial complexity masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float spatial_cplx_masking; + + /** + * p block masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float p_masking; + + /** + * darkness masking (0-> disabled) + * - encoding: Set by user. + * - decoding: unused + */ + float dark_masking; + + /** + * IDCT algorithm, see FF_IDCT_* below. + * - encoding: Set by user. + * - decoding: Set by user. + */ + int idct_algo; +#define FF_IDCT_AUTO 0 +#define FF_IDCT_INT 1 +#define FF_IDCT_SIMPLE 2 +#define FF_IDCT_SIMPLEMMX 3 +#define FF_IDCT_LIBMPEG2MMX 4 +#define FF_IDCT_PS2 5 +#define FF_IDCT_MLIB 6 +#define FF_IDCT_ARM 7 +#define FF_IDCT_ALTIVEC 8 +#define FF_IDCT_SH4 9 +#define FF_IDCT_SIMPLEARM 10 +#define FF_IDCT_H264 11 +#define FF_IDCT_VP3 12 +#define FF_IDCT_IPP 13 +#define FF_IDCT_XVIDMMX 14 +#define FF_IDCT_CAVS 15 +#define FF_IDCT_SIMPLEARMV5TE 16 +#define FF_IDCT_SIMPLEARMV6 17 +#define FF_IDCT_SIMPLEVIS 18 +#define FF_IDCT_WMV2 19 +#define FF_IDCT_FAAN 20 +#define FF_IDCT_EA 21 +#define FF_IDCT_SIMPLENEON 22 +#define FF_IDCT_SIMPLEALPHA 23 +#define FF_IDCT_BINK 24 + + /** + * slice count + * - encoding: Set by libavcodec. + * - decoding: Set by user (or 0). + */ + int slice_count; + /** + * slice offsets in the frame in bytes + * - encoding: Set/allocated by libavcodec. + * - decoding: Set/allocated by user (or NULL). + */ + int *slice_offset; + + /** + * error concealment flags + * - encoding: unused + * - decoding: Set by user. + */ + int error_concealment; +#define FF_EC_GUESS_MVS 1 +#define FF_EC_DEBLOCK 2 + + /** + * dsp_mask could be add used to disable unwanted CPU features + * CPU features (i.e. MMX, SSE. ...) + * + * With the FORCE flag you may instead enable given CPU features. + * (Dangerous: Usable in case of misdetection, improper usage however will + * result into program crash.) + */ + unsigned dsp_mask; +#define FF_MM_FORCE 0x80000000 /* Force usage of selected flags (OR) */ + /* lower 16 bits - CPU features */ +#define FF_MM_MMX 0x0001 ///< standard MMX +#define FF_MM_3DNOW 0x0004 ///< AMD 3DNOW +#if LIBAVCODEC_VERSION_MAJOR < 53 +#define FF_MM_MMXEXT 0x0002 ///< SSE integer functions or AMD MMX ext +#endif +#define FF_MM_MMX2 0x0002 ///< SSE integer functions or AMD MMX ext +#define FF_MM_SSE 0x0008 ///< SSE functions +#define FF_MM_SSE2 0x0010 ///< PIV SSE2 functions +#define FF_MM_3DNOWEXT 0x0020 ///< AMD 3DNowExt +#define FF_MM_SSE3 0x0040 ///< Prescott SSE3 functions +#define FF_MM_SSSE3 0x0080 ///< Conroe SSSE3 functions +#define FF_MM_SSE4 0x0100 ///< Penryn SSE4.1 functions +#define FF_MM_SSE42 0x0200 ///< Nehalem SSE4.2 functions +#define FF_MM_IWMMXT 0x0100 ///< XScale IWMMXT +#define FF_MM_ALTIVEC 0x0001 ///< standard AltiVec + + /** + * bits per sample/pixel from the demuxer (needed for huffyuv). + * - encoding: Set by libavcodec. + * - decoding: Set by user. + */ + int bits_per_coded_sample; + + /** + * prediction method (needed for huffyuv) + * - encoding: Set by user. + * - decoding: unused + */ + int prediction_method; +#define FF_PRED_LEFT 0 +#define FF_PRED_PLANE 1 +#define FF_PRED_MEDIAN 2 + + /** + * sample aspect ratio (0 if unknown) + * That is the width of a pixel divided by the height of the pixel. + * Numerator and denominator must be relatively prime and smaller than 256 for some video standards. + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + AVRational sample_aspect_ratio; + + /** + * the picture in the bitstream + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. + */ + AVFrame *coded_frame; + + /** + * debug + * - encoding: Set by user. + * - decoding: Set by user. + */ + int debug; +#define FF_DEBUG_PICT_INFO 1 +#define FF_DEBUG_RC 2 +#define FF_DEBUG_BITSTREAM 4 +#define FF_DEBUG_MB_TYPE 8 +#define FF_DEBUG_QP 16 +#define FF_DEBUG_MV 32 +#define FF_DEBUG_DCT_COEFF 0x00000040 +#define FF_DEBUG_SKIP 0x00000080 +#define FF_DEBUG_STARTCODE 0x00000100 +#define FF_DEBUG_PTS 0x00000200 +#define FF_DEBUG_ER 0x00000400 +#define FF_DEBUG_MMCO 0x00000800 +#define FF_DEBUG_BUGS 0x00001000 +#define FF_DEBUG_VIS_QP 0x00002000 +#define FF_DEBUG_VIS_MB_TYPE 0x00004000 +#define FF_DEBUG_BUFFERS 0x00008000 + + /** + * debug + * - encoding: Set by user. + * - decoding: Set by user. + */ + int debug_mv; +#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames +#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames +#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames + + /** + * error + * - encoding: Set by libavcodec if flags&CODEC_FLAG_PSNR. + * - decoding: unused + */ + uint64_t error[4]; + + /** + * minimum MB quantizer + * - encoding: unused + * - decoding: unused + */ + int mb_qmin; + + /** + * maximum MB quantizer + * - encoding: unused + * - decoding: unused + */ + int mb_qmax; + + /** + * motion estimation comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int me_cmp; + /** + * subpixel motion estimation comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int me_sub_cmp; + /** + * macroblock comparison function (not supported yet) + * - encoding: Set by user. + * - decoding: unused + */ + int mb_cmp; + /** + * interlaced DCT comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int ildct_cmp; +#define FF_CMP_SAD 0 +#define FF_CMP_SSE 1 +#define FF_CMP_SATD 2 +#define FF_CMP_DCT 3 +#define FF_CMP_PSNR 4 +#define FF_CMP_BIT 5 +#define FF_CMP_RD 6 +#define FF_CMP_ZERO 7 +#define FF_CMP_VSAD 8 +#define FF_CMP_VSSE 9 +#define FF_CMP_NSSE 10 +#define FF_CMP_W53 11 +#define FF_CMP_W97 12 +#define FF_CMP_DCTMAX 13 +#define FF_CMP_DCT264 14 +#define FF_CMP_CHROMA 256 + + /** + * ME diamond size & shape + * - encoding: Set by user. + * - decoding: unused + */ + int dia_size; + + /** + * amount of previous MV predictors (2a+1 x 2a+1 square) + * - encoding: Set by user. + * - decoding: unused + */ + int last_predictor_count; + + /** + * prepass for motion estimation + * - encoding: Set by user. + * - decoding: unused + */ + int pre_me; + + /** + * motion estimation prepass comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int me_pre_cmp; + + /** + * ME prepass diamond size & shape + * - encoding: Set by user. + * - decoding: unused + */ + int pre_dia_size; + + /** + * subpel ME quality + * - encoding: Set by user. + * - decoding: unused + */ + int me_subpel_quality; + + /** + * callback to negotiate the pixelFormat + * @param fmt is the list of formats which are supported by the codec, + * it is terminated by -1 as 0 is a valid format, the formats are ordered by quality. + * The first is always the native one. + * @return the chosen format + * - encoding: unused + * - decoding: Set by user, if not set the native format will be chosen. + */ + enum PixelFormat (*get_format)(struct AVCodecContext *s, const enum PixelFormat * fmt); + + /** + * DTG active format information (additional aspect ratio + * information only used in DVB MPEG-2 transport streams) + * 0 if not set. + * + * - encoding: unused + * - decoding: Set by decoder. + */ + int dtg_active_format; +#define FF_DTG_AFD_SAME 8 +#define FF_DTG_AFD_4_3 9 +#define FF_DTG_AFD_16_9 10 +#define FF_DTG_AFD_14_9 11 +#define FF_DTG_AFD_4_3_SP_14_9 13 +#define FF_DTG_AFD_16_9_SP_14_9 14 +#define FF_DTG_AFD_SP_4_3 15 + + /** + * maximum motion estimation search range in subpel units + * If 0 then no limit. + * + * - encoding: Set by user. + * - decoding: unused + */ + int me_range; + + /** + * intra quantizer bias + * - encoding: Set by user. + * - decoding: unused + */ + int intra_quant_bias; +#define FF_DEFAULT_QUANT_BIAS 999999 + + /** + * inter quantizer bias + * - encoding: Set by user. + * - decoding: unused + */ + int inter_quant_bias; + + /** + * color table ID + * - encoding: unused + * - decoding: Which clrtable should be used for 8bit RGB images. + * Tables have to be stored somewhere. FIXME + */ + int color_table_id; + + /** + * internal_buffer count + * Don't touch, used by libavcodec default_get_buffer(). + */ + int internal_buffer_count; + + /** + * internal_buffers + * Don't touch, used by libavcodec default_get_buffer(). + */ + void *internal_buffer; + +#define FF_LAMBDA_SHIFT 7 +#define FF_LAMBDA_SCALE (1< ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). + * This is used to work around some encoder bugs. + * - encoding: unused + * - decoding: Set by user, will be converted to uppercase by libavcodec during init. + */ + unsigned int stream_codec_tag; + + /** + * scene change detection threshold + * 0 is default, larger means fewer detected scene changes. + * - encoding: Set by user. + * - decoding: unused + */ + int scenechange_threshold; + + /** + * minimum Lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ + int lmin; + + /** + * maximum Lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ + int lmax; + + /** + * palette control structure + * - encoding: ??? (no palette-enabled encoder yet) + * - decoding: Set by user. + */ + struct AVPaletteControl *palctrl; + + /** + * noise reduction strength + * - encoding: Set by user. + * - decoding: unused + */ + int noise_reduction; + + /** + * Called at the beginning of a frame to get cr buffer for it. + * Buffer type (size, hints) must be the same. libavcodec won't check it. + * libavcodec will pass previous buffer in pic, function should return + * same buffer or new buffer with old frame "painted" into it. + * If pic.data[0] == NULL must behave like get_buffer(). + * if CODEC_CAP_DR1 is not set then reget_buffer() must call + * avcodec_default_reget_buffer() instead of providing buffers allocated by + * some other means. + * - encoding: unused + * - decoding: Set by libavcodec., user can override + */ + int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * Number of bits which should be loaded into the rc buffer before decoding starts. + * - encoding: Set by user. + * - decoding: unused + */ + int rc_initial_buffer_occupancy; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ + int inter_threshold; + + /** + * CODEC_FLAG2_* + * - encoding: Set by user. + * - decoding: Set by user. + */ + int flags2; + + /** + * Simulates errors in the bitstream to test error concealment. + * - encoding: Set by user. + * - decoding: unused + */ + int error_rate; + + /** + * MP3 antialias algorithm, see FF_AA_* below. + * - encoding: unused + * - decoding: Set by user. + */ + int antialias_algo; +#define FF_AA_AUTO 0 +#define FF_AA_FASTINT 1 //not implemented yet +#define FF_AA_INT 2 +#define FF_AA_FLOAT 3 + /** + * quantizer noise shaping + * - encoding: Set by user. + * - decoding: unused + */ + int quantizer_noise_shaping; + + /** + * thread count + * is used to decide how many independent tasks should be passed to execute() + * - encoding: Set by user. + * - decoding: Set by user. + */ + int thread_count; + + /** + * The codec may call this to execute several independent things. + * It will return only after finishing all tasks. + * The user may replace this with some multithreaded implementation, + * the default implementation will execute the parts serially. + * @param count the number of things to execute + * - encoding: Set by libavcodec, user can override. + * - decoding: Set by libavcodec, user can override. + */ + int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size); + + /** + * thread opaque + * Can be used by execute() to store some per AVCodecContext stuff. + * - encoding: set by execute() + * - decoding: set by execute() + */ + void *thread_opaque; + + /** + * Motion estimation threshold below which no motion estimation is + * performed, but instead the user specified motion vectors are used. + * + * - encoding: Set by user. + * - decoding: unused + */ + int me_threshold; + + /** + * Macroblock threshold below which the user specified macroblock types will be used. + * - encoding: Set by user. + * - decoding: unused + */ + int mb_threshold; + + /** + * precision of the intra DC coefficient - 8 + * - encoding: Set by user. + * - decoding: unused + */ + int intra_dc_precision; + + /** + * noise vs. sse weight for the nsse comparsion function + * - encoding: Set by user. + * - decoding: unused + */ + int nsse_weight; + + /** + * Number of macroblock rows at the top which are skipped. + * - encoding: unused + * - decoding: Set by user. + */ + int skip_top; + + /** + * Number of macroblock rows at the bottom which are skipped. + * - encoding: unused + * - decoding: Set by user. + */ + int skip_bottom; + + /** + * profile + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int profile; +#define FF_PROFILE_UNKNOWN -99 + +#define FF_PROFILE_AAC_MAIN 0 +#define FF_PROFILE_AAC_LOW 1 +#define FF_PROFILE_AAC_SSR 2 +#define FF_PROFILE_AAC_LTP 3 + +#define FF_PROFILE_H264_BASELINE 66 +#define FF_PROFILE_H264_MAIN 77 +#define FF_PROFILE_H264_EXTENDED 88 +#define FF_PROFILE_H264_HIGH 100 +#define FF_PROFILE_H264_HIGH_10 110 +#define FF_PROFILE_H264_HIGH_422 122 +#define FF_PROFILE_H264_HIGH_444 244 +#define FF_PROFILE_H264_CAVLC_444 44 + + /** + * level + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int level; +#define FF_LEVEL_UNKNOWN -99 + + /** + * low resolution decoding, 1-> 1/2 size, 2->1/4 size + * - encoding: unused + * - decoding: Set by user. + */ + int lowres; + + /** + * Bitstream width / height, may be different from width/height if lowres + * or other things are used. + * - encoding: unused + * - decoding: Set by user before init if known. Codec should override / dynamically change if needed. + */ + int coded_width, coded_height; + + /** + * frame skip threshold + * - encoding: Set by user. + * - decoding: unused + */ + int frame_skip_threshold; + + /** + * frame skip factor + * - encoding: Set by user. + * - decoding: unused + */ + int frame_skip_factor; + + /** + * frame skip exponent + * - encoding: Set by user. + * - decoding: unused + */ + int frame_skip_exp; + + /** + * frame skip comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int frame_skip_cmp; + + /** + * Border processing masking, raises the quantizer for mbs on the borders + * of the picture. + * - encoding: Set by user. + * - decoding: unused + */ + float border_masking; + + /** + * minimum MB lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ + int mb_lmin; + + /** + * maximum MB lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ + int mb_lmax; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ + int me_penalty_compensation; + + /** + * + * - encoding: unused + * - decoding: Set by user. + */ + enum AVDiscard skip_loop_filter; + + /** + * + * - encoding: unused + * - decoding: Set by user. + */ + enum AVDiscard skip_idct; + + /** + * + * - encoding: unused + * - decoding: Set by user. + */ + enum AVDiscard skip_frame; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ + int bidir_refine; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ + int brd_scale; + + /** + * constant rate factor - quality-based VBR - values ~correspond to qps + * - encoding: Set by user. + * - decoding: unused + */ + float crf; + + /** + * constant quantization parameter rate control method + * - encoding: Set by user. + * - decoding: unused + */ + int cqp; + + /** + * minimum GOP size + * - encoding: Set by user. + * - decoding: unused + */ + int keyint_min; + + /** + * number of reference frames + * - encoding: Set by user. + * - decoding: Set by lavc. + */ + int refs; + + /** + * chroma qp offset from luma + * - encoding: Set by user. + * - decoding: unused + */ + int chromaoffset; + + /** + * Influences how often B-frames are used. + * - encoding: Set by user. + * - decoding: unused + */ + int bframebias; + + /** + * trellis RD quantization + * - encoding: Set by user. + * - decoding: unused + */ + int trellis; + + /** + * Reduce fluctuations in qp (before curve compression). + * - encoding: Set by user. + * - decoding: unused + */ + float complexityblur; + + /** + * in-loop deblocking filter alphac0 parameter + * alpha is in the range -6...6 + * - encoding: Set by user. + * - decoding: unused + */ + int deblockalpha; + + /** + * in-loop deblocking filter beta parameter + * beta is in the range -6...6 + * - encoding: Set by user. + * - decoding: unused + */ + int deblockbeta; + + /** + * macroblock subpartition sizes to consider - p8x8, p4x4, b8x8, i8x8, i4x4 + * - encoding: Set by user. + * - decoding: unused + */ + int partitions; +#define X264_PART_I4X4 0x001 /* Analyze i4x4 */ +#define X264_PART_I8X8 0x002 /* Analyze i8x8 (requires 8x8 transform) */ +#define X264_PART_P8X8 0x010 /* Analyze p16x8, p8x16 and p8x8 */ +#define X264_PART_P4X4 0x020 /* Analyze p8x4, p4x8, p4x4 */ +#define X264_PART_B8X8 0x100 /* Analyze b16x8, b8x16 and b8x8 */ + + /** + * direct MV prediction mode - 0 (none), 1 (spatial), 2 (temporal), 3 (auto) + * - encoding: Set by user. + * - decoding: unused + */ + int directpred; + + /** + * Audio cutoff bandwidth (0 means "automatic") + * - encoding: Set by user. + * - decoding: unused + */ + int cutoff; + + /** + * Multiplied by qscale for each frame and added to scene_change_score. + * - encoding: Set by user. + * - decoding: unused + */ + int scenechange_factor; + + /** + * + * Note: Value depends upon the compare function used for fullpel ME. + * - encoding: Set by user. + * - decoding: unused + */ + int mv0_threshold; + + /** + * Adjusts sensitivity of b_frame_strategy 1. + * - encoding: Set by user. + * - decoding: unused + */ + int b_sensitivity; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int compression_level; +#define FF_COMPRESSION_DEFAULT -1 + + /** + * Sets whether to use LPC mode - used by FLAC encoder. + * - encoding: Set by user. + * - decoding: unused + */ + int use_lpc; + + /** + * LPC coefficient precision - used by FLAC encoder + * - encoding: Set by user. + * - decoding: unused + */ + int lpc_coeff_precision; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int min_prediction_order; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int max_prediction_order; + + /** + * search method for selecting prediction order + * - encoding: Set by user. + * - decoding: unused + */ + int prediction_order_method; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int min_partition_order; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int max_partition_order; + + /** + * GOP timecode frame start number, in non drop frame format + * - encoding: Set by user. + * - decoding: unused + */ + int64_t timecode_frame_start; + +#if LIBAVCODEC_VERSION_MAJOR < 53 + /** + * Decoder should decode to this many channels if it can (0 for default) + * - encoding: unused + * - decoding: Set by user. + * @deprecated Deprecated in favor of request_channel_layout. + */ + int request_channels; +#endif + + /** + * Percentage of dynamic range compression to be applied by the decoder. + * The default value is 1.0, corresponding to full compression. + * - encoding: unused + * - decoding: Set by user. + */ + float drc_scale; + + /** + * opaque 64bit number (generally a PTS) that will be reordered and + * output in AVFrame.reordered_opaque + * - encoding: unused + * - decoding: Set by user. + */ + int64_t reordered_opaque; + + /** + * Bits per sample/pixel of internal libavcodec pixel/sample format. + * This field is applicable only when sample_fmt is SAMPLE_FMT_S32. + * - encoding: set by user. + * - decoding: set by libavcodec. + */ + int bits_per_raw_sample; + + /** + * Audio channel layout. + * - encoding: set by user. + * - decoding: set by libavcodec. + */ + int64_t channel_layout; + + /** + * Request decoder to use this channel layout if it can (0 for default) + * - encoding: unused + * - decoding: Set by user. + */ + int64_t request_channel_layout; + + /** + * Ratecontrol attempt to use, at maximum, of what can be used without an underflow. + * - encoding: Set by user. + * - decoding: unused. + */ + float rc_max_available_vbv_use; + + /** + * Ratecontrol attempt to use, at least, times the amount needed to prevent a vbv overflow. + * - encoding: Set by user. + * - decoding: unused. + */ + float rc_min_vbv_overflow_use; + + /** + * Hardware accelerator in use + * - encoding: unused. + * - decoding: Set by libavcodec + */ + struct AVHWAccel *hwaccel; + + /** + * For some codecs, the time base is closer to the field rate than the frame rate. + * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration + * if no telecine is used ... + * + * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2. + */ + int ticks_per_frame; + + /** + * Hardware accelerator context. + * For some hardware accelerators, a global context needs to be + * provided by the user. In that case, this holds display-dependent + * data FFmpeg cannot instantiate itself. Please refer to the + * FFmpeg HW accelerator documentation to know how to fill this + * is. e.g. for VA API, this is a struct vaapi_context. + * - encoding: unused + * - decoding: Set by user + */ + void *hwaccel_context; + + /** + * Chromaticity coordinates of the source primaries. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorPrimaries color_primaries; + + /** + * Color Transfer Characteristic. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorTransferCharacteristic color_trc; + + /** + * YUV colorspace type. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorSpace colorspace; + + /** + * MPEG vs JPEG YUV range. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorRange color_range; + + /** + * This defines the location of chroma samples. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVChromaLocation chroma_sample_location; + + /** + * The codec may call this to execute several independent things. + * It will return only after finishing all tasks. + * The user may replace this with some multithreaded implementation, + * the default implementation will execute the parts serially. + * Also see avcodec_thread_init and e.g. the --enable-pthread configure option. + * @param c context passed also to func + * @param count the number of things to execute + * @param arg2 argument passed unchanged to func + * @param ret return values of executed functions, must have space for "count" values. May be NULL. + * @param func function that will be called count times, with jobnr from 0 to count-1. + * threadnr will be in the range 0 to c->thread_count-1 < MAX_THREADS and so that no + * two instances of func executing at the same time will have the same threadnr. + * @return always 0 currently, but code should handle a future improvement where when any call to func + * returns < 0 no further calls to func may be done and < 0 is returned. + * - encoding: Set by libavcodec, user can override. + * - decoding: Set by libavcodec, user can override. + */ + int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count); + + /** + * explicit P-frame weighted prediction analysis method + * 0: off + * 1: fast blind weighting (one reference duplicate with -1 offset) + * 2: smart weighting (full fade detection analysis) + * - encoding: Set by user. + * - decoding: unused + */ + int weighted_p_pred; + + /** + * AQ mode + * 0: Disabled + * 1: Variance AQ (complexity mask) + * 2: Auto-variance AQ (experimental) + * - encoding: Set by user + * - decoding: unused + */ + int aq_mode; + + /** + * AQ strength + * Reduces blocking and blurring in flat and textured areas. + * - encoding: Set by user + * - decoding: unused + */ + float aq_strength; + + /** + * PSY RD + * Strength of psychovisual optimization + * - encoding: Set by user + * - decoding: unused + */ + float psy_rd; + + /** + * PSY trellis + * Strength of psychovisual optimization + * - encoding: Set by user + * - decoding: unused + */ + float psy_trellis; + + /** + * RC lookahead + * Number of frames for frametype and ratecontrol lookahead + * - encoding: Set by user + * - decoding: unused + */ + int rc_lookahead; +} AVCodecContext; + +/** + * AVCodec. + */ +typedef struct AVCodec { + /** + * Name of the codec implementation. + * The name is globally unique among encoders and among decoders (but an + * encoder and a decoder can share the same name). + * This is the primary way to find a codec from the user perspective. + */ + const char *name; + enum AVMediaType type; + enum CodecID id; + int priv_data_size; + int (*init)(AVCodecContext *); + int (*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data); + int (*close)(AVCodecContext *); + int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt); + /** + * Codec capabilities. + * see CODEC_CAP_* + */ + int capabilities; + struct AVCodec *next; + /** + * Flush buffers. + * Will be called when seeking + */ + void (*flush)(AVCodecContext *); + const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0} + const enum PixelFormat *pix_fmts; ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1 + /** + * Descriptive name for the codec, meant to be more human readable than name. + * You should use the NULL_IF_CONFIG_SMALL() macro to define it. + */ + const char *long_name; + const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0 + const enum SampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1 + const int64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0 +} AVCodec; + +/** + * AVHWAccel. + */ +typedef struct AVHWAccel { + /** + * Name of the hardware accelerated codec. + * The name is globally unique among encoders and among decoders (but an + * encoder and a decoder can share the same name). + */ + const char *name; + + /** + * Type of codec implemented by the hardware accelerator. + * + * See AVMEDIA_TYPE_xxx + */ + enum AVMediaType type; + + /** + * Codec implemented by the hardware accelerator. + * + * See CODEC_ID_xxx + */ + enum CodecID id; + + /** + * Supported pixel format. + * + * Only hardware accelerated formats are supported here. + */ + enum PixelFormat pix_fmt; + + /** + * Hardware accelerated codec capabilities. + * see FF_HWACCEL_CODEC_CAP_* + */ + int capabilities; + + struct AVHWAccel *next; + + /** + * Called at the beginning of each frame or field picture. + * + * Meaningful frame information (codec specific) is guaranteed to + * be parsed at this point. This function is mandatory. + * + * Note that buf can be NULL along with buf_size set to 0. + * Otherwise, this means the whole frame is available at this point. + * + * @param avctx the codec context + * @param buf the frame data buffer base + * @param buf_size the size of the frame in bytes + * @return zero if successful, a negative value otherwise + */ + int (*start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); + + /** + * Callback for each slice. + * + * Meaningful slice information (codec specific) is guaranteed to + * be parsed at this point. This function is mandatory. + * + * @param avctx the codec context + * @param buf the slice data buffer base + * @param buf_size the size of the slice in bytes + * @return zero if successful, a negative value otherwise + */ + int (*decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); + + /** + * Called at the end of each frame or field picture. + * + * The whole picture is parsed at this point and can now be sent + * to the hardware accelerator. This function is mandatory. + * + * @param avctx the codec context + * @return zero if successful, a negative value otherwise + */ + int (*end_frame)(AVCodecContext *avctx); + + /** + * Size of HW accelerator private data. + * + * Private data is allocated with av_mallocz() before + * AVCodecContext.get_buffer() and deallocated after + * AVCodecContext.release_buffer(). + */ + int priv_data_size; +} AVHWAccel; + +/** + * four components are given, that's all. + * the last component is alpha + */ +typedef struct AVPicture { + uint8_t *data[4]; + int linesize[4]; ///< number of bytes per line +} AVPicture; + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * AVPaletteControl + * This structure defines a method for communicating palette changes + * between and demuxer and a decoder. + * + * @deprecated Use AVPacket to send palette changes instead. + * This is totally broken. + */ +#define AVPALETTE_SIZE 1024 +#define AVPALETTE_COUNT 256 +typedef struct AVPaletteControl { + + /* Demuxer sets this to 1 to indicate the palette has changed; + * decoder resets to 0. */ + int palette_changed; + + /* 4-byte ARGB palette entries, stored in native byte order; note that + * the individual palette components should be on a 8-bit scale; if + * the palette data comes from an IBM VGA native format, the component + * data is probably 6 bits in size and needs to be scaled. */ + unsigned int palette[AVPALETTE_COUNT]; + +} AVPaletteControl attribute_deprecated; +#endif + +enum AVSubtitleType { + SUBTITLE_NONE, + + SUBTITLE_BITMAP, ///< A bitmap, pict will be set + + /** + * Plain text, the text field must be set by the decoder and is + * authoritative. ass and pict fields may contain approximations. + */ + SUBTITLE_TEXT, + + /** + * Formatted text, the ass field must be set by the decoder and is + * authoritative. pict and text fields may contain approximations. + */ + SUBTITLE_ASS, +}; + +typedef struct AVSubtitleRect { + int x; ///< top left corner of pict, undefined when pict is not set + int y; ///< top left corner of pict, undefined when pict is not set + int w; ///< width of pict, undefined when pict is not set + int h; ///< height of pict, undefined when pict is not set + int nb_colors; ///< number of colors in pict, undefined when pict is not set + + /** + * data+linesize for the bitmap of this subtitle. + * can be set for text/ass as well once they where rendered + */ + AVPicture pict; + enum AVSubtitleType type; + + char *text; ///< 0 terminated plain UTF-8 text + + /** + * 0 terminated ASS/SSA compatible event line. + * The pressentation of this is unaffected by the other values in this + * struct. + */ + char *ass; +} AVSubtitleRect; + +typedef struct AVSubtitle { + uint16_t format; /* 0 = graphics */ + uint32_t start_display_time; /* relative to packet pts, in ms */ + uint32_t end_display_time; /* relative to packet pts, in ms */ + unsigned num_rects; + AVSubtitleRect **rects; + int64_t pts; ///< Same as packet pts, in AV_TIME_BASE +} AVSubtitle; + +/* packet functions */ + +/** + * @deprecated use NULL instead + */ +attribute_deprecated void av_destruct_packet_nofree(AVPacket *pkt); + +/** + * Default packet destructor. + */ +void av_destruct_packet(AVPacket *pkt); + +/** + * Initialize optional fields of a packet with default values. + * + * @param pkt packet + */ +void av_init_packet(AVPacket *pkt); + +/** + * Allocate the payload of a packet and initialize its fields with + * default values. + * + * @param pkt packet + * @param size wanted payload size + * @return 0 if OK, AVERROR_xxx otherwise + */ +int av_new_packet(AVPacket *pkt, int size); + +/** + * Reduce packet size, correctly zeroing padding + * + * @param pkt packet + * @param size new size + */ +void av_shrink_packet(AVPacket *pkt, int size); + +/** + * @warning This is a hack - the packet memory allocation stuff is broken. The + * packet is allocated if it was not really allocated. + */ +int av_dup_packet(AVPacket *pkt); + +/** + * Free a packet. + * + * @param pkt packet to free + */ +void av_free_packet(AVPacket *pkt); + +/* resample.c */ + +struct ReSampleContext; +struct AVResampleContext; + +typedef struct ReSampleContext ReSampleContext; + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * @deprecated Use av_audio_resample_init() instead. + */ +attribute_deprecated ReSampleContext *audio_resample_init(int output_channels, int input_channels, + int output_rate, int input_rate); +#endif +/** + * Initializes audio resampling context + * + * @param output_channels number of output channels + * @param input_channels number of input channels + * @param output_rate output sample rate + * @param input_rate input sample rate + * @param sample_fmt_out requested output sample format + * @param sample_fmt_in input sample format + * @param filter_length length of each FIR filter in the filterbank relative to the cutoff freq + * @param log2_phase_count log2 of the number of entries in the polyphase filterbank + * @param linear If 1 then the used FIR filter will be linearly interpolated + between the 2 closest, if 0 the closest will be used + * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate + * @return allocated ReSampleContext, NULL if error occured + */ +ReSampleContext *av_audio_resample_init(int output_channels, int input_channels, + int output_rate, int input_rate, + enum SampleFormat sample_fmt_out, + enum SampleFormat sample_fmt_in, + int filter_length, int log2_phase_count, + int linear, double cutoff); + +int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples); +void audio_resample_close(ReSampleContext *s); + + +/** + * Initializes an audio resampler. + * Note, if either rate is not an integer then simply scale both rates up so they are. + * @param filter_length length of each FIR filter in the filterbank relative to the cutoff freq + * @param log2_phase_count log2 of the number of entries in the polyphase filterbank + * @param linear If 1 then the used FIR filter will be linearly interpolated + between the 2 closest, if 0 the closest will be used + * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate + */ +struct AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_length, int log2_phase_count, int linear, double cutoff); + +/** + * resamples. + * @param src an array of unconsumed samples + * @param consumed the number of samples of src which have been consumed are returned here + * @param src_size the number of unconsumed samples available + * @param dst_size the amount of space in samples available in dst + * @param update_ctx If this is 0 then the context will not be modified, that way several channels can be resampled with the same context. + * @return the number of samples written in dst or -1 if an error occurred + */ +int av_resample(struct AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx); + + +/** + * Compensates samplerate/timestamp drift. The compensation is done by changing + * the resampler parameters, so no audible clicks or similar distortions occur + * @param compensation_distance distance in output samples over which the compensation should be performed + * @param sample_delta number of output samples which should be output less + * + * example: av_resample_compensate(c, 10, 500) + * here instead of 510 samples only 500 samples would be output + * + * note, due to rounding the actual compensation might be slightly different, + * especially if the compensation_distance is large and the in_rate used during init is small + */ +void av_resample_compensate(struct AVResampleContext *c, int sample_delta, int compensation_distance); +void av_resample_close(struct AVResampleContext *c); + +/** + * Allocate memory for a picture. Call avpicture_free to free it. + * + * @param picture the picture to be filled in + * @param pix_fmt the format of the picture + * @param width the width of the picture + * @param height the height of the picture + * @return zero if successful, a negative value if not + */ +int avpicture_alloc(AVPicture *picture, enum PixelFormat pix_fmt, int width, int height); + +/** + * Free a picture previously allocated by avpicture_alloc(). + * + * @param picture the AVPicture to be freed + */ +void avpicture_free(AVPicture *picture); + +/** + * Fill in the AVPicture fields. + * The fields of the given AVPicture are filled in by using the 'ptr' address + * which points to the image data buffer. Depending on the specified picture + * format, one or multiple image data pointers and line sizes will be set. + * If a planar format is specified, several pointers will be set pointing to + * the different picture planes and the line sizes of the different planes + * will be stored in the lines_sizes array. + * Call with ptr == NULL to get the required size for the ptr buffer. + * + * @param picture AVPicture whose fields are to be filled in + * @param ptr Buffer which will contain or contains the actual image data + * @param pix_fmt The format in which the picture data is stored. + * @param width the width of the image in pixels + * @param height the height of the image in pixels + * @return size of the image data in bytes + */ +int avpicture_fill(AVPicture *picture, uint8_t *ptr, + enum PixelFormat pix_fmt, int width, int height); +int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height, + unsigned char *dest, int dest_size); + +/** + * Calculate the size in bytes that a picture of the given width and height + * would occupy if stored in the given picture format. + * Note that this returns the size of a compact representation as generated + * by avpicture_layout, which can be smaller than the size required for e.g. + * avpicture_fill. + * + * @param pix_fmt the given picture format + * @param width the width of the image + * @param height the height of the image + * @return Image data size in bytes or -1 on error (e.g. too large dimensions). + */ +int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height); +void avcodec_get_chroma_sub_sample(enum PixelFormat pix_fmt, int *h_shift, int *v_shift); +const char *avcodec_get_pix_fmt_name(enum PixelFormat pix_fmt); +void avcodec_set_dimensions(AVCodecContext *s, int width, int height); + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * Returns the pixel format corresponding to the name name. + * + * If there is no pixel format with name name, then looks for a + * pixel format with the name corresponding to the native endian + * format of name. + * For example in a little-endian system, first looks for "gray16", + * then for "gray16le". + * + * Finally if no pixel format has been found, returns PIX_FMT_NONE. + * + * @deprecated Deprecated in favor of av_get_pix_fmt(). + */ +attribute_deprecated enum PixelFormat avcodec_get_pix_fmt(const char* name); +#endif + +/** + * Returns a value representing the fourCC code associated to the + * pixel format pix_fmt, or 0 if no associated fourCC code can be + * found. + */ +unsigned int avcodec_pix_fmt_to_codec_tag(enum PixelFormat pix_fmt); + +#define FF_LOSS_RESOLUTION 0x0001 /**< loss due to resolution change */ +#define FF_LOSS_DEPTH 0x0002 /**< loss due to color depth change */ +#define FF_LOSS_COLORSPACE 0x0004 /**< loss due to color space conversion */ +#define FF_LOSS_ALPHA 0x0008 /**< loss of alpha bits */ +#define FF_LOSS_COLORQUANT 0x0010 /**< loss due to color quantization */ +#define FF_LOSS_CHROMA 0x0020 /**< loss of chroma (e.g. RGB to gray conversion) */ + +/** + * Computes what kind of losses will occur when converting from one specific + * pixel format to another. + * When converting from one pixel format to another, information loss may occur. + * For example, when converting from RGB24 to GRAY, the color information will + * be lost. Similarly, other losses occur when converting from some formats to + * other formats. These losses can involve loss of chroma, but also loss of + * resolution, loss of color depth, loss due to the color space conversion, loss + * of the alpha bits or loss due to color quantization. + * avcodec_get_fix_fmt_loss() informs you about the various types of losses + * which will occur when converting from one pixel format to another. + * + * @param[in] dst_pix_fmt destination pixel format + * @param[in] src_pix_fmt source pixel format + * @param[in] has_alpha Whether the source pixel format alpha channel is used. + * @return Combination of flags informing you what kind of losses will occur. + */ +int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt, + int has_alpha); + +/** + * Finds the best pixel format to convert to given a certain source pixel + * format. When converting from one pixel format to another, information loss + * may occur. For example, when converting from RGB24 to GRAY, the color + * information will be lost. Similarly, other losses occur when converting from + * some formats to other formats. avcodec_find_best_pix_fmt() searches which of + * the given pixel formats should be used to suffer the least amount of loss. + * The pixel formats from which it chooses one, are determined by the + * pix_fmt_mask parameter. + * + * @code + * src_pix_fmt = PIX_FMT_YUV420P; + * pix_fmt_mask = (1 << PIX_FMT_YUV422P) || (1 << PIX_FMT_RGB24); + * dst_pix_fmt = avcodec_find_best_pix_fmt(pix_fmt_mask, src_pix_fmt, alpha, &loss); + * @endcode + * + * @param[in] pix_fmt_mask bitmask determining which pixel format to choose from + * @param[in] src_pix_fmt source pixel format + * @param[in] has_alpha Whether the source pixel format alpha channel is used. + * @param[out] loss_ptr Combination of flags informing you what kind of losses will occur. + * @return The best pixel format to convert to or -1 if none was found. + */ +enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt, + int has_alpha, int *loss_ptr); + + +/** + * Print in buf the string corresponding to the pixel format with + * number pix_fmt, or an header if pix_fmt is negative. + * + * @param[in] buf the buffer where to write the string + * @param[in] buf_size the size of buf + * @param[in] pix_fmt the number of the pixel format to print the corresponding info string, or + * a negative value to print the corresponding header. + * Meaningful values for obtaining a pixel format info vary from 0 to PIX_FMT_NB -1. + */ +void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt); + +#define FF_ALPHA_TRANSP 0x0001 /* image has some totally transparent pixels */ +#define FF_ALPHA_SEMI_TRANSP 0x0002 /* image has some transparent pixels */ + +/** + * Tell if an image really has transparent alpha values. + * @return ored mask of FF_ALPHA_xxx constants + */ +int img_get_alpha_info(const AVPicture *src, + enum PixelFormat pix_fmt, int width, int height); + +/* deinterlace a picture */ +/* deinterlace - if not supported return -1 */ +int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, + enum PixelFormat pix_fmt, int width, int height); + +/* external high level API */ + +/** + * If c is NULL, returns the first registered codec, + * if c is non-NULL, returns the next registered codec after c, + * or NULL if c is the last one. + */ +AVCodec *av_codec_next(AVCodec *c); + +/** + * Returns the LIBAVCODEC_VERSION_INT constant. + */ +unsigned avcodec_version(void); + +/** + * Returns the libavcodec build-time configuration. + */ +const char *avcodec_configuration(void); + +/** + * Returns the libavcodec license. + */ +const char *avcodec_license(void); + +/** + * Initializes libavcodec. + * + * @warning This function must be called before any other libavcodec + * function. + */ +void avcodec_init(void); + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * @deprecated Deprecated in favor of avcodec_register(). + */ +attribute_deprecated void register_avcodec(AVCodec *codec); +#endif + +/** + * Register the codec codec and initialize libavcodec. + * + * @see avcodec_init() + */ +void avcodec_register(AVCodec *codec); + +/** + * Finds a registered encoder with a matching codec ID. + * + * @param id CodecID of the requested encoder + * @return An encoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_encoder(enum CodecID id); + +/** + * Finds a registered encoder with the specified name. + * + * @param name name of the requested encoder + * @return An encoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_encoder_by_name(const char *name); + +/** + * Finds a registered decoder with a matching codec ID. + * + * @param id CodecID of the requested decoder + * @return A decoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_decoder(enum CodecID id); + +/** + * Finds a registered decoder with the specified name. + * + * @param name name of the requested decoder + * @return A decoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_decoder_by_name(const char *name); +void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); + +/** + * Sets the fields of the given AVCodecContext to default values. + * + * @param s The AVCodecContext of which the fields should be set to default values. + */ +void avcodec_get_context_defaults(AVCodecContext *s); + +/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! + * we WILL change its arguments and name a few times! */ +void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType); + +/** + * Allocates an AVCodecContext and sets its fields to default values. The + * resulting struct can be deallocated by simply calling av_free(). + * + * @return An AVCodecContext filled with default values or NULL on failure. + * @see avcodec_get_context_defaults + */ +AVCodecContext *avcodec_alloc_context(void); + +/** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! + * we WILL change its arguments and name a few times! */ +AVCodecContext *avcodec_alloc_context2(enum AVMediaType); + +/** + * Copy the settings of the source AVCodecContext into the destination + * AVCodecContext. The resulting destination codec context will be + * unopened, i.e. you are required to call avcodec_open() before you + * can use this AVCodecContext to decode/encode video/audio data. + * + * @param dest target codec context, should be initialized with + * avcodec_alloc_context(), but otherwise uninitialized + * @param src source codec context + * @return AVERROR() on error (e.g. memory allocation error), 0 on success + */ +int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src); + +/** + * Sets the fields of the given AVFrame to default values. + * + * @param pic The AVFrame of which the fields should be set to default values. + */ +void avcodec_get_frame_defaults(AVFrame *pic); + +/** + * Allocates an AVFrame and sets its fields to default values. The resulting + * struct can be deallocated by simply calling av_free(). + * + * @return An AVFrame filled with default values or NULL on failure. + * @see avcodec_get_frame_defaults + */ +AVFrame *avcodec_alloc_frame(void); + +int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic); +void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic); +int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic); + +/** + * Returns the amount of padding in pixels which the get_buffer callback must + * provide around the edge of the image for codecs which do not have the + * CODEC_FLAG_EMU_EDGE flag. + * + * @return Required padding in pixels. + */ +unsigned avcodec_get_edge_width(void); +/** + * Modifies width and height values so that they will result in a memory + * buffer that is acceptable for the codec if you do not use any horizontal + * padding. + */ +void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height); +/** + * Modifies width and height values so that they will result in a memory + * buffer that is acceptable for the codec if you also ensure that all + * line sizes are a multiple of the respective linesize_align[i]. + */ +void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, + int linesize_align[4]); + +/** + * Checks if the given dimension of a picture is valid, meaning that all + * bytes of the picture can be addressed with a signed int. + * + * @param[in] w Width of the picture. + * @param[in] h Height of the picture. + * @return Zero if valid, a negative value if invalid. + */ +int avcodec_check_dimensions(void *av_log_ctx, unsigned int w, unsigned int h); +enum PixelFormat avcodec_default_get_format(struct AVCodecContext *s, const enum PixelFormat * fmt); + +int avcodec_thread_init(AVCodecContext *s, int thread_count); +void avcodec_thread_free(AVCodecContext *s); +int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size); +int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count); +//FIXME func typedef + +/** + * Initializes the AVCodecContext to use the given AVCodec. Prior to using this + * function the context has to be allocated. + * + * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), + * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for + * retrieving a codec. + * + * @warning This function is not thread safe! + * + * @code + * avcodec_register_all(); + * codec = avcodec_find_decoder(CODEC_ID_H264); + * if (!codec) + * exit(1); + * + * context = avcodec_alloc_context(); + * + * if (avcodec_open(context, codec) < 0) + * exit(1); + * @endcode + * + * @param avctx The context which will be set up to use the given codec. + * @param codec The codec to use within the context. + * @return zero on success, a negative value on error + * @see avcodec_alloc_context, avcodec_find_decoder, avcodec_find_encoder + */ +int avcodec_open(AVCodecContext *avctx, AVCodec *codec); + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * Decodes an audio frame from buf into samples. + * Wrapper function which calls avcodec_decode_audio3. + * + * @deprecated Use avcodec_decode_audio3 instead. + * @param avctx the codec context + * @param[out] samples the output buffer + * @param[in,out] frame_size_ptr the output buffer size in bytes + * @param[in] buf the input buffer + * @param[in] buf_size the input buffer size in bytes + * @return On error a negative value is returned, otherwise the number of bytes + * used or zero if no frame could be decompressed. + */ +attribute_deprecated int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples, + int *frame_size_ptr, + const uint8_t *buf, int buf_size); +#endif + +/** + * Decodes the audio frame of size avpkt->size from avpkt->data into samples. + * Some decoders may support multiple frames in a single AVPacket, such + * decoders would then just decode the first frame. In this case, + * avcodec_decode_audio3 has to be called again with an AVPacket that contains + * the remaining data in order to decode the second frame etc. + * If no frame + * could be outputted, frame_size_ptr is zero. Otherwise, it is the + * decompressed frame size in bytes. + * + * @warning You must set frame_size_ptr to the allocated size of the + * output buffer before calling avcodec_decode_audio3(). + * + * @warning The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE larger than + * the actual read bytes because some optimized bitstream readers read 32 or 64 + * bits at once and could read over the end. + * + * @warning The end of the input buffer avpkt->data should be set to 0 to ensure that + * no overreading happens for damaged MPEG streams. + * + * @note You might have to align the input buffer avpkt->data and output buffer + * samples. The alignment requirements depend on the CPU: On some CPUs it isn't + * necessary at all, on others it won't work at all if not aligned and on others + * it will work but it will have an impact on performance. + * + * In practice, avpkt->data should have 4 byte alignment at minimum and + * samples should be 16 byte aligned unless the CPU doesn't need it + * (AltiVec and SSE do). + * + * @param avctx the codec context + * @param[out] samples the output buffer, sample type in avctx->sample_fmt + * @param[in,out] frame_size_ptr the output buffer size in bytes + * @param[in] avpkt The input AVPacket containing the input buffer. + * You can create such packet with av_init_packet() and by then setting + * data and size, some decoders might in addition need other fields. + * All decoders are designed to use the least fields possible though. + * @return On error a negative value is returned, otherwise the number of bytes + * used or zero if no frame data was decompressed (used) from the input AVPacket. + */ +int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples, + int *frame_size_ptr, + AVPacket *avpkt); + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * Decodes a video frame from buf into picture. + * Wrapper function which calls avcodec_decode_video2. + * + * @deprecated Use avcodec_decode_video2 instead. + * @param avctx the codec context + * @param[out] picture The AVFrame in which the decoded video frame will be stored. + * @param[in] buf the input buffer + * @param[in] buf_size the size of the input buffer in bytes + * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero. + * @return On error a negative value is returned, otherwise the number of bytes + * used or zero if no frame could be decompressed. + */ +attribute_deprecated int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, + const uint8_t *buf, int buf_size); +#endif + +/** + * Decodes the video frame of size avpkt->size from avpkt->data into picture. + * Some decoders may support multiple frames in a single AVPacket, such + * decoders would then just decode the first frame. + * + * @warning The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE larger than + * the actual read bytes because some optimized bitstream readers read 32 or 64 + * bits at once and could read over the end. + * + * @warning The end of the input buffer buf should be set to 0 to ensure that + * no overreading happens for damaged MPEG streams. + * + * @note You might have to align the input buffer avpkt->data. + * The alignment requirements depend on the CPU: on some CPUs it isn't + * necessary at all, on others it won't work at all if not aligned and on others + * it will work but it will have an impact on performance. + * + * In practice, avpkt->data should have 4 byte alignment at minimum. + * + * @note Some codecs have a delay between input and output, these need to be + * fed with avpkt->data=NULL, avpkt->size=0 at the end to return the remaining frames. + * + * @param avctx the codec context + * @param[out] picture The AVFrame in which the decoded video frame will be stored. + * @param[in] avpkt The input AVpacket containing the input buffer. + * You can create such packet with av_init_packet() and by then setting + * data and size, some decoders might in addition need other fields like + * flags&AV_PKT_FLAG_KEY. All decoders are designed to use the least + * fields possible. + * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero. + * @return On error a negative value is returned, otherwise the number of bytes + * used or zero if no frame could be decompressed. + */ +int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, + AVPacket *avpkt); + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/* Decode a subtitle message. Return -1 if error, otherwise return the + * number of bytes used. If no subtitle could be decompressed, + * got_sub_ptr is zero. Otherwise, the subtitle is stored in *sub. */ +attribute_deprecated int avcodec_decode_subtitle(AVCodecContext *avctx, AVSubtitle *sub, + int *got_sub_ptr, + const uint8_t *buf, int buf_size); +#endif + +/** + * Decodes a subtitle message. + * Returns a negative value on error, otherwise returns the number of bytes used. + * If no subtitle could be decompressed, got_sub_ptr is zero. + * Otherwise, the subtitle is stored in *sub. + * + * @param avctx the codec context + * @param[out] sub The AVSubtitle in which the decoded subtitle will be stored. + * @param[in,out] got_sub_ptr Zero if no subtitle could be decompressed, otherwise, it is nonzero. + * @param[in] avpkt The input AVPacket containing the input buffer. + */ +int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, + int *got_sub_ptr, + AVPacket *avpkt); +int avcodec_parse_frame(AVCodecContext *avctx, uint8_t **pdata, + int *data_size_ptr, + uint8_t *buf, int buf_size); + +/** + * Encodes an audio frame from samples into buf. + * + * @note The output buffer should be at least FF_MIN_BUFFER_SIZE bytes large. + * However, for PCM audio the user will know how much space is needed + * because it depends on the value passed in buf_size as described + * below. In that case a lower value can be used. + * + * @param avctx the codec context + * @param[out] buf the output buffer + * @param[in] buf_size the output buffer size + * @param[in] samples the input buffer containing the samples + * The number of samples read from this buffer is frame_size*channels, + * both of which are defined in avctx. + * For PCM audio the number of samples read from samples is equal to + * buf_size * input_sample_size / output_sample_size. + * @return On error a negative value is returned, on success zero or the number + * of bytes used to encode the data read from the input buffer. + */ +int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const short *samples); + +/** + * Encodes a video frame from pict into buf. + * The input picture should be + * stored using a specific format, namely avctx.pix_fmt. + * + * @param avctx the codec context + * @param[out] buf the output buffer for the bitstream of encoded frame + * @param[in] buf_size the size of the output buffer in bytes + * @param[in] pict the input picture to encode + * @return On error a negative value is returned, on success zero or the number + * of bytes used from the output buffer. + */ +int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const AVFrame *pict); +int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const AVSubtitle *sub); + +int avcodec_close(AVCodecContext *avctx); + +/** + * Register all the codecs, parsers and bitstream filters which were enabled at + * configuration time. If you do not call this function you can select exactly + * which formats you want to support, by using the individual registration + * functions. + * + * @see avcodec_register + * @see av_register_codec_parser + * @see av_register_bitstream_filter + */ +void avcodec_register_all(void); + +/** + * Flush buffers, should be called when seeking or when switching to a different stream. + */ +void avcodec_flush_buffers(AVCodecContext *avctx); + +void avcodec_default_free_buffers(AVCodecContext *s); + +/* misc useful functions */ + +/** + * Returns a single letter to describe the given picture type pict_type. + * + * @param[in] pict_type the picture type + * @return A single character representing the picture type. + */ +char av_get_pict_type_char(int pict_type); + +/** + * Returns codec bits per sample. + * + * @param[in] codec_id the codec + * @return Number of bits per sample or zero if unknown for the given codec. + */ +int av_get_bits_per_sample(enum CodecID codec_id); + +/** + * Returns sample format bits per sample. + * + * @param[in] sample_fmt the sample format + * @return Number of bits per sample or zero if unknown for the given sample format. + */ +int av_get_bits_per_sample_format(enum SampleFormat sample_fmt); + +/* frame parsing */ +typedef struct AVCodecParserContext { + void *priv_data; + struct AVCodecParser *parser; + int64_t frame_offset; /* offset of the current frame */ + int64_t cur_offset; /* current offset + (incremented by each av_parser_parse()) */ + int64_t next_frame_offset; /* offset of the next frame */ + /* video info */ + int pict_type; /* XXX: Put it back in AVCodecContext. */ + /** + * This field is used for proper frame duration computation in lavf. + * It signals, how much longer the frame duration of the current frame + * is compared to normal frame duration. + * + * frame_duration = (1 + repeat_pict) * time_base + * + * It is used by codecs like H.264 to display telecined material. + */ + int repeat_pict; /* XXX: Put it back in AVCodecContext. */ + int64_t pts; /* pts of the current frame */ + int64_t dts; /* dts of the current frame */ + + /* private data */ + int64_t last_pts; + int64_t last_dts; + int fetch_timestamp; + +#define AV_PARSER_PTS_NB 4 + int cur_frame_start_index; + int64_t cur_frame_offset[AV_PARSER_PTS_NB]; + int64_t cur_frame_pts[AV_PARSER_PTS_NB]; + int64_t cur_frame_dts[AV_PARSER_PTS_NB]; + + int flags; +#define PARSER_FLAG_COMPLETE_FRAMES 0x0001 + + int64_t offset; ///< byte offset from starting packet start + int64_t cur_frame_end[AV_PARSER_PTS_NB]; + + /*! + * Set by parser to 1 for key frames and 0 for non-key frames. + * It is initialized to -1, so if the parser doesn't set this flag, + * old-style fallback using FF_I_TYPE picture type as key frames + * will be used. + */ + int key_frame; + + /** + * Time difference in stream time base units from the pts of this + * packet to the point at which the output from the decoder has converged + * independent from the availability of previous frames. That is, the + * frames are virtually identical no matter if decoding started from + * the very first frame or from this keyframe. + * Is AV_NOPTS_VALUE if unknown. + * This field is not the display duration of the current frame. + * + * The purpose of this field is to allow seeking in streams that have no + * keyframes in the conventional sense. It corresponds to the + * recovery point SEI in H.264 and match_time_delta in NUT. It is also + * essential for some types of subtitle streams to ensure that all + * subtitles are correctly displayed after seeking. + */ + int64_t convergence_duration; + + // Timestamp generation support: + /** + * Synchronization point for start of timestamp generation. + * + * Set to >0 for sync point, 0 for no sync point and <0 for undefined + * (default). + * + * For example, this corresponds to presence of H.264 buffering period + * SEI message. + */ + int dts_sync_point; + + /** + * Offset of the current timestamp against last timestamp sync point in + * units of AVCodecContext.time_base. + * + * Set to INT_MIN when dts_sync_point unused. Otherwise, it must + * contain a valid timestamp offset. + * + * Note that the timestamp of sync point has usually a nonzero + * dts_ref_dts_delta, which refers to the previous sync point. Offset of + * the next frame after timestamp sync point will be usually 1. + * + * For example, this corresponds to H.264 cpb_removal_delay. + */ + int dts_ref_dts_delta; + + /** + * Presentation delay of current frame in units of AVCodecContext.time_base. + * + * Set to INT_MIN when dts_sync_point unused. Otherwise, it must + * contain valid non-negative timestamp delta (presentation time of a frame + * must not lie in the past). + * + * This delay represents the difference between decoding and presentation + * time of the frame. + * + * For example, this corresponds to H.264 dpb_output_delay. + */ + int pts_dts_delta; + + /** + * Position of the packet in file. + * + * Analogous to cur_frame_pts/dts + */ + int64_t cur_frame_pos[AV_PARSER_PTS_NB]; + + /** + * Byte position of currently parsed frame in stream. + */ + int64_t pos; + + /** + * Previous frame byte position. + */ + int64_t last_pos; +} AVCodecParserContext; + +typedef struct AVCodecParser { + int codec_ids[5]; /* several codec IDs are permitted */ + int priv_data_size; + int (*parser_init)(AVCodecParserContext *s); + int (*parser_parse)(AVCodecParserContext *s, + AVCodecContext *avctx, + const uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size); + void (*parser_close)(AVCodecParserContext *s); + int (*split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size); + struct AVCodecParser *next; +} AVCodecParser; + +AVCodecParser *av_parser_next(AVCodecParser *c); + +void av_register_codec_parser(AVCodecParser *parser); +AVCodecParserContext *av_parser_init(int codec_id); + +#if LIBAVCODEC_VERSION_MAJOR < 53 +attribute_deprecated +int av_parser_parse(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, + int64_t pts, int64_t dts); +#endif + +/** + * Parse a packet. + * + * @param s parser context. + * @param avctx codec context. + * @param poutbuf set to pointer to parsed buffer or NULL if not yet finished. + * @param poutbuf_size set to size of parsed buffer or zero if not yet finished. + * @param buf input buffer. + * @param buf_size input length, to signal EOF, this should be 0 (so that the last frame can be output). + * @param pts input presentation timestamp. + * @param dts input decoding timestamp. + * @param pos input byte position in stream. + * @return the number of bytes of the input bitstream used. + * + * Example: + * @code + * while(in_len){ + * len = av_parser_parse2(myparser, AVCodecContext, &data, &size, + * in_data, in_len, + * pts, dts, pos); + * in_data += len; + * in_len -= len; + * + * if(size) + * decode_frame(data, size); + * } + * @endcode + */ +int av_parser_parse2(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, + int64_t pts, int64_t dts, + int64_t pos); + +int av_parser_change(AVCodecParserContext *s, + AVCodecContext *avctx, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe); +void av_parser_close(AVCodecParserContext *s); + + +typedef struct AVBitStreamFilterContext { + void *priv_data; + struct AVBitStreamFilter *filter; + AVCodecParserContext *parser; + struct AVBitStreamFilterContext *next; +} AVBitStreamFilterContext; + + +typedef struct AVBitStreamFilter { + const char *name; + int priv_data_size; + int (*filter)(AVBitStreamFilterContext *bsfc, + AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe); + void (*close)(AVBitStreamFilterContext *bsfc); + struct AVBitStreamFilter *next; +} AVBitStreamFilter; + +void av_register_bitstream_filter(AVBitStreamFilter *bsf); +AVBitStreamFilterContext *av_bitstream_filter_init(const char *name); +int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, + AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe); +void av_bitstream_filter_close(AVBitStreamFilterContext *bsf); + +AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f); + +/* memory */ + +/** + * Reallocates the given block if it is not large enough, otherwise it + * does nothing. + * + * @see av_realloc + */ +void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size); + +/** + * Allocates a buffer, reusing the given one if large enough. + * + * Contrary to av_fast_realloc the current buffer contents might not be + * preserved and on error the old buffer is freed, thus no special + * handling to avoid memleaks is necessary. + * + * @param ptr pointer to pointer to already allocated buffer, overwritten with pointer to new buffer + * @param size size of the buffer *ptr points to + * @param min_size minimum size of *ptr buffer after returning, *ptr will be NULL and + * *size 0 if an error occurred. + */ +void av_fast_malloc(void *ptr, unsigned int *size, unsigned int min_size); + +/** + * Copy image 'src' to 'dst'. + */ +void av_picture_copy(AVPicture *dst, const AVPicture *src, + enum PixelFormat pix_fmt, int width, int height); + +/** + * Crop image top and left side. + */ +int av_picture_crop(AVPicture *dst, const AVPicture *src, + enum PixelFormat pix_fmt, int top_band, int left_band); + +/** + * Pad image. + */ +int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, enum PixelFormat pix_fmt, + int padtop, int padbottom, int padleft, int padright, int *color); + +/** + * Encodes extradata length to a buffer. Used by xiph codecs. + * + * @param s buffer to write to; must be at least (v/255+1) bytes long + * @param v size of extradata in bytes + * @return number of bytes written to the buffer. + */ +unsigned int av_xiphlacing(unsigned char *s, unsigned int v); + +/** + * Parses str and put in width_ptr and height_ptr the detected values. + * + * @return 0 in case of a successful parsing, a negative value otherwise + * @param[in] str the string to parse: it has to be a string in the format + * x or a valid video frame size abbreviation. + * @param[in,out] width_ptr pointer to the variable which will contain the detected + * frame width value + * @param[in,out] height_ptr pointer to the variable which will contain the detected + * frame height value + */ +int av_parse_video_frame_size(int *width_ptr, int *height_ptr, const char *str); + +/** + * Parses str and put in frame_rate the detected values. + * + * @return 0 in case of a successful parsing, a negative value otherwise + * @param[in] str the string to parse: it has to be a string in the format + * /, a float number or a valid video rate abbreviation + * @param[in,out] frame_rate pointer to the AVRational which will contain the detected + * frame rate + */ +int av_parse_video_frame_rate(AVRational *frame_rate, const char *str); + +/** + * Logs a generic warning message about a missing feature. This function is + * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.) + * only, and would normally not be used by applications. + * @param[in] avc a pointer to an arbitrary struct of which the first field is + * a pointer to an AVClass struct + * @param[in] feature string containing the name of the missing feature + * @param[in] want_sample indicates if samples are wanted which exhibit this feature. + * If want_sample is non-zero, additional verbage will be added to the log + * message which tells the user how to report samples to the development + * mailing list. + */ +void av_log_missing_feature(void *avc, const char *feature, int want_sample); + +/** + * Logs a generic warning message asking for a sample. This function is + * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.) + * only, and would normally not be used by applications. + * @param[in] avc a pointer to an arbitrary struct of which the first field is + * a pointer to an AVClass struct + * @param[in] msg string containing an optional message, or NULL if no message + */ +void av_log_ask_for_sample(void *avc, const char *msg); + +/** + * Registers the hardware accelerator hwaccel. + */ +void av_register_hwaccel(AVHWAccel *hwaccel); + +/** + * If hwaccel is NULL, returns the first registered hardware accelerator, + * if hwaccel is non-NULL, returns the next registered hardware accelerator + * after hwaccel, or NULL if hwaccel is the last one. + */ +AVHWAccel *av_hwaccel_next(AVHWAccel *hwaccel); + + +/** + * Lock operation used by lockmgr + */ +enum AVLockOp { + AV_LOCK_CREATE, ///< Create a mutex + AV_LOCK_OBTAIN, ///< Lock the mutex + AV_LOCK_RELEASE, ///< Unlock the mutex + AV_LOCK_DESTROY, ///< Free mutex resources +}; + +/** + * Register a user provided lock manager supporting the operations + * specified by AVLockOp. mutex points to a (void *) where the + * lockmgr should store/get a pointer to a user allocated mutex. It's + * NULL upon AV_LOCK_CREATE and != NULL for all other ops. + * + * @param cb User defined callback. Note: FFmpeg may invoke calls to this + * callback during the call to av_lockmgr_register(). + * Thus, the application must be prepared to handle that. + * If cb is set to NULL the lockmgr will be unregistered. + * Also note that during unregistration the previously registered + * lockmgr callback may also be invoked. + */ +int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op)); + +#endif /* AVCODEC_AVCODEC_H */ diff --git a/extra_lib/include/ffmpeg_android/libavformat/avformat.h b/extra_lib/include/ffmpeg_android/libavformat/avformat.h new file mode 100644 index 0000000..5ff08c0 --- /dev/null +++ b/extra_lib/include/ffmpeg_android/libavformat/avformat.h @@ -0,0 +1,1340 @@ +/* + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg 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.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVFORMAT_AVFORMAT_H +#define AVFORMAT_AVFORMAT_H + +#define LIBAVFORMAT_VERSION_MAJOR 52 +#define LIBAVFORMAT_VERSION_MINOR 61 +#define LIBAVFORMAT_VERSION_MICRO 0 + +#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ + LIBAVFORMAT_VERSION_MINOR, \ + LIBAVFORMAT_VERSION_MICRO) +#define LIBAVFORMAT_VERSION AV_VERSION(LIBAVFORMAT_VERSION_MAJOR, \ + LIBAVFORMAT_VERSION_MINOR, \ + LIBAVFORMAT_VERSION_MICRO) +#define LIBAVFORMAT_BUILD LIBAVFORMAT_VERSION_INT + +#define LIBAVFORMAT_IDENT "Lavf" AV_STRINGIFY(LIBAVFORMAT_VERSION) + +/** + * I return the LIBAVFORMAT_VERSION_INT constant. You got + * a fucking problem with that, douchebag? + */ +unsigned avformat_version(void); + +/** + * Returns the libavformat build-time configuration. + */ +const char *avformat_configuration(void); + +/** + * Returns the libavformat license. + */ +const char *avformat_license(void); + +#include +#include /* FILE */ +#include "libavcodec/avcodec.h" + +#include "avio.h" + +struct AVFormatContext; + + +/* + * Public Metadata API. + * The metadata API allows libavformat to export metadata tags to a client + * application using a sequence of key/value pairs. Like all strings in FFmpeg, + * metadata must be stored as UTF-8 encoded Unicode. Note that metadata + * exported by demuxers isn't checked to be valid UTF-8 in most cases. + * Important concepts to keep in mind: + * 1. Keys are unique; there can never be 2 tags with the same key. This is + * also meant semantically, i.e., a demuxer should not knowingly produce + * several keys that are literally different but semantically identical. + * E.g., key=Author5, key=Author6. In this example, all authors must be + * placed in the same tag. + * 2. Metadata is flat, not hierarchical; there are no subtags. If you + * want to store, e.g., the email address of the child of producer Alice + * and actor Bob, that could have key=alice_and_bobs_childs_email_address. + * 3. Several modifiers can be applied to the tag name. This is done by + * appending a dash character ('-') and the modifier name in the order + * they appear in the list below -- e.g. foo-eng-sort, not foo-sort-eng. + * a) language -- a tag whose value is localized for a particular language + * is appended with the ISO 639-2/B 3-letter language code. + * For example: Author-ger=Michael, Author-eng=Mike + * The original/default language is in the unqualified "Author" tag. + * A demuxer should set a default if it sets any translated tag. + * b) sorting -- a modified version of a tag that should be used for + * sorting will have '-sort' appended. E.g. artist="The Beatles", + * artist-sort="Beatles, The". + * + * 4. Tag names are normally exported exactly as stored in the container to + * allow lossless remuxing to the same format. For container-independent + * handling of metadata, av_metadata_conv() can convert it to ffmpeg generic + * format. Follows a list of generic tag names: + * + * album -- name of the set this work belongs to + * album_artist -- main creator of the set/album, if different from artist. + * e.g. "Various Artists" for compilation albums. + * artist -- main creator of the work + * comment -- any additional description of the file. + * composer -- who composed the work, if different from artist. + * copyright -- name of copyright holder. + * date -- date when the work was created, preferably in ISO 8601. + * disc -- number of a subset, e.g. disc in a multi-disc collection. + * encoder -- name/settings of the software/hardware that produced the file. + * encoded_by -- person/group who created the file. + * filename -- original name of the file. + * genre -- . + * language -- main language in which the work is performed, preferably + * in ISO 639-2 format. + * performer -- artist who performed the work, if different from artist. + * E.g for "Also sprach Zarathustra", artist would be "Richard + * Strauss" and performer "London Philharmonic Orchestra". + * publisher -- name of the label/publisher. + * title -- name of the work. + * track -- number of this work in the set, can be in form current/total. + */ + +#define AV_METADATA_MATCH_CASE 1 +#define AV_METADATA_IGNORE_SUFFIX 2 +#define AV_METADATA_DONT_STRDUP_KEY 4 +#define AV_METADATA_DONT_STRDUP_VAL 8 +#define AV_METADATA_DONT_OVERWRITE 16 ///< Don't overwrite existing tags. + +typedef struct { + char *key; + char *value; +}AVMetadataTag; + +typedef struct AVMetadata AVMetadata; +typedef struct AVMetadataConv AVMetadataConv; + +/** + * Gets a metadata element with matching key. + * @param prev Set to the previous matching element to find the next. + * If set to NULL the first matching element is returned. + * @param flags Allows case as well as suffix-insensitive comparisons. + * @return Found tag or NULL, changing key or value leads to undefined behavior. + */ +AVMetadataTag * +av_metadata_get(AVMetadata *m, const char *key, const AVMetadataTag *prev, int flags); + +#if LIBAVFORMAT_VERSION_MAJOR == 52 +/** + * Sets the given tag in m, overwriting an existing tag. + * @param key tag key to add to m (will be av_strduped) + * @param value tag value to add to m (will be av_strduped) + * @return >= 0 on success otherwise an error code <0 + */ +int av_metadata_set(AVMetadata **pm, const char *key, const char *value); +#endif + +/** + * Sets the given tag in m, overwriting an existing tag. + * @param key tag key to add to m (will be av_strduped depending on flags) + * @param value tag value to add to m (will be av_strduped depending on flags) + * @return >= 0 on success otherwise an error code <0 + */ +int av_metadata_set2(AVMetadata **pm, const char *key, const char *value, int flags); + +/** + * Converts all the metadata sets from ctx according to the source and + * destination conversion tables. If one of the tables is NULL, then + * tags are converted to/from ffmpeg generic tag names. + * @param d_conv destination tags format conversion table + * @param s_conv source tags format conversion table + */ +void av_metadata_conv(struct AVFormatContext *ctx,const AVMetadataConv *d_conv, + const AVMetadataConv *s_conv); + +/** + * Frees all the memory allocated for an AVMetadata struct. + */ +void av_metadata_free(AVMetadata **m); + + +/* packet functions */ + + +/** + * Allocates and reads the payload of a packet and initializes its + * fields with default values. + * + * @param pkt packet + * @param size desired payload size + * @return >0 (read size) if OK, AVERROR_xxx otherwise + */ +int av_get_packet(ByteIOContext *s, AVPacket *pkt, int size); + + +/*************************************************/ +/* fractional numbers for exact pts handling */ + +/** + * The exact value of the fractional number is: 'val + num / den'. + * num is assumed to be 0 <= num < den. + */ +typedef struct AVFrac { + int64_t val, num, den; +} AVFrac; + +/*************************************************/ +/* input/output formats */ + +struct AVCodecTag; + +/** This structure contains the data a format has to probe a file. */ +typedef struct AVProbeData { + const char *filename; + unsigned char *buf; /**< Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero. */ + int buf_size; /**< Size of buf except extra allocated bytes */ +} AVProbeData; + +#define AVPROBE_SCORE_MAX 100 ///< maximum score, half of that is used for file-extension-based detection +#define AVPROBE_PADDING_SIZE 32 ///< extra allocated bytes at the end of the probe buffer + +typedef struct AVFormatParameters { + AVRational time_base; + int sample_rate; + int channels; + int width; + int height; + enum PixelFormat pix_fmt; + int channel; /**< Used to select DV channel. */ + const char *standard; /**< TV standard, NTSC, PAL, SECAM */ + unsigned int mpeg2ts_raw:1; /**< Force raw MPEG-2 transport stream output, if possible. */ + unsigned int mpeg2ts_compute_pcr:1; /**< Compute exact PCR for each transport + stream packet (only meaningful if + mpeg2ts_raw is TRUE). */ + unsigned int initial_pause:1; /**< Do not begin to play the stream + immediately (RTSP only). */ + unsigned int prealloced_context:1; +#if LIBAVFORMAT_VERSION_INT < (53<<16) + enum CodecID video_codec_id; + enum CodecID audio_codec_id; +#endif +} AVFormatParameters; + +//! Demuxer will use url_fopen, no opened file should be provided by the caller. +#define AVFMT_NOFILE 0x0001 +#define AVFMT_NEEDNUMBER 0x0002 /**< Needs '%d' in filename. */ +#define AVFMT_SHOW_IDS 0x0008 /**< Show format stream IDs numbers. */ +#define AVFMT_RAWPICTURE 0x0020 /**< Format wants AVPicture structure for + raw picture data. */ +#define AVFMT_GLOBALHEADER 0x0040 /**< Format wants global header. */ +#define AVFMT_NOTIMESTAMPS 0x0080 /**< Format does not need / have any timestamps. */ +#define AVFMT_GENERIC_INDEX 0x0100 /**< Use generic index building code. */ +#define AVFMT_TS_DISCONT 0x0200 /**< Format allows timestamp discontinuities. */ +#define AVFMT_VARIABLE_FPS 0x0400 /**< Format allows variable fps. */ +#define AVFMT_NODIMENSIONS 0x0800 /**< Format does not need width/height */ + +typedef struct AVOutputFormat { + const char *name; + /** + * Descriptive name for the format, meant to be more human-readable + * than name. You should use the NULL_IF_CONFIG_SMALL() macro + * to define it. + */ + const char *long_name; + const char *mime_type; + const char *extensions; /**< comma-separated filename extensions */ + /** size of private data so that it can be allocated in the wrapper */ + int priv_data_size; + /* output support */ + enum CodecID audio_codec; /**< default audio codec */ + enum CodecID video_codec; /**< default video codec */ + int (*write_header)(struct AVFormatContext *); + int (*write_packet)(struct AVFormatContext *, AVPacket *pkt); + int (*write_trailer)(struct AVFormatContext *); + /** can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_GLOBALHEADER */ + int flags; + /** Currently only used to set pixel format if not YUV420P. */ + int (*set_parameters)(struct AVFormatContext *, AVFormatParameters *); + int (*interleave_packet)(struct AVFormatContext *, AVPacket *out, + AVPacket *in, int flush); + + /** + * List of supported codec_id-codec_tag pairs, ordered by "better + * choice first". The arrays are all terminated by CODEC_ID_NONE. + */ + const struct AVCodecTag * const *codec_tag; + + enum CodecID subtitle_codec; /**< default subtitle codec */ + + const AVMetadataConv *metadata_conv; + + /* private fields */ + struct AVOutputFormat *next; +} AVOutputFormat; + +typedef struct AVInputFormat { + const char *name; + /** + * Descriptive name for the format, meant to be more human-readable + * than name. You should use the NULL_IF_CONFIG_SMALL() macro + * to define it. + */ + const char *long_name; + /** Size of private data so that it can be allocated in the wrapper. */ + int priv_data_size; + /** + * Tell if a given file has a chance of being parsed as this format. + * The buffer provided is guaranteed to be AVPROBE_PADDING_SIZE bytes + * big so you do not have to check for that unless you need more. + */ + int (*read_probe)(AVProbeData *); + /** Read the format header and initialize the AVFormatContext + structure. Return 0 if OK. 'ap' if non-NULL contains + additional parameters. Only used in raw format right + now. 'av_new_stream' should be called to create new streams. */ + int (*read_header)(struct AVFormatContext *, + AVFormatParameters *ap); + /** Read one packet and put it in 'pkt'. pts and flags are also + set. 'av_new_stream' can be called only if the flag + AVFMTCTX_NOHEADER is used. + @return 0 on success, < 0 on error. + When returning an error, pkt must not have been allocated + or must be freed before returning */ + int (*read_packet)(struct AVFormatContext *, AVPacket *pkt); + /** Close the stream. The AVFormatContext and AVStreams are not + freed by this function */ + int (*read_close)(struct AVFormatContext *); + +#if LIBAVFORMAT_VERSION_MAJOR < 53 + /** + * Seek to a given timestamp relative to the frames in + * stream component stream_index. + * @param stream_index Must not be -1. + * @param flags Selects which direction should be preferred if no exact + * match is available. + * @return >= 0 on success (but not necessarily the new offset) + */ + int (*read_seek)(struct AVFormatContext *, + int stream_index, int64_t timestamp, int flags); +#endif + /** + * Gets the next timestamp in stream[stream_index].time_base units. + * @return the timestamp or AV_NOPTS_VALUE if an error occurred + */ + int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index, + int64_t *pos, int64_t pos_limit); + /** Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER. */ + int flags; + /** If extensions are defined, then no probe is done. You should + usually not use extension format guessing because it is not + reliable enough */ + const char *extensions; + /** General purpose read-only value that the format can use. */ + int value; + + /** Starts/resumes playing - only meaningful if using a network-based format + (RTSP). */ + int (*read_play)(struct AVFormatContext *); + + /** Pauses playing - only meaningful if using a network-based format + (RTSP). */ + int (*read_pause)(struct AVFormatContext *); + + const struct AVCodecTag * const *codec_tag; + + /** + * Seeks to timestamp ts. + * Seeking will be done so that the point from which all active streams + * can be presented successfully will be closest to ts and within min/max_ts. + * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL. + */ + int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); + + const AVMetadataConv *metadata_conv; + + /* private fields */ + struct AVInputFormat *next; +} AVInputFormat; + +enum AVStreamParseType { + AVSTREAM_PARSE_NONE, + AVSTREAM_PARSE_FULL, /**< full parsing and repack */ + AVSTREAM_PARSE_HEADERS, /**< Only parse headers, do not repack. */ + AVSTREAM_PARSE_TIMESTAMPS, /**< full parsing and interpolation of timestamps for frames not starting on a packet boundary */ +}; + +typedef struct AVIndexEntry { + int64_t pos; + int64_t timestamp; +#define AVINDEX_KEYFRAME 0x0001 + int flags:2; + int size:30; //Yeah, trying to keep the size of this small to reduce memory requirements (it is 24 vs. 32 bytes due to possible 8-byte alignment). + int min_distance; /**< Minimum distance between this and the previous keyframe, used to avoid unneeded searching. */ +} AVIndexEntry; + +#define AV_DISPOSITION_DEFAULT 0x0001 +#define AV_DISPOSITION_DUB 0x0002 +#define AV_DISPOSITION_ORIGINAL 0x0004 +#define AV_DISPOSITION_COMMENT 0x0008 +#define AV_DISPOSITION_LYRICS 0x0010 +#define AV_DISPOSITION_KARAOKE 0x0020 + +/** + * Stream structure. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(AVStream) must not be used outside libav*. + */ +typedef struct AVStream { + int index; /**< stream index in AVFormatContext */ + int id; /**< format-specific stream ID */ + AVCodecContext *codec; /**< codec context */ + /** + * Real base framerate of the stream. + * This is the lowest framerate with which all timestamps can be + * represented accurately (it is the least common multiple of all + * framerates in the stream). Note, this value is just a guess! + * For example, if the time base is 1/90000 and all frames have either + * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1. + */ + AVRational r_frame_rate; + void *priv_data; + + /* internal data used in av_find_stream_info() */ + int64_t first_dts; + /** encoding: pts generation when outputting stream */ + struct AVFrac pts; + + /** + * This is the fundamental unit of time (in seconds) in terms + * of which frame timestamps are represented. For fixed-fps content, + * time base should be 1/framerate and timestamp increments should be 1. + */ + AVRational time_base; + int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */ + /* ffmpeg.c private use */ + int stream_copy; /**< If set, just copy stream. */ + enum AVDiscard discard; ///< Selects which packets can be discarded at will and do not need to be demuxed. + //FIXME move stuff to a flags field? + /** Quality, as it has been removed from AVCodecContext and put in AVVideoFrame. + * MN: dunno if that is the right place for it */ + float quality; + /** + * Decoding: pts of the first frame of the stream, in stream time base. + * Only set this if you are absolutely 100% sure that the value you set + * it to really is the pts of the first frame. + * This may be undefined (AV_NOPTS_VALUE). + * @note The ASF header does NOT contain a correct start_time the ASF + * demuxer must NOT set this. + */ + int64_t start_time; + /** + * Decoding: duration of the stream, in stream time base. + * If a source file does not specify a duration, but does specify + * a bitrate, this value will be estimated from bitrate and file size. + */ + int64_t duration; + +#if LIBAVFORMAT_VERSION_INT < (53<<16) + char language[4]; /** ISO 639-2/B 3-letter language code (empty string if undefined) */ +#endif + + /* av_read_frame() support */ + enum AVStreamParseType need_parsing; + struct AVCodecParserContext *parser; + + int64_t cur_dts; + int last_IP_duration; + int64_t last_IP_pts; + /* av_seek_frame() support */ + AVIndexEntry *index_entries; /**< Only used if the format does not + support seeking natively. */ + int nb_index_entries; + unsigned int index_entries_allocated_size; + + int64_t nb_frames; ///< number of frames in this stream if known or 0 + +#if LIBAVFORMAT_VERSION_INT < (53<<16) + int64_t unused[4+1]; + + char *filename; /**< source filename of the stream */ +#endif + + int disposition; /**< AV_DISPOSITION_* bit field */ + + AVProbeData probe_data; +#define MAX_REORDER_DELAY 16 + int64_t pts_buffer[MAX_REORDER_DELAY+1]; + + /** + * sample aspect ratio (0 if unknown) + * - encoding: Set by user. + * - decoding: Set by libavformat. + */ + AVRational sample_aspect_ratio; + + AVMetadata *metadata; + + /* av_read_frame() support */ + const uint8_t *cur_ptr; + int cur_len; + AVPacket cur_pkt; + + // Timestamp generation support: + /** + * Timestamp corresponding to the last dts sync point. + * + * Initialized when AVCodecParserContext.dts_sync_point >= 0 and + * a DTS is received from the underlying container. Otherwise set to + * AV_NOPTS_VALUE by default. + */ + int64_t reference_dts; + + /** + * Number of packets to buffer for codec probing + * NOT PART OF PUBLIC API + */ +#define MAX_PROBE_PACKETS 2500 + int probe_packets; + + /** + * last packet in packet_buffer for this stream when muxing. + * used internally, NOT PART OF PUBLIC API, dont read or write from outside of libav* + */ + struct AVPacketList *last_in_packet_buffer; + + /** + * Average framerate + */ + AVRational avg_frame_rate; + + /** + * Number of frames that have been demuxed during av_find_stream_info() + */ + int codec_info_nb_frames; +} AVStream; + +#define AV_PROGRAM_RUNNING 1 + +/** + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(AVProgram) must not be used outside libav*. + */ +typedef struct AVProgram { + int id; +#if LIBAVFORMAT_VERSION_INT < (53<<16) + char *provider_name; ///< network name for DVB streams + char *name; ///< service name for DVB streams +#endif + int flags; + enum AVDiscard discard; ///< selects which program to discard and which to feed to the caller + unsigned int *stream_index; + unsigned int nb_stream_indexes; + AVMetadata *metadata; +} AVProgram; + +#define AVFMTCTX_NOHEADER 0x0001 /**< signal that no header is present + (streams are added dynamically) */ + +typedef struct AVChapter { + int id; ///< unique ID to identify the chapter + AVRational time_base; ///< time base in which the start/end timestamps are specified + int64_t start, end; ///< chapter start/end time in time_base units +#if LIBAVFORMAT_VERSION_INT < (53<<16) + char *title; ///< chapter title +#endif + AVMetadata *metadata; +} AVChapter; + +#if LIBAVFORMAT_VERSION_MAJOR < 53 +#define MAX_STREAMS 20 +#else +#define MAX_STREAMS 100 +#endif + +/** + * Format I/O context. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(AVFormatContext) must not be used outside libav*. + */ +typedef struct AVFormatContext { + const AVClass *av_class; /**< Set by avformat_alloc_context. */ + /* Can only be iformat or oformat, not both at the same time. */ + struct AVInputFormat *iformat; + struct AVOutputFormat *oformat; + void *priv_data; + ByteIOContext *pb; + unsigned int nb_streams; + AVStream *streams[MAX_STREAMS]; + char filename[1024]; /**< input or output filename */ + /* stream info */ + int64_t timestamp; +#if LIBAVFORMAT_VERSION_INT < (53<<16) + char title[512]; + char author[512]; + char copyright[512]; + char comment[512]; + char album[512]; + int year; /**< ID3 year, 0 if none */ + int track; /**< track number, 0 if none */ + char genre[32]; /**< ID3 genre */ +#endif + + int ctx_flags; /**< Format-specific flags, see AVFMTCTX_xx */ + /* private data for pts handling (do not modify directly). */ + /** This buffer is only needed when packets were already buffered but + not decoded, for example to get the codec parameters in MPEG + streams. */ + struct AVPacketList *packet_buffer; + + /** Decoding: position of the first frame of the component, in + AV_TIME_BASE fractional seconds. NEVER set this value directly: + It is deduced from the AVStream values. */ + int64_t start_time; + /** Decoding: duration of the stream, in AV_TIME_BASE fractional + seconds. Only set this value if you know none of the individual stream + durations and also dont set any of them. This is deduced from the + AVStream values if not set. */ + int64_t duration; + /** decoding: total file size, 0 if unknown */ + int64_t file_size; + /** Decoding: total stream bitrate in bit/s, 0 if not + available. Never set it directly if the file_size and the + duration are known as FFmpeg can compute it automatically. */ + int bit_rate; + + /* av_read_frame() support */ + AVStream *cur_st; +#if LIBAVFORMAT_VERSION_INT < (53<<16) + const uint8_t *cur_ptr_deprecated; + int cur_len_deprecated; + AVPacket cur_pkt_deprecated; +#endif + + /* av_seek_frame() support */ + int64_t data_offset; /** offset of the first packet */ + int index_built; + + int mux_rate; + unsigned int packet_size; + int preload; + int max_delay; + +#define AVFMT_NOOUTPUTLOOP -1 +#define AVFMT_INFINITEOUTPUTLOOP 0 + /** number of times to loop output in formats that support it */ + int loop_output; + + int flags; +#define AVFMT_FLAG_GENPTS 0x0001 ///< Generate missing pts even if it requires parsing future frames. +#define AVFMT_FLAG_IGNIDX 0x0002 ///< Ignore index. +#define AVFMT_FLAG_NONBLOCK 0x0004 ///< Do not block when reading packets from input. +#define AVFMT_FLAG_IGNDTS 0x0008 ///< Ignore DTS on frames that contain both DTS & PTS +#define AVFMT_FLAG_NOFILLIN 0x0010 ///< Do not infer any values from other values, just return what is stored in the container +#define AVFMT_FLAG_NOPARSE 0x0020 ///< Do not use AVParsers, you also must set AVFMT_FLAG_NOFILLIN as the fillin code works on frames and no parsing -> no frames. Also seeking to frames can not work if parsing to find frame boundaries has been disabled + + int loop_input; + /** decoding: size of data to probe; encoding: unused. */ + unsigned int probesize; + + /** + * Maximum time (in AV_TIME_BASE units) during which the input should + * be analyzed in av_find_stream_info(). + */ + int max_analyze_duration; + + const uint8_t *key; + int keylen; + + unsigned int nb_programs; + AVProgram **programs; + + /** + * Forced video codec_id. + * Demuxing: Set by user. + */ + enum CodecID video_codec_id; + /** + * Forced audio codec_id. + * Demuxing: Set by user. + */ + enum CodecID audio_codec_id; + /** + * Forced subtitle codec_id. + * Demuxing: Set by user. + */ + enum CodecID subtitle_codec_id; + + /** + * Maximum amount of memory in bytes to use for the index of each stream. + * If the index exceeds this size, entries will be discarded as + * needed to maintain a smaller size. This can lead to slower or less + * accurate seeking (depends on demuxer). + * Demuxers for which a full in-memory index is mandatory will ignore + * this. + * muxing : unused + * demuxing: set by user + */ + unsigned int max_index_size; + + /** + * Maximum amount of memory in bytes to use for buffering frames + * obtained from realtime capture devices. + */ + unsigned int max_picture_buffer; + + unsigned int nb_chapters; + AVChapter **chapters; + + /** + * Flags to enable debugging. + */ + int debug; +#define FF_FDEBUG_TS 0x0001 + + /** + * Raw packets from the demuxer, prior to parsing and decoding. + * This buffer is used for buffering packets until the codec can + * be identified, as parsing cannot be done without knowing the + * codec. + */ + struct AVPacketList *raw_packet_buffer; + struct AVPacketList *raw_packet_buffer_end; + + struct AVPacketList *packet_buffer_end; + + AVMetadata *metadata; + + /** + * Remaining size available for raw_packet_buffer, in bytes. + * NOT PART OF PUBLIC API + */ +#define RAW_PACKET_BUFFER_SIZE 2500000 + int raw_packet_buffer_remaining_size; + + /** + * Start time of the stream in real world time, in microseconds + * since the unix epoch (00:00 1st January 1970). That is, pts=0 + * in the stream was captured at this real world time. + * - encoding: Set by user. + * - decoding: Unused. + */ + int64_t start_time_realtime; +} AVFormatContext; + +typedef struct AVPacketList { + AVPacket pkt; + struct AVPacketList *next; +} AVPacketList; + +#if LIBAVFORMAT_VERSION_INT < (53<<16) +extern AVInputFormat *first_iformat; +extern AVOutputFormat *first_oformat; +#endif + +/** + * If f is NULL, returns the first registered input format, + * if f is non-NULL, returns the next registered input format after f + * or NULL if f is the last one. + */ +AVInputFormat *av_iformat_next(AVInputFormat *f); + +/** + * If f is NULL, returns the first registered output format, + * if f is non-NULL, returns the next registered output format after f + * or NULL if f is the last one. + */ +AVOutputFormat *av_oformat_next(AVOutputFormat *f); + +enum CodecID av_guess_image2_codec(const char *filename); + +/* XXX: Use automatic init with either ELF sections or C file parser */ +/* modules. */ + +/* utils.c */ +void av_register_input_format(AVInputFormat *format); +void av_register_output_format(AVOutputFormat *format); +#if LIBAVFORMAT_VERSION_MAJOR < 53 +attribute_deprecated AVOutputFormat *guess_stream_format(const char *short_name, + const char *filename, + const char *mime_type); + +/** + * @deprecated Use av_guess_format() instead. + */ +attribute_deprecated AVOutputFormat *guess_format(const char *short_name, + const char *filename, + const char *mime_type); +#endif + +/** + * Returns the output format in the list of registered output formats + * which best matches the provided parameters, or returns NULL if + * there is no match. + * + * @param short_name if non-NULL checks if short_name matches with the + * names of the registered formats + * @param filename if non-NULL checks if filename terminates with the + * extensions of the registered formats + * @param mime_type if non-NULL checks if mime_type matches with the + * MIME type of the registered formats + */ +AVOutputFormat *av_guess_format(const char *short_name, + const char *filename, + const char *mime_type); + +/** + * Guesses the codec ID based upon muxer and filename. + */ +enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name, + const char *filename, const char *mime_type, + enum AVMediaType type); + +/** + * Sends a nice hexadecimal dump of a buffer to the specified file stream. + * + * @param f The file stream pointer where the dump should be sent to. + * @param buf buffer + * @param size buffer size + * + * @see av_hex_dump_log, av_pkt_dump, av_pkt_dump_log + */ +void av_hex_dump(FILE *f, uint8_t *buf, int size); + +/** + * Sends a nice hexadecimal dump of a buffer to the log. + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message, lower values signifying + * higher importance. + * @param buf buffer + * @param size buffer size + * + * @see av_hex_dump, av_pkt_dump, av_pkt_dump_log + */ +void av_hex_dump_log(void *avcl, int level, uint8_t *buf, int size); + +/** + * Sends a nice dump of a packet to the specified file stream. + * + * @param f The file stream pointer where the dump should be sent to. + * @param pkt packet to dump + * @param dump_payload True if the payload must be displayed, too. + */ +void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload); + +/** + * Sends a nice dump of a packet to the log. + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message, lower values signifying + * higher importance. + * @param pkt packet to dump + * @param dump_payload True if the payload must be displayed, too. + */ +void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt, int dump_payload); + +/** + * Initializes libavformat and registers all the muxers, demuxers and + * protocols. If you do not call this function, then you can select + * exactly which formats you want to support. + * + * @see av_register_input_format() + * @see av_register_output_format() + * @see av_register_protocol() + */ +void av_register_all(void); + +/** codec tag <-> codec id */ +enum CodecID av_codec_get_id(const struct AVCodecTag * const *tags, unsigned int tag); +unsigned int av_codec_get_tag(const struct AVCodecTag * const *tags, enum CodecID id); + +/* media file input */ + +/** + * Finds AVInputFormat based on the short name of the input format. + */ +AVInputFormat *av_find_input_format(const char *short_name); + +/** + * Guesses the file format. + * + * @param is_opened Whether the file is already opened; determines whether + * demuxers with or without AVFMT_NOFILE are probed. + */ +AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened); + +/** + * Allocates all the structures needed to read an input stream. + * This does not open the needed codecs for decoding the stream[s]. + */ +int av_open_input_stream(AVFormatContext **ic_ptr, + ByteIOContext *pb, const char *filename, + AVInputFormat *fmt, AVFormatParameters *ap); + +/** + * Opens a media file as input. The codecs are not opened. Only the file + * header (if present) is read. + * + * @param ic_ptr The opened media file handle is put here. + * @param filename filename to open + * @param fmt If non-NULL, force the file format to use. + * @param buf_size optional buffer size (zero if default is OK) + * @param ap Additional parameters needed when opening the file + * (NULL if default). + * @return 0 if OK, AVERROR_xxx otherwise + */ +int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, + AVInputFormat *fmt, + int buf_size, + AVFormatParameters *ap); + +#if LIBAVFORMAT_VERSION_MAJOR < 53 +/** + * @deprecated Use avformat_alloc_context() instead. + */ +attribute_deprecated AVFormatContext *av_alloc_format_context(void); +#endif + +/** + * Allocates an AVFormatContext. + * Can be freed with av_free() but do not forget to free everything you + * explicitly allocated as well! + */ +AVFormatContext *avformat_alloc_context(void); + +/** + * Reads packets of a media file to get stream information. This + * is useful for file formats with no headers such as MPEG. This + * function also computes the real framerate in case of MPEG-2 repeat + * frame mode. + * The logical file position is not changed by this function; + * examined packets may be buffered for later processing. + * + * @param ic media file handle + * @return >=0 if OK, AVERROR_xxx on error + * @todo Let the user decide somehow what information is needed so that + * we do not waste time getting stuff the user does not need. + */ +int av_find_stream_info(AVFormatContext *ic); + +/** + * Reads a transport packet from a media file. + * + * This function is obsolete and should never be used. + * Use av_read_frame() instead. + * + * @param s media file handle + * @param pkt is filled + * @return 0 if OK, AVERROR_xxx on error + */ +int av_read_packet(AVFormatContext *s, AVPacket *pkt); + +/** + * Returns the next frame of a stream. + * + * The returned packet is valid + * until the next av_read_frame() or until av_close_input_file() and + * must be freed with av_free_packet. For video, the packet contains + * exactly one frame. For audio, it contains an integer number of + * frames if each frame has a known fixed size (e.g. PCM or ADPCM + * data). If the audio frames have a variable size (e.g. MPEG audio), + * then it contains one frame. + * + * pkt->pts, pkt->dts and pkt->duration are always set to correct + * values in AVStream.time_base units (and guessed if the format cannot + * provide them). pkt->pts can be AV_NOPTS_VALUE if the video format + * has B-frames, so it is better to rely on pkt->dts if you do not + * decompress the payload. + * + * @return 0 if OK, < 0 on error or end of file + */ +int av_read_frame(AVFormatContext *s, AVPacket *pkt); + +/** + * Seeks to the keyframe at timestamp. + * 'timestamp' in 'stream_index'. + * @param stream_index If stream_index is (-1), a default + * stream is selected, and timestamp is automatically converted + * from AV_TIME_BASE units to the stream specific time_base. + * @param timestamp Timestamp in AVStream.time_base units + * or, if no stream is specified, in AV_TIME_BASE units. + * @param flags flags which select direction and seeking mode + * @return >= 0 on success + */ +int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, + int flags); + +/** + * Seeks to timestamp ts. + * Seeking will be done so that the point from which all active streams + * can be presented successfully will be closest to ts and within min/max_ts. + * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL. + * + * If flags contain AVSEEK_FLAG_BYTE, then all timestamps are in bytes and + * are the file position (this may not be supported by all demuxers). + * If flags contain AVSEEK_FLAG_FRAME, then all timestamps are in frames + * in the stream with stream_index (this may not be supported by all demuxers). + * Otherwise all timestamps are in units of the stream selected by stream_index + * or if stream_index is -1, in AV_TIME_BASE units. + * If flags contain AVSEEK_FLAG_ANY, then non-keyframes are treated as + * keyframes (this may not be supported by all demuxers). + * + * @param stream_index index of the stream which is used as time base reference + * @param min_ts smallest acceptable timestamp + * @param ts target timestamp + * @param max_ts largest acceptable timestamp + * @param flags flags + * @return >=0 on success, error code otherwise + * + * @NOTE This is part of the new seek API which is still under construction. + * Thus do not use this yet. It may change at any time, do not expect + * ABI compatibility yet! + */ +int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); + +/** + * Starts playing a network-based stream (e.g. RTSP stream) at the + * current position. + */ +int av_read_play(AVFormatContext *s); + +/** + * Pauses a network-based stream (e.g. RTSP stream). + * + * Use av_read_play() to resume it. + */ +int av_read_pause(AVFormatContext *s); + +/** + * Frees a AVFormatContext allocated by av_open_input_stream. + * @param s context to free + */ +void av_close_input_stream(AVFormatContext *s); + +/** + * Closes a media file (but not its codecs). + * + * @param s media file handle + */ +void av_close_input_file(AVFormatContext *s); + +/** + * Adds a new stream to a media file. + * + * Can only be called in the read_header() function. If the flag + * AVFMTCTX_NOHEADER is in the format context, then new streams + * can be added in read_packet too. + * + * @param s media file handle + * @param id file-format-dependent stream ID + */ +AVStream *av_new_stream(AVFormatContext *s, int id); +AVProgram *av_new_program(AVFormatContext *s, int id); + +/** + * Adds a new chapter. + * This function is NOT part of the public API + * and should ONLY be used by demuxers. + * + * @param s media file handle + * @param id unique ID for this chapter + * @param start chapter start time in time_base units + * @param end chapter end time in time_base units + * @param title chapter title + * + * @return AVChapter or NULL on error + */ +AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base, + int64_t start, int64_t end, const char *title); + +/** + * Sets the pts for a given stream. + * + * @param s stream + * @param pts_wrap_bits number of bits effectively used by the pts + * (used for wrap control, 33 is the value for MPEG) + * @param pts_num numerator to convert to seconds (MPEG: 1) + * @param pts_den denominator to convert to seconds (MPEG: 90000) + */ +void av_set_pts_info(AVStream *s, int pts_wrap_bits, + unsigned int pts_num, unsigned int pts_den); + +#define AVSEEK_FLAG_BACKWARD 1 ///< seek backward +#define AVSEEK_FLAG_BYTE 2 ///< seeking based on position in bytes +#define AVSEEK_FLAG_ANY 4 ///< seek to any frame, even non-keyframes +#define AVSEEK_FLAG_FRAME 8 ///< seeking based on frame number + +int av_find_default_stream_index(AVFormatContext *s); + +/** + * Gets the index for a specific timestamp. + * @param flags if AVSEEK_FLAG_BACKWARD then the returned index will correspond + * to the timestamp which is <= the requested one, if backward + * is 0, then it will be >= + * if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise + * @return < 0 if no such timestamp could be found + */ +int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags); + +/** + * Ensures the index uses less memory than the maximum specified in + * AVFormatContext.max_index_size by discarding entries if it grows + * too large. + * This function is not part of the public API and should only be called + * by demuxers. + */ +void ff_reduce_index(AVFormatContext *s, int stream_index); + +/** + * Adds an index entry into a sorted list. Updates the entry if the list + * already contains it. + * + * @param timestamp timestamp in the time base of the given stream + */ +int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, + int size, int distance, int flags); + +/** + * Does a binary search using av_index_search_timestamp() and + * AVCodec.read_timestamp(). + * This is not supposed to be called directly by a user application, + * but by demuxers. + * @param target_ts target timestamp in the time base of the given stream + * @param stream_index stream number + */ +int av_seek_frame_binary(AVFormatContext *s, int stream_index, + int64_t target_ts, int flags); + +/** + * Updates cur_dts of all streams based on the given timestamp and AVStream. + * + * Stream ref_st unchanged, others set cur_dts in their native time base. + * Only needed for timestamp wrapping or if (dts not set and pts!=dts). + * @param timestamp new dts expressed in time_base of param ref_st + * @param ref_st reference stream giving time_base of param timestamp + */ +void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp); + +/** + * Does a binary search using read_timestamp(). + * This is not supposed to be called directly by a user application, + * but by demuxers. + * @param target_ts target timestamp in the time base of the given stream + * @param stream_index stream number + */ +int64_t av_gen_search(AVFormatContext *s, int stream_index, + int64_t target_ts, int64_t pos_min, + int64_t pos_max, int64_t pos_limit, + int64_t ts_min, int64_t ts_max, + int flags, int64_t *ts_ret, + int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )); + +/** media file output */ +int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap); + +/** + * Allocates the stream private data and writes the stream header to an + * output media file. + * + * @param s media file handle + * @return 0 if OK, AVERROR_xxx on error + */ +int av_write_header(AVFormatContext *s); + +/** + * Writes a packet to an output media file. + * + * The packet shall contain one audio or video frame. + * The packet must be correctly interleaved according to the container + * specification, if not then av_interleaved_write_frame must be used. + * + * @param s media file handle + * @param pkt The packet, which contains the stream_index, buf/buf_size, + dts/pts, ... + * @return < 0 on error, = 0 if OK, 1 if end of stream wanted + */ +int av_write_frame(AVFormatContext *s, AVPacket *pkt); + +/** + * Writes a packet to an output media file ensuring correct interleaving. + * + * The packet must contain one audio or video frame. + * If the packets are already correctly interleaved, the application should + * call av_write_frame() instead as it is slightly faster. It is also important + * to keep in mind that completely non-interleaved input will need huge amounts + * of memory to interleave with this, so it is preferable to interleave at the + * demuxer level. + * + * @param s media file handle + * @param pkt The packet, which contains the stream_index, buf/buf_size, + dts/pts, ... + * @return < 0 on error, = 0 if OK, 1 if end of stream wanted + */ +int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt); + +/** + * Interleaves a packet per dts in an output media file. + * + * Packets with pkt->destruct == av_destruct_packet will be freed inside this + * function, so they cannot be used after it. Note that calling av_free_packet() + * on them is still safe. + * + * @param s media file handle + * @param out the interleaved packet will be output here + * @param in the input packet + * @param flush 1 if no further packets are available as input and all + * remaining packets should be output + * @return 1 if a packet was output, 0 if no packet could be output, + * < 0 if an error occurred + */ +int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, + AVPacket *pkt, int flush); + +/** + * Writes the stream trailer to an output media file and frees the + * file private data. + * + * May only be called after a successful call to av_write_header. + * + * @param s media file handle + * @return 0 if OK, AVERROR_xxx on error + */ +int av_write_trailer(AVFormatContext *s); + +void dump_format(AVFormatContext *ic, + int index, + const char *url, + int is_output); + +#if LIBAVFORMAT_VERSION_MAJOR < 53 +/** + * Parses width and height out of string str. + * @deprecated Use av_parse_video_frame_size instead. + */ +attribute_deprecated int parse_image_size(int *width_ptr, int *height_ptr, + const char *str); + +/** + * Converts framerate from a string to a fraction. + * @deprecated Use av_parse_video_frame_rate instead. + */ +attribute_deprecated int parse_frame_rate(int *frame_rate, int *frame_rate_base, + const char *arg); +#endif + +/** + * Parses datestr and returns a corresponding number of microseconds. + * @param datestr String representing a date or a duration. + * - If a date the syntax is: + * @code + * [{YYYY-MM-DD|YYYYMMDD}]{T| }{HH[:MM[:SS[.m...]]][Z]|HH[MM[SS[.m...]]][Z]} + * @endcode + * Time is local time unless Z is appended, in which case it is + * interpreted as UTC. + * If the year-month-day part is not specified it takes the current + * year-month-day. + * Returns the number of microseconds since 1st of January, 1970 up to + * the time of the parsed date or INT64_MIN if datestr cannot be + * successfully parsed. + * - If a duration the syntax is: + * @code + * [-]HH[:MM[:SS[.m...]]] + * [-]S+[.m...] + * @endcode + * Returns the number of microseconds contained in a time interval + * with the specified duration or INT64_MIN if datestr cannot be + * successfully parsed. + * @param duration Flag which tells how to interpret datestr, if + * not zero datestr is interpreted as a duration, otherwise as a + * date. + */ +int64_t parse_date(const char *datestr, int duration); + +/** Gets the current time in microseconds. */ +int64_t av_gettime(void); + +/* ffm-specific for ffserver */ +#define FFM_PACKET_SIZE 4096 +int64_t ffm_read_write_index(int fd); +int ffm_write_write_index(int fd, int64_t pos); +void ffm_set_write_index(AVFormatContext *s, int64_t pos, int64_t file_size); + +/** + * Attempts to find a specific tag in a URL. + * + * syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. + * Return 1 if found. + */ +int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info); + +/** + * Returns in 'buf' the path with '%d' replaced by a number. + * + * Also handles the '%0nd' format where 'n' is the total number + * of digits and '%%'. + * + * @param buf destination buffer + * @param buf_size destination buffer size + * @param path numbered sequence string + * @param number frame number + * @return 0 if OK, -1 on format error + */ +int av_get_frame_filename(char *buf, int buf_size, + const char *path, int number); + +/** + * Checks whether filename actually is a numbered sequence generator. + * + * @param filename possible numbered sequence string + * @return 1 if a valid numbered sequence string, 0 otherwise + */ +int av_filename_number_test(const char *filename); + +/** + * Generates an SDP for an RTP session. + * + * @param ac array of AVFormatContexts describing the RTP streams. If the + * array is composed by only one context, such context can contain + * multiple AVStreams (one AVStream per RTP stream). Otherwise, + * all the contexts in the array (an AVCodecContext per RTP stream) + * must contain only one AVStream. + * @param n_files number of AVCodecContexts contained in ac + * @param buff buffer where the SDP will be stored (must be allocated by + * the caller) + * @param size the size of the buffer + * @return 0 if OK, AVERROR_xxx on error + */ +int avf_sdp_create(AVFormatContext *ac[], int n_files, char *buff, int size); + +/** + * Returns a positive value if the given filename has one of the given + * extensions, 0 otherwise. + * + * @param extensions a comma-separated list of filename extensions + */ +int av_match_ext(const char *filename, const char *extensions); + +#endif /* AVFORMAT_AVFORMAT_H */ diff --git a/extra_lib/include/ffmpeg_android/libavformat/avio.h b/extra_lib/include/ffmpeg_android/libavformat/avio.h new file mode 100644 index 0000000..d186876 --- /dev/null +++ b/extra_lib/include/ffmpeg_android/libavformat/avio.h @@ -0,0 +1,525 @@ +/* + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg 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.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef AVFORMAT_AVIO_H +#define AVFORMAT_AVIO_H + +/** + * @file libavformat/avio.h + * unbuffered I/O operations + * + * @warning This file has to be considered an internal but installed + * header, so it should not be directly included in your projects. + */ + +#include + +#include "libavutil/common.h" + +/* unbuffered I/O */ + +/** + * URL Context. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(URLContext) must not be used outside libav*. + */ +typedef struct URLContext { +#if LIBAVFORMAT_VERSION_MAJOR >= 53 + const AVClass *av_class; ///< information for av_log(). Set by url_open(). +#endif + struct URLProtocol *prot; + int flags; + int is_streamed; /**< true if streamed (no seek possible), default = false */ + int max_packet_size; /**< if non zero, the stream is packetized with this max packet size */ + void *priv_data; + char *filename; /**< specified URL */ +} URLContext; + +typedef struct URLPollEntry { + URLContext *handle; + int events; + int revents; +} URLPollEntry; + +#define URL_RDONLY 0 +#define URL_WRONLY 1 +#define URL_RDWR 2 + +typedef int URLInterruptCB(void); + +/** + * Creates an URLContext for accessing to the resource indicated by + * url, and opens it using the URLProtocol up. + * + * @param puc pointer to the location where, in case of success, the + * function puts the pointer to the created URLContext + * @param flags flags which control how the resource indicated by url + * is to be opened + * @return 0 in case of success, a negative value corresponding to an + * AVERROR code in case of failure + */ +int url_open_protocol (URLContext **puc, struct URLProtocol *up, + const char *url, int flags); + +/** + * Creates an URLContext for accessing to the resource indicated by + * url, and opens it. + * + * @param puc pointer to the location where, in case of success, the + * function puts the pointer to the created URLContext + * @param flags flags which control how the resource indicated by url + * is to be opened + * @return 0 in case of success, a negative value corresponding to an + * AVERROR code in case of failure + */ +int url_open(URLContext **h, const char *url, int flags); + +/** + * Reads up to size bytes from the resource accessed by h, and stores + * the read bytes in buf. + * + * @return The number of bytes actually read, or a negative value + * corresponding to an AVERROR code in case of error. A value of zero + * indicates that it is not possible to read more from the accessed + * resource (except if the value of the size argument is also zero). + */ +int url_read(URLContext *h, unsigned char *buf, int size); + +/** + * Read as many bytes as possible (up to size), calling the + * read function multiple times if necessary. + * Will also retry if the read function returns AVERROR(EAGAIN). + * This makes special short-read handling in applications + * unnecessary, if the return value is < size then it is + * certain there was either an error or the end of file was reached. + */ +int url_read_complete(URLContext *h, unsigned char *buf, int size); +int url_write(URLContext *h, unsigned char *buf, int size); + +/** + * Changes the position that will be used by the next read/write + * operation on the resource accessed by h. + * + * @param pos specifies the new position to set + * @param whence specifies how pos should be interpreted, it must be + * one of SEEK_SET (seek from the beginning), SEEK_CUR (seek from the + * current position), SEEK_END (seek from the end), or AVSEEK_SIZE + * (return the filesize of the requested resource, pos is ignored). + * @return a negative value corresponding to an AVERROR code in case + * of failure, or the resulting file position, measured in bytes from + * the beginning of the file. You can use this feature together with + * SEEK_CUR to read the current file position. + */ +int64_t url_seek(URLContext *h, int64_t pos, int whence); + +/** + * Closes the resource accessed by the URLContext h, and frees the + * memory used by it. + * + * @return a negative value if an error condition occurred, 0 + * otherwise + */ +int url_close(URLContext *h); + +/** + * Returns a non-zero value if the resource indicated by url + * exists, 0 otherwise. + */ +int url_exist(const char *url); + +int64_t url_filesize(URLContext *h); + +/** + * Return the file descriptor associated with this URL. For RTP, this + * will return only the RTP file descriptor, not the RTCP file descriptor. + * To get both, use rtp_get_file_handles(). + * + * @return the file descriptor associated with this URL, or <0 on error. + */ +int url_get_file_handle(URLContext *h); + +/** + * Return the maximum packet size associated to packetized file + * handle. If the file is not packetized (stream like HTTP or file on + * disk), then 0 is returned. + * + * @param h file handle + * @return maximum packet size in bytes + */ +int url_get_max_packet_size(URLContext *h); +void url_get_filename(URLContext *h, char *buf, int buf_size); + +/** + * The callback is called in blocking functions to test regulary if + * asynchronous interruption is needed. AVERROR(EINTR) is returned + * in this case by the interrupted function. 'NULL' means no interrupt + * callback is given. + */ +void url_set_interrupt_cb(URLInterruptCB *interrupt_cb); + +/* not implemented */ +int url_poll(URLPollEntry *poll_table, int n, int timeout); + +/** + * Pause and resume playing - only meaningful if using a network streaming + * protocol (e.g. MMS). + * @param pause 1 for pause, 0 for resume + */ +int av_url_read_pause(URLContext *h, int pause); + +/** + * Seek to a given timestamp relative to some component stream. + * Only meaningful if using a network streaming protocol (e.g. MMS.). + * @param stream_index The stream index that the timestamp is relative to. + * If stream_index is (-1) the timestamp should be in AV_TIME_BASE + * units from the beginning of the presentation. + * If a stream_index >= 0 is used and the protocol does not support + * seeking based on component streams, the call will fail with ENOTSUP. + * @param timestamp timestamp in AVStream.time_base units + * or if there is no stream specified then in AV_TIME_BASE units. + * @param flags Optional combination of AVSEEK_FLAG_BACKWARD, AVSEEK_FLAG_BYTE + * and AVSEEK_FLAG_ANY. The protocol may silently ignore + * AVSEEK_FLAG_BACKWARD and AVSEEK_FLAG_ANY, but AVSEEK_FLAG_BYTE will + * fail with ENOTSUP if used and not supported. + * @return >= 0 on success + * @see AVInputFormat::read_seek + */ +int64_t av_url_read_seek(URLContext *h, int stream_index, + int64_t timestamp, int flags); + +/** + * Passing this as the "whence" parameter to a seek function causes it to + * return the filesize without seeking anywhere. Supporting this is optional. + * If it is not supported then the seek function will return <0. + */ +#define AVSEEK_SIZE 0x10000 + +/** + * Oring this flag as into the "whence" parameter to a seek function causes it to + * seek by any means (like reopening and linear reading) or other normally unreasonble + * means that can be extreemly slow. + * This may be ignored by the seek code. + */ +#define AVSEEK_FORCE 0x20000 + +typedef struct URLProtocol { + const char *name; + int (*url_open)(URLContext *h, const char *url, int flags); + int (*url_read)(URLContext *h, unsigned char *buf, int size); + int (*url_write)(URLContext *h, unsigned char *buf, int size); + int64_t (*url_seek)(URLContext *h, int64_t pos, int whence); + int (*url_close)(URLContext *h); + struct URLProtocol *next; + int (*url_read_pause)(URLContext *h, int pause); + int64_t (*url_read_seek)(URLContext *h, int stream_index, + int64_t timestamp, int flags); + int (*url_get_file_handle)(URLContext *h); +} URLProtocol; + +#if LIBAVFORMAT_VERSION_MAJOR < 53 +extern URLProtocol *first_protocol; +#endif + +extern URLInterruptCB *url_interrupt_cb; + +/** + * If protocol is NULL, returns the first registered protocol, + * if protocol is non-NULL, returns the next registered protocol after protocol, + * or NULL if protocol is the last one. + */ +URLProtocol *av_protocol_next(URLProtocol *p); + +#if LIBAVFORMAT_VERSION_MAJOR < 53 +/** + * @deprecated Use av_register_protocol() instead. + */ +attribute_deprecated int register_protocol(URLProtocol *protocol); +#endif + +/** + * Registers the URLProtocol protocol. + */ +int av_register_protocol(URLProtocol *protocol); + +/** + * Bytestream IO Context. + * New fields can be added to the end with minor version bumps. + * Removal, reordering and changes to existing fields require a major + * version bump. + * sizeof(ByteIOContext) must not be used outside libav*. + */ +typedef struct { + unsigned char *buffer; + int buffer_size; + unsigned char *buf_ptr, *buf_end; + void *opaque; + int (*read_packet)(void *opaque, uint8_t *buf, int buf_size); + int (*write_packet)(void *opaque, uint8_t *buf, int buf_size); + int64_t (*seek)(void *opaque, int64_t offset, int whence); + int64_t pos; /**< position in the file of the current buffer */ + int must_flush; /**< true if the next seek should flush */ + int eof_reached; /**< true if eof reached */ + int write_flag; /**< true if open for writing */ + int is_streamed; + int max_packet_size; + unsigned long checksum; + unsigned char *checksum_ptr; + unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size); + int error; ///< contains the error code or 0 if no error happened + int (*read_pause)(void *opaque, int pause); + int64_t (*read_seek)(void *opaque, int stream_index, + int64_t timestamp, int flags); +} ByteIOContext; + +int init_put_byte(ByteIOContext *s, + unsigned char *buffer, + int buffer_size, + int write_flag, + void *opaque, + int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), + int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), + int64_t (*seek)(void *opaque, int64_t offset, int whence)); +ByteIOContext *av_alloc_put_byte( + unsigned char *buffer, + int buffer_size, + int write_flag, + void *opaque, + int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), + int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), + int64_t (*seek)(void *opaque, int64_t offset, int whence)); + +void put_byte(ByteIOContext *s, int b); +void put_buffer(ByteIOContext *s, const unsigned char *buf, int size); +void put_le64(ByteIOContext *s, uint64_t val); +void put_be64(ByteIOContext *s, uint64_t val); +void put_le32(ByteIOContext *s, unsigned int val); +void put_be32(ByteIOContext *s, unsigned int val); +void put_le24(ByteIOContext *s, unsigned int val); +void put_be24(ByteIOContext *s, unsigned int val); +void put_le16(ByteIOContext *s, unsigned int val); +void put_be16(ByteIOContext *s, unsigned int val); +void put_tag(ByteIOContext *s, const char *tag); + +void put_strz(ByteIOContext *s, const char *buf); + +/** + * fseek() equivalent for ByteIOContext. + * @return new position or AVERROR. + */ +int64_t url_fseek(ByteIOContext *s, int64_t offset, int whence); + +/** + * Skip given number of bytes forward. + * @param offset number of bytes + */ +void url_fskip(ByteIOContext *s, int64_t offset); + +/** + * ftell() equivalent for ByteIOContext. + * @return position or AVERROR. + */ +int64_t url_ftell(ByteIOContext *s); + +/** + * Gets the filesize. + * @return filesize or AVERROR + */ +int64_t url_fsize(ByteIOContext *s); + +/** + * feof() equivalent for ByteIOContext. + * @return non zero if and only if end of file + */ +int url_feof(ByteIOContext *s); + +int url_ferror(ByteIOContext *s); + +int av_url_read_fpause(ByteIOContext *h, int pause); +int64_t av_url_read_fseek(ByteIOContext *h, int stream_index, + int64_t timestamp, int flags); + +#define URL_EOF (-1) +/** @note return URL_EOF (-1) if EOF */ +int url_fgetc(ByteIOContext *s); + +/** @warning currently size is limited */ +#ifdef __GNUC__ +int url_fprintf(ByteIOContext *s, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 2, 3))); +#else +int url_fprintf(ByteIOContext *s, const char *fmt, ...); +#endif + +/** @note unlike fgets, the EOL character is not returned and a whole + line is parsed. return NULL if first char read was EOF */ +char *url_fgets(ByteIOContext *s, char *buf, int buf_size); + +void put_flush_packet(ByteIOContext *s); + + +/** + * Reads size bytes from ByteIOContext into buf. + * @return number of bytes read or AVERROR + */ +int get_buffer(ByteIOContext *s, unsigned char *buf, int size); + +/** + * Reads size bytes from ByteIOContext into buf. + * This reads at most 1 packet. If that is not enough fewer bytes will be + * returned. + * @return number of bytes read or AVERROR + */ +int get_partial_buffer(ByteIOContext *s, unsigned char *buf, int size); + +/** @note return 0 if EOF, so you cannot use it if EOF handling is + necessary */ +int get_byte(ByteIOContext *s); +unsigned int get_le24(ByteIOContext *s); +unsigned int get_le32(ByteIOContext *s); +uint64_t get_le64(ByteIOContext *s); +unsigned int get_le16(ByteIOContext *s); + +char *get_strz(ByteIOContext *s, char *buf, int maxlen); +unsigned int get_be16(ByteIOContext *s); +unsigned int get_be24(ByteIOContext *s); +unsigned int get_be32(ByteIOContext *s); +uint64_t get_be64(ByteIOContext *s); + +uint64_t ff_get_v(ByteIOContext *bc); + +static inline int url_is_streamed(ByteIOContext *s) +{ + return s->is_streamed; +} + +/** + * Creates and initializes a ByteIOContext for accessing the + * resource referenced by the URLContext h. + * @note When the URLContext h has been opened in read+write mode, the + * ByteIOContext can be used only for writing. + * + * @param s Used to return the pointer to the created ByteIOContext. + * In case of failure the pointed to value is set to NULL. + * @return 0 in case of success, a negative value corresponding to an + * AVERROR code in case of failure + */ +int url_fdopen(ByteIOContext **s, URLContext *h); + +/** @warning must be called before any I/O */ +int url_setbufsize(ByteIOContext *s, int buf_size); +#if LIBAVFORMAT_VERSION_MAJOR < 53 +/** Reset the buffer for reading or writing. + * @note Will drop any data currently in the buffer without transmitting it. + * @param flags URL_RDONLY to set up the buffer for reading, or URL_WRONLY + * to set up the buffer for writing. */ +int url_resetbuf(ByteIOContext *s, int flags); +#endif + +/** + * Rewinds the ByteIOContext using the specified buffer containing the first buf_size bytes of the file. + * Used after probing to avoid seeking. + * Joins buf and s->buffer, taking any overlap into consideration. + * @note s->buffer must overlap with buf or they can't be joined and the function fails + * @note This function is NOT part of the public API + * + * @param s The read-only ByteIOContext to rewind + * @param buf The probe buffer containing the first buf_size bytes of the file + * @param buf_size The size of buf + * @return 0 in case of success, a negative value corresponding to an + * AVERROR code in case of failure + */ +int ff_rewind_with_probe_data(ByteIOContext *s, unsigned char *buf, int buf_size); + +/** + * Creates and initializes a ByteIOContext for accessing the + * resource indicated by url. + * @note When the resource indicated by url has been opened in + * read+write mode, the ByteIOContext can be used only for writing. + * + * @param s Used to return the pointer to the created ByteIOContext. + * In case of failure the pointed to value is set to NULL. + * @param flags flags which control how the resource indicated by url + * is to be opened + * @return 0 in case of success, a negative value corresponding to an + * AVERROR code in case of failure + */ +int url_fopen(ByteIOContext **s, const char *url, int flags); + +int url_fclose(ByteIOContext *s); +URLContext *url_fileno(ByteIOContext *s); + +/** + * Return the maximum packet size associated to packetized buffered file + * handle. If the file is not packetized (stream like http or file on + * disk), then 0 is returned. + * + * @param s buffered file handle + * @return maximum packet size in bytes + */ +int url_fget_max_packet_size(ByteIOContext *s); + +int url_open_buf(ByteIOContext **s, uint8_t *buf, int buf_size, int flags); + +/** return the written or read size */ +int url_close_buf(ByteIOContext *s); + +/** + * Open a write only memory stream. + * + * @param s new IO context + * @return zero if no error. + */ +int url_open_dyn_buf(ByteIOContext **s); + +/** + * Open a write only packetized memory stream with a maximum packet + * size of 'max_packet_size'. The stream is stored in a memory buffer + * with a big endian 4 byte header giving the packet size in bytes. + * + * @param s new IO context + * @param max_packet_size maximum packet size (must be > 0) + * @return zero if no error. + */ +int url_open_dyn_packet_buf(ByteIOContext **s, int max_packet_size); + +/** + * Return the written size and a pointer to the buffer. The buffer + * must be freed with av_free(). + * @param s IO context + * @param pbuffer pointer to a byte buffer + * @return the length of the byte buffer + */ +int url_close_dyn_buf(ByteIOContext *s, uint8_t **pbuffer); + +unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf, + unsigned int len); +unsigned long get_checksum(ByteIOContext *s); +void init_checksum(ByteIOContext *s, + unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len), + unsigned long checksum); + +/* udp.c */ +int udp_set_remote_url(URLContext *h, const char *uri); +int udp_get_local_port(URLContext *h); +#if (LIBAVFORMAT_VERSION_MAJOR <= 52) +int udp_get_file_handle(URLContext *h); +#endif + +#endif /* AVFORMAT_AVIO_H */ diff --git a/extra_lib/include/ffmpeg_android/libavutil/attributes.h b/extra_lib/include/ffmpeg_android/libavutil/attributes.h new file mode 100644 index 0000000..1208bc0 --- /dev/null +++ b/extra_lib/include/ffmpeg_android/libavutil/attributes.h @@ -0,0 +1,113 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg 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.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file libavutil/attributes.h + * Macro definitions for various function/variable attributes + */ + +#ifndef AVUTIL_ATTRIBUTES_H +#define AVUTIL_ATTRIBUTES_H + +#ifdef __GNUC__ +# define AV_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > x || __GNUC__ == x && __GNUC_MINOR__ >= y) +#else +# define AV_GCC_VERSION_AT_LEAST(x,y) 0 +#endif + +#ifndef av_always_inline +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define av_always_inline __attribute__((always_inline)) inline +#else +# define av_always_inline inline +#endif +#endif + +#ifndef av_noinline +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define av_noinline __attribute__((noinline)) +#else +# define av_noinline +#endif +#endif + +#ifndef av_pure +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define av_pure __attribute__((pure)) +#else +# define av_pure +#endif +#endif + +#ifndef av_const +#if AV_GCC_VERSION_AT_LEAST(2,6) +# define av_const __attribute__((const)) +#else +# define av_const +#endif +#endif + +#ifndef av_cold +#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(4,3) +# define av_cold __attribute__((cold)) +#else +# define av_cold +#endif +#endif + +#ifndef av_flatten +#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(4,1) +# define av_flatten __attribute__((flatten)) +#else +# define av_flatten +#endif +#endif + +#ifndef attribute_deprecated +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define attribute_deprecated __attribute__((deprecated)) +#else +# define attribute_deprecated +#endif +#endif + +#ifndef av_unused +#if defined(__GNUC__) +# define av_unused __attribute__((unused)) +#else +# define av_unused +#endif +#endif + +#ifndef av_uninit +#if defined(__GNUC__) && !defined(__ICC) +# define av_uninit(x) x=x +#else +# define av_uninit(x) x +#endif +#endif + +#ifdef __GNUC__ +# define av_builtin_constant_p __builtin_constant_p +#else +# define av_builtin_constant_p(x) 0 +#endif + +#endif /* AVUTIL_ATTRIBUTES_H */ diff --git a/extra_lib/include/ffmpeg_android/libavutil/avconfig.h b/extra_lib/include/ffmpeg_android/libavutil/avconfig.h new file mode 100644 index 0000000..b028bb4 --- /dev/null +++ b/extra_lib/include/ffmpeg_android/libavutil/avconfig.h @@ -0,0 +1,5 @@ +/* Generated by ffconf */ +#ifndef AVUTIL_AVCONFIG_H +#define AVUTIL_AVCONFIG_H +#define AV_HAVE_BIGENDIAN 0 +#endif /* AVUTIL_AVCONFIG_H */ diff --git a/extra_lib/include/ffmpeg_android/libavutil/avutil.h b/extra_lib/include/ffmpeg_android/libavutil/avutil.h new file mode 100644 index 0000000..1523de6 --- /dev/null +++ b/extra_lib/include/ffmpeg_android/libavutil/avutil.h @@ -0,0 +1,89 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg 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.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_AVUTIL_H +#define AVUTIL_AVUTIL_H + +/** + * @file libavutil/avutil.h + * external API header + */ + + +#define AV_STRINGIFY(s) AV_TOSTRING(s) +#define AV_TOSTRING(s) #s + +#define AV_GLUE(a, b) a ## b +#define AV_JOIN(a, b) AV_GLUE(a, b) + +#define AV_PRAGMA(s) _Pragma(#s) + +#define AV_VERSION_INT(a, b, c) (a<<16 | b<<8 | c) +#define AV_VERSION_DOT(a, b, c) a ##.## b ##.## c +#define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) + +#define LIBAVUTIL_VERSION_MAJOR 50 +#define LIBAVUTIL_VERSION_MINOR 14 +#define LIBAVUTIL_VERSION_MICRO 0 + +#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ + LIBAVUTIL_VERSION_MINOR, \ + LIBAVUTIL_VERSION_MICRO) +#define LIBAVUTIL_VERSION AV_VERSION(LIBAVUTIL_VERSION_MAJOR, \ + LIBAVUTIL_VERSION_MINOR, \ + LIBAVUTIL_VERSION_MICRO) +#define LIBAVUTIL_BUILD LIBAVUTIL_VERSION_INT + +#define LIBAVUTIL_IDENT "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION) + +/** + * Returns the LIBAVUTIL_VERSION_INT constant. + */ +unsigned avutil_version(void); + +/** + * Returns the libavutil build-time configuration. + */ +const char *avutil_configuration(void); + +/** + * Returns the libavutil license. + */ +const char *avutil_license(void); + +enum AVMediaType { + AVMEDIA_TYPE_UNKNOWN = -1, + AVMEDIA_TYPE_VIDEO, + AVMEDIA_TYPE_AUDIO, + AVMEDIA_TYPE_DATA, + AVMEDIA_TYPE_SUBTITLE, + AVMEDIA_TYPE_ATTACHMENT, + AVMEDIA_TYPE_NB +}; + +#include "common.h" +#include "error.h" +#include "mathematics.h" +#include "rational.h" +#include "intfloat_readwrite.h" +#include "log.h" +#include "pixfmt.h" + +#endif /* AVUTIL_AVUTIL_H */ diff --git a/extra_lib/include/ffmpeg_android/libavutil/common.h b/extra_lib/include/ffmpeg_android/libavutil/common.h new file mode 100644 index 0000000..fae0b5b --- /dev/null +++ b/extra_lib/include/ffmpeg_android/libavutil/common.h @@ -0,0 +1,297 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg 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.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file libavutil/common.h + * common internal and external API header + */ + +#ifndef AVUTIL_COMMON_H +#define AVUTIL_COMMON_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "attributes.h" + +//rounded division & shift +#define RSHIFT(a,b) ((a) > 0 ? ((a) + ((1<<(b))>>1))>>(b) : ((a) + ((1<<(b))>>1)-1)>>(b)) +/* assume b>0 */ +#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) +#define FFABS(a) ((a) >= 0 ? (a) : (-(a))) +#define FFSIGN(a) ((a) > 0 ? 1 : -1) + +#define FFMAX(a,b) ((a) > (b) ? (a) : (b)) +#define FFMAX3(a,b,c) FFMAX(FFMAX(a,b),c) +#define FFMIN(a,b) ((a) > (b) ? (b) : (a)) +#define FFMIN3(a,b,c) FFMIN(FFMIN(a,b),c) + +#define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0) +#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) +#define FFALIGN(x, a) (((x)+(a)-1)&~((a)-1)) + +/* misc math functions */ +extern const uint8_t ff_log2_tab[256]; + +extern const uint8_t av_reverse[256]; + +static inline av_const int av_log2_c(unsigned int v) +{ + int n = 0; + if (v & 0xffff0000) { + v >>= 16; + n += 16; + } + if (v & 0xff00) { + v >>= 8; + n += 8; + } + n += ff_log2_tab[v]; + + return n; +} + +static inline av_const int av_log2_16bit_c(unsigned int v) +{ + int n = 0; + if (v & 0xff00) { + v >>= 8; + n += 8; + } + n += ff_log2_tab[v]; + + return n; +} + +#ifdef HAVE_AV_CONFIG_H +# include "config.h" +# include "intmath.h" +#endif + +#ifndef av_log2 +# define av_log2 av_log2_c +#endif +#ifndef av_log2_16bit +# define av_log2_16bit av_log2_16bit_c +#endif + +/** + * Clips a signed integer value into the amin-amax range. + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static inline av_const int av_clip(int a, int amin, int amax) +{ + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +/** + * Clips a signed integer value into the 0-255 range. + * @param a value to clip + * @return clipped value + */ +static inline av_const uint8_t av_clip_uint8(int a) +{ + if (a&(~255)) return (-a)>>31; + else return a; +} + +/** + * Clips a signed integer value into the 0-65535 range. + * @param a value to clip + * @return clipped value + */ +static inline av_const uint16_t av_clip_uint16(int a) +{ + if (a&(~65535)) return (-a)>>31; + else return a; +} + +/** + * Clips a signed integer value into the -32768,32767 range. + * @param a value to clip + * @return clipped value + */ +static inline av_const int16_t av_clip_int16(int a) +{ + if ((a+32768) & ~65535) return (a>>31) ^ 32767; + else return a; +} + +/** + * Clips a float value into the amin-amax range. + * @param a value to clip + * @param amin minimum value of the clip range + * @param amax maximum value of the clip range + * @return clipped value + */ +static inline av_const float av_clipf(float a, float amin, float amax) +{ + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +/** Computes ceil(log2(x)). + * @param x value used to compute ceil(log2(x)) + * @return computed ceiling of log2(x) + */ +static inline av_const int av_ceil_log2(int x) +{ + return av_log2((x - 1) << 1); +} + +#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24)) +#define MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24)) + +/*! + * \def GET_UTF8(val, GET_BYTE, ERROR) + * Converts a UTF-8 character (up to 4 bytes long) to its 32-bit UCS-4 encoded form + * \param val is the output and should be of type uint32_t. It holds the converted + * UCS-4 character and should be a left value. + * \param GET_BYTE gets UTF-8 encoded bytes from any proper source. It can be + * a function or a statement whose return value or evaluated value is of type + * uint8_t. It will be executed up to 4 times for values in the valid UTF-8 range, + * and up to 7 times in the general case. + * \param ERROR action that should be taken when an invalid UTF-8 byte is returned + * from GET_BYTE. It should be a statement that jumps out of the macro, + * like exit(), goto, return, break, or continue. + */ +#define GET_UTF8(val, GET_BYTE, ERROR)\ + val= GET_BYTE;\ + {\ + int ones= 7 - av_log2(val ^ 255);\ + if(ones==1)\ + ERROR\ + val&= 127>>ones;\ + while(--ones > 0){\ + int tmp= GET_BYTE - 128;\ + if(tmp>>6)\ + ERROR\ + val= (val<<6) + tmp;\ + }\ + } + +/*! + * \def GET_UTF16(val, GET_16BIT, ERROR) + * Converts a UTF-16 character (2 or 4 bytes) to its 32-bit UCS-4 encoded form + * \param val is the output and should be of type uint32_t. It holds the converted + * UCS-4 character and should be a left value. + * \param GET_16BIT gets two bytes of UTF-16 encoded data converted to native endianness. + * It can be a function or a statement whose return value or evaluated value is of type + * uint16_t. It will be executed up to 2 times. + * \param ERROR action that should be taken when an invalid UTF-16 surrogate is + * returned from GET_BYTE. It should be a statement that jumps out of the macro, + * like exit(), goto, return, break, or continue. + */ +#define GET_UTF16(val, GET_16BIT, ERROR)\ + val = GET_16BIT;\ + {\ + unsigned int hi = val - 0xD800;\ + if (hi < 0x800) {\ + val = GET_16BIT - 0xDC00;\ + if (val > 0x3FFU || hi > 0x3FFU)\ + ERROR\ + val += (hi<<10) + 0x10000;\ + }\ + }\ + +/*! + * \def PUT_UTF8(val, tmp, PUT_BYTE) + * Converts a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes long). + * \param val is an input-only argument and should be of type uint32_t. It holds + * a UCS-4 encoded Unicode character that is to be converted to UTF-8. If + * val is given as a function it is executed only once. + * \param tmp is a temporary variable and should be of type uint8_t. It + * represents an intermediate value during conversion that is to be + * output by PUT_BYTE. + * \param PUT_BYTE writes the converted UTF-8 bytes to any proper destination. + * It could be a function or a statement, and uses tmp as the input byte. + * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be + * executed up to 4 times for values in the valid UTF-8 range and up to + * 7 times in the general case, depending on the length of the converted + * Unicode character. + */ +#define PUT_UTF8(val, tmp, PUT_BYTE)\ + {\ + int bytes, shift;\ + uint32_t in = val;\ + if (in < 0x80) {\ + tmp = in;\ + PUT_BYTE\ + } else {\ + bytes = (av_log2(in) + 4) / 5;\ + shift = (bytes - 1) * 6;\ + tmp = (256 - (256 >> bytes)) | (in >> shift);\ + PUT_BYTE\ + while (shift >= 6) {\ + shift -= 6;\ + tmp = 0x80 | ((in >> shift) & 0x3f);\ + PUT_BYTE\ + }\ + }\ + } + +/*! + * \def PUT_UTF16(val, tmp, PUT_16BIT) + * Converts a 32-bit Unicode character to its UTF-16 encoded form (2 or 4 bytes). + * \param val is an input-only argument and should be of type uint32_t. It holds + * a UCS-4 encoded Unicode character that is to be converted to UTF-16. If + * val is given as a function it is executed only once. + * \param tmp is a temporary variable and should be of type uint16_t. It + * represents an intermediate value during conversion that is to be + * output by PUT_16BIT. + * \param PUT_16BIT writes the converted UTF-16 data to any proper destination + * in desired endianness. It could be a function or a statement, and uses tmp + * as the input byte. For example, PUT_BYTE could be "*output++ = tmp;" + * PUT_BYTE will be executed 1 or 2 times depending on input character. + */ +#define PUT_UTF16(val, tmp, PUT_16BIT)\ + {\ + uint32_t in = val;\ + if (in < 0x10000) {\ + tmp = in;\ + PUT_16BIT\ + } else {\ + tmp = 0xD800 | ((in - 0x10000) >> 10);\ + PUT_16BIT\ + tmp = 0xDC00 | ((in - 0x10000) & 0x3FF);\ + PUT_16BIT\ + }\ + }\ + + + +#include "mem.h" + +#ifdef HAVE_AV_CONFIG_H +# include "internal.h" +#endif /* HAVE_AV_CONFIG_H */ + +#endif /* AVUTIL_COMMON_H */ diff --git a/extra_lib/include/ffmpeg_android/libavutil/error.h b/extra_lib/include/ffmpeg_android/libavutil/error.h new file mode 100644 index 0000000..c757981 --- /dev/null +++ b/extra_lib/include/ffmpeg_android/libavutil/error.h @@ -0,0 +1,70 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg 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.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file libavutil/error.h + * error code definitions + */ + +#ifndef AVUTIL_ERROR_H +#define AVUTIL_ERROR_H + +#include +#include "avutil.h" + +/* error handling */ +#if EDOM > 0 +#define AVERROR(e) (-(e)) ///< Returns a negative error code from a POSIX error code, to return from library functions. +#define AVUNERROR(e) (-(e)) ///< Returns a POSIX error code from a library function error return value. +#else +/* Some platforms have E* and errno already negated. */ +#define AVERROR(e) (e) +#define AVUNERROR(e) (e) +#endif + +#if LIBAVUTIL_VERSION_MAJOR < 51 +#define AVERROR_INVALIDDATA AVERROR(EINVAL) ///< Invalid data found when processing input +#define AVERROR_IO AVERROR(EIO) ///< I/O error +#define AVERROR_NOENT AVERROR(ENOENT) ///< No such file or directory +#define AVERROR_NOFMT AVERROR(EILSEQ) ///< Unknown format +#define AVERROR_NOMEM AVERROR(ENOMEM) ///< Not enough memory +#define AVERROR_NUMEXPECTED AVERROR(EDOM) ///< Number syntax expected in filename +#define AVERROR_UNKNOWN AVERROR(EINVAL) ///< Unknown error +#endif + +#define AVERROR_EOF AVERROR(EPIPE) ///< End of file +#define AVERROR_NOTSUPP AVERROR(ENOSYS) ///< Operation not supported + +#define AVERROR_PATCHWELCOME (-MKTAG('P','A','W','E')) ///< Not yet implemented in FFmpeg, patches welcome + +#if LIBAVUTIL_VERSION_MAJOR > 50 +#define AVERROR_INVALIDDATA (-MKTAG('I','N','D','A')) ///< Invalid data found when processing input +#define AVERROR_NUMEXPECTED (-MKTAG('N','U','E','X')) ///< Number syntax expected in filename +#endif + +/** + * Puts a description of the AVERROR code errnum in errbuf. + * In case of failure the global variable errno is set to indicate the + * error. + * + * @param errbuf_size the size in bytes of errbuf + * @return 0 on success, a negative value otherwise + */ +int av_strerror(int errnum, char *errbuf, size_t errbuf_size); + +#endif /* AVUTIL_ERROR_H */ diff --git a/extra_lib/include/ffmpeg_android/libavutil/intfloat_readwrite.h b/extra_lib/include/ffmpeg_android/libavutil/intfloat_readwrite.h new file mode 100644 index 0000000..1b80fc6 --- /dev/null +++ b/extra_lib/include/ffmpeg_android/libavutil/intfloat_readwrite.h @@ -0,0 +1,40 @@ +/* + * copyright (c) 2005 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg 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.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_INTFLOAT_READWRITE_H +#define AVUTIL_INTFLOAT_READWRITE_H + +#include +#include "attributes.h" + +/* IEEE 80 bits extended float */ +typedef struct AVExtFloat { + uint8_t exponent[2]; + uint8_t mantissa[8]; +} AVExtFloat; + +double av_int2dbl(int64_t v) av_const; +float av_int2flt(int32_t v) av_const; +double av_ext2dbl(const AVExtFloat ext) av_const; +int64_t av_dbl2int(double d) av_const; +int32_t av_flt2int(float d) av_const; +AVExtFloat av_dbl2ext(double d) av_const; + +#endif /* AVUTIL_INTFLOAT_READWRITE_H */ diff --git a/extra_lib/include/ffmpeg_android/libavutil/log.h b/extra_lib/include/ffmpeg_android/libavutil/log.h new file mode 100644 index 0000000..b0a1493 --- /dev/null +++ b/extra_lib/include/ffmpeg_android/libavutil/log.h @@ -0,0 +1,115 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg 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.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_LOG_H +#define AVUTIL_LOG_H + +#include +#include "avutil.h" + +/** + * Describes the class of an AVClass context structure. That is an + * arbitrary struct of which the first field is a pointer to an + * AVClass struct (e.g. AVCodecContext, AVFormatContext etc.). + */ +typedef struct { + /** + * The name of the class; usually it is the same name as the + * context structure type to which the AVClass is associated. + */ + const char* class_name; + + /** + * A pointer to a function which returns the name of a context + * instance ctx associated with the class. + */ + const char* (*item_name)(void* ctx); + + /** + * a pointer to the first option specified in the class if any or NULL + * + * @see av_set_default_options() + */ + const struct AVOption *option; +} AVClass; + +/* av_log API */ + +#define AV_LOG_QUIET -8 + +/** + * Something went really wrong and we will crash now. + */ +#define AV_LOG_PANIC 0 + +/** + * Something went wrong and recovery is not possible. + * For example, no header was found for a format which depends + * on headers or an illegal combination of parameters is used. + */ +#define AV_LOG_FATAL 8 + +/** + * Something went wrong and cannot losslessly be recovered. + * However, not all future data is affected. + */ +#define AV_LOG_ERROR 16 + +/** + * Something somehow does not look correct. This may or may not + * lead to problems. An example would be the use of '-vstrict -2'. + */ +#define AV_LOG_WARNING 24 + +#define AV_LOG_INFO 32 +#define AV_LOG_VERBOSE 40 + +/** + * Stuff which is only useful for libav* developers. + */ +#define AV_LOG_DEBUG 48 + +/** + * Sends the specified message to the log if the level is less than or equal + * to the current av_log_level. By default, all logging messages are sent to + * stderr. This behavior can be altered by setting a different av_vlog callback + * function. + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message, lower values signifying + * higher importance. + * @param fmt The format string (printf-compatible) that specifies how + * subsequent arguments are converted to output. + * @see av_vlog + */ +#ifdef __GNUC__ +void av_log(void*, int level, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 3, 4))); +#else +void av_log(void*, int level, const char *fmt, ...); +#endif + +void av_vlog(void*, int level, const char *fmt, va_list); +int av_log_get_level(void); +void av_log_set_level(int); +void av_log_set_callback(void (*)(void*, int, const char*, va_list)); +void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl); + +#endif /* AVUTIL_LOG_H */ diff --git a/extra_lib/include/ffmpeg_android/libavutil/mathematics.h b/extra_lib/include/ffmpeg_android/libavutil/mathematics.h new file mode 100644 index 0000000..e198aef --- /dev/null +++ b/extra_lib/include/ffmpeg_android/libavutil/mathematics.h @@ -0,0 +1,98 @@ +/* + * copyright (c) 2005 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg 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.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_MATHEMATICS_H +#define AVUTIL_MATHEMATICS_H + +#include +#include +#include "attributes.h" +#include "rational.h" + +#ifndef M_E +#define M_E 2.7182818284590452354 /* e */ +#endif +#ifndef M_LN2 +#define M_LN2 0.69314718055994530942 /* log_e 2 */ +#endif +#ifndef M_LN10 +#define M_LN10 2.30258509299404568402 /* log_e 10 */ +#endif +#ifndef M_LOG2_10 +#define M_LOG2_10 3.32192809488736234787 /* log_2 10 */ +#endif +#ifndef M_PI +#define M_PI 3.14159265358979323846 /* pi */ +#endif +#ifndef M_SQRT1_2 +#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ +#endif +#ifndef M_SQRT2 +#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ +#endif +#ifndef NAN +#define NAN (0.0/0.0) +#endif +#ifndef INFINITY +#define INFINITY (1.0/0.0) +#endif + +enum AVRounding { + AV_ROUND_ZERO = 0, ///< Round toward zero. + AV_ROUND_INF = 1, ///< Round away from zero. + AV_ROUND_DOWN = 2, ///< Round toward -infinity. + AV_ROUND_UP = 3, ///< Round toward +infinity. + AV_ROUND_NEAR_INF = 5, ///< Round to nearest and halfway cases away from zero. +}; + +/** + * Returns the greatest common divisor of a and b. + * If both a and b are 0 or either or both are <0 then behavior is + * undefined. + */ +int64_t av_const av_gcd(int64_t a, int64_t b); + +/** + * Rescales a 64-bit integer with rounding to nearest. + * A simple a*b/c isn't possible as it can overflow. + */ +int64_t av_rescale(int64_t a, int64_t b, int64_t c) av_const; + +/** + * Rescales a 64-bit integer with specified rounding. + * A simple a*b/c isn't possible as it can overflow. + */ +int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding) av_const; + +/** + * Rescales a 64-bit integer by 2 rational numbers. + */ +int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const; + +/** + * Compares 2 timestamps each in its own timebases. + * The result of the function is undefined if one of the timestamps + * is outside the int64_t range when represented in the others timebase. + * @return -1 if ts_a is before ts_b, 1 if ts_a is after ts_b or 0 if they represent the same position + */ +int av_compare_ts(int64_t ts_a, AVRational tb_a, int64_t ts_b, AVRational tb_b); + + +#endif /* AVUTIL_MATHEMATICS_H */ diff --git a/extra_lib/include/ffmpeg_android/libavutil/mem.h b/extra_lib/include/ffmpeg_android/libavutil/mem.h new file mode 100644 index 0000000..fffbb87 --- /dev/null +++ b/extra_lib/include/ffmpeg_android/libavutil/mem.h @@ -0,0 +1,125 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg 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.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file libavutil/mem.h + * memory handling functions + */ + +#ifndef AVUTIL_MEM_H +#define AVUTIL_MEM_H + +#include "attributes.h" + +#if defined(__ICC) || defined(__SUNPRO_C) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_CONST(n,t,v) const t __attribute__ ((aligned (n))) v +#elif defined(__TI_COMPILER_VERSION__) + #define DECLARE_ALIGNED(n,t,v) \ + AV_PRAGMA(DATA_ALIGN(v,n)) \ + t __attribute__((aligned(n))) v + #define DECLARE_ASM_CONST(n,t,v) \ + AV_PRAGMA(DATA_ALIGN(v,n)) \ + static const t __attribute__((aligned(n))) v +#elif defined(__GNUC__) + #define DECLARE_ALIGNED(n,t,v) t __attribute__ ((aligned (n))) v + #define DECLARE_ASM_CONST(n,t,v) static const t attribute_used __attribute__ ((aligned (n))) v +#elif defined(_MSC_VER) + #define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v + #define DECLARE_ASM_CONST(n,t,v) __declspec(align(n)) static const t v +#else + #define DECLARE_ALIGNED(n,t,v) t v + #define DECLARE_ASM_CONST(n,t,v) static const t v +#endif + +#if AV_GCC_VERSION_AT_LEAST(3,1) + #define av_malloc_attrib __attribute__((__malloc__)) +#else + #define av_malloc_attrib +#endif + +#if (!defined(__ICC) || __ICC > 1110) && AV_GCC_VERSION_AT_LEAST(4,3) + #define av_alloc_size(n) __attribute__((alloc_size(n))) +#else + #define av_alloc_size(n) +#endif + +/** + * Allocates a block of size bytes with alignment suitable for all + * memory accesses (including vectors if available on the CPU). + * @param size Size in bytes for the memory block to be allocated. + * @return Pointer to the allocated block, NULL if the block cannot + * be allocated. + * @see av_mallocz() + */ +void *av_malloc(unsigned int size) av_malloc_attrib av_alloc_size(1); + +/** + * Allocates or reallocates a block of memory. + * If ptr is NULL and size > 0, allocates a new block. If + * size is zero, frees the memory block pointed to by ptr. + * @param size Size in bytes for the memory block to be allocated or + * reallocated. + * @param ptr Pointer to a memory block already allocated with + * av_malloc(z)() or av_realloc() or NULL. + * @return Pointer to a newly reallocated block or NULL if the block + * cannot be reallocated or the function is used to free the memory block. + * @see av_fast_realloc() + */ +void *av_realloc(void *ptr, unsigned int size) av_alloc_size(2); + +/** + * Frees a memory block which has been allocated with av_malloc(z)() or + * av_realloc(). + * @param ptr Pointer to the memory block which should be freed. + * @note ptr = NULL is explicitly allowed. + * @note It is recommended that you use av_freep() instead. + * @see av_freep() + */ +void av_free(void *ptr); + +/** + * Allocates a block of size bytes with alignment suitable for all + * memory accesses (including vectors if available on the CPU) and + * zeroes all the bytes of the block. + * @param size Size in bytes for the memory block to be allocated. + * @return Pointer to the allocated block, NULL if it cannot be allocated. + * @see av_malloc() + */ +void *av_mallocz(unsigned int size) av_malloc_attrib av_alloc_size(1); + +/** + * Duplicates the string s. + * @param s string to be duplicated + * @return Pointer to a newly allocated string containing a + * copy of s or NULL if the string cannot be allocated. + */ +char *av_strdup(const char *s) av_malloc_attrib; + +/** + * Frees a memory block which has been allocated with av_malloc(z)() or + * av_realloc() and set the pointer pointing to it to NULL. + * @param ptr Pointer to the pointer to the memory block which should + * be freed. + * @see av_free() + */ +void av_freep(void *ptr); + +#endif /* AVUTIL_MEM_H */ diff --git a/extra_lib/include/ffmpeg_android/libavutil/pixfmt.h b/extra_lib/include/ffmpeg_android/libavutil/pixfmt.h new file mode 100644 index 0000000..9118d3d --- /dev/null +++ b/extra_lib/include/ffmpeg_android/libavutil/pixfmt.h @@ -0,0 +1,162 @@ +/* + * copyright (c) 2006 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg 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.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_PIXFMT_H +#define AVUTIL_PIXFMT_H + +/** + * @file libavutil/pixfmt.h + * pixel format definitions + * + * @warning This file has to be considered an internal but installed + * header, so it should not be directly included in your projects. + */ + +#include "libavutil/avconfig.h" + +/** + * Pixel format. Notes: + * + * PIX_FMT_RGB32 is handled in an endian-specific manner. An RGBA + * color is put together as: + * (A << 24) | (R << 16) | (G << 8) | B + * This is stored as BGRA on little-endian CPU architectures and ARGB on + * big-endian CPUs. + * + * When the pixel format is palettized RGB (PIX_FMT_PAL8), the palettized + * image data is stored in AVFrame.data[0]. The palette is transported in + * AVFrame.data[1], is 1024 bytes long (256 4-byte entries) and is + * formatted the same as in PIX_FMT_RGB32 described above (i.e., it is + * also endian-specific). Note also that the individual RGB palette + * components stored in AVFrame.data[1] should be in the range 0..255. + * This is important as many custom PAL8 video codecs that were designed + * to run on the IBM VGA graphics adapter use 6-bit palette components. + * + * For all the 8bit per pixel formats, an RGB32 palette is in data[1] like + * for pal8. This palette is filled in automatically by the function + * allocating the picture. + * + * Note, make sure that all newly added big endian formats have pix_fmt&1==1 + * and that all newly added little endian formats have pix_fmt&1==0 + * this allows simpler detection of big vs little endian. + */ +enum PixelFormat { + PIX_FMT_NONE= -1, + PIX_FMT_YUV420P, ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples) + PIX_FMT_YUYV422, ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr + PIX_FMT_RGB24, ///< packed RGB 8:8:8, 24bpp, RGBRGB... + PIX_FMT_BGR24, ///< packed RGB 8:8:8, 24bpp, BGRBGR... + PIX_FMT_YUV422P, ///< planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples) + PIX_FMT_YUV444P, ///< planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples) + PIX_FMT_YUV410P, ///< planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples) + PIX_FMT_YUV411P, ///< planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) + PIX_FMT_GRAY8, ///< Y , 8bpp + PIX_FMT_MONOWHITE, ///< Y , 1bpp, 0 is white, 1 is black + PIX_FMT_MONOBLACK, ///< Y , 1bpp, 0 is black, 1 is white + PIX_FMT_PAL8, ///< 8 bit with PIX_FMT_RGB32 palette + PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG) + PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG) + PIX_FMT_YUVJ444P, ///< planar YUV 4:4:4, 24bpp, full scale (JPEG) + PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing + PIX_FMT_XVMC_MPEG2_IDCT, + PIX_FMT_UYVY422, ///< packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1 + PIX_FMT_UYYVYY411, ///< packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3 + PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb) + PIX_FMT_BGR4, ///< packed RGB 1:2:1, 4bpp, (msb)1B 2G 1R(lsb) + PIX_FMT_BGR4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb) + PIX_FMT_RGB8, ///< packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb) + PIX_FMT_RGB4, ///< packed RGB 1:2:1, 4bpp, (msb)1R 2G 1B(lsb) + PIX_FMT_RGB4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb) + PIX_FMT_NV12, ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 for UV + PIX_FMT_NV21, ///< as above, but U and V bytes are swapped + + PIX_FMT_ARGB, ///< packed ARGB 8:8:8:8, 32bpp, ARGBARGB... + PIX_FMT_RGBA, ///< packed RGBA 8:8:8:8, 32bpp, RGBARGBA... + PIX_FMT_ABGR, ///< packed ABGR 8:8:8:8, 32bpp, ABGRABGR... + PIX_FMT_BGRA, ///< packed BGRA 8:8:8:8, 32bpp, BGRABGRA... + + PIX_FMT_GRAY16BE, ///< Y , 16bpp, big-endian + PIX_FMT_GRAY16LE, ///< Y , 16bpp, little-endian + PIX_FMT_YUV440P, ///< planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples) + PIX_FMT_YUVJ440P, ///< planar YUV 4:4:0 full scale (JPEG) + PIX_FMT_YUVA420P, ///< planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples) + PIX_FMT_VDPAU_H264,///< H.264 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers + PIX_FMT_VDPAU_MPEG1,///< MPEG-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers + PIX_FMT_VDPAU_MPEG2,///< MPEG-2 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers + PIX_FMT_VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers + PIX_FMT_VDPAU_VC1, ///< VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers + PIX_FMT_RGB48BE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, big-endian + PIX_FMT_RGB48LE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, little-endian + + PIX_FMT_RGB565BE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian + PIX_FMT_RGB565LE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), little-endian + PIX_FMT_RGB555BE, ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), big-endian, most significant bit to 0 + PIX_FMT_RGB555LE, ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), little-endian, most significant bit to 0 + + PIX_FMT_BGR565BE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), big-endian + PIX_FMT_BGR565LE, ///< packed BGR 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), little-endian + PIX_FMT_BGR555BE, ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), big-endian, most significant bit to 1 + PIX_FMT_BGR555LE, ///< packed BGR 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), little-endian, most significant bit to 1 + + PIX_FMT_VAAPI_MOCO, ///< HW acceleration through VA API at motion compensation entry-point, Picture.data[3] contains a vaapi_render_state struct which contains macroblocks as well as various fields extracted from headers + PIX_FMT_VAAPI_IDCT, ///< HW acceleration through VA API at IDCT entry-point, Picture.data[3] contains a vaapi_render_state struct which contains fields extracted from headers + PIX_FMT_VAAPI_VLD, ///< HW decoding through VA API, Picture.data[3] contains a vaapi_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers + + PIX_FMT_YUV420P16LE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), little-endian + PIX_FMT_YUV420P16BE, ///< planar YUV 4:2:0, 24bpp, (1 Cr & Cb sample per 2x2 Y samples), big-endian + PIX_FMT_YUV422P16LE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian + PIX_FMT_YUV422P16BE, ///< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), big-endian + PIX_FMT_YUV444P16LE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), little-endian + PIX_FMT_YUV444P16BE, ///< planar YUV 4:4:4, 48bpp, (1 Cr & Cb sample per 1x1 Y samples), big-endian + PIX_FMT_VDPAU_MPEG4, ///< MPEG4 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers + PIX_FMT_DXVA2_VLD, ///< HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer + + PIX_FMT_RGB444BE, ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), big-endian, most significant bits to 0 + PIX_FMT_RGB444LE, ///< packed RGB 4:4:4, 16bpp, (msb)4A 4R 4G 4B(lsb), little-endian, most significant bits to 0 + PIX_FMT_BGR444BE, ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), big-endian, most significant bits to 1 + PIX_FMT_BGR444LE, ///< packed BGR 4:4:4, 16bpp, (msb)4A 4B 4G 4R(lsb), little-endian, most significant bits to 1 + PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions +}; + +#if AV_HAVE_BIGENDIAN +# define PIX_FMT_NE(be, le) PIX_FMT_##be +#else +# define PIX_FMT_NE(be, le) PIX_FMT_##le +#endif + +#define PIX_FMT_RGB32 PIX_FMT_NE(ARGB, BGRA) +#define PIX_FMT_RGB32_1 PIX_FMT_NE(RGBA, ABGR) +#define PIX_FMT_BGR32 PIX_FMT_NE(ABGR, RGBA) +#define PIX_FMT_BGR32_1 PIX_FMT_NE(BGRA, ARGB) + +#define PIX_FMT_GRAY16 PIX_FMT_NE(GRAY16BE, GRAY16LE) +#define PIX_FMT_RGB48 PIX_FMT_NE(RGB48BE, RGB48LE) +#define PIX_FMT_RGB565 PIX_FMT_NE(RGB565BE, RGB565LE) +#define PIX_FMT_RGB555 PIX_FMT_NE(RGB555BE, RGB555LE) +#define PIX_FMT_RGB444 PIX_FMT_NE(RGB444BE, RGB444LE) +#define PIX_FMT_BGR565 PIX_FMT_NE(BGR565BE, BGR565LE) +#define PIX_FMT_BGR555 PIX_FMT_NE(BGR555BE, BGR555LE) +#define PIX_FMT_BGR444 PIX_FMT_NE(BGR444BE, BGR444LE) + +#define PIX_FMT_YUV420P16 PIX_FMT_NE(YUV420P16BE, YUV420P16LE) +#define PIX_FMT_YUV422P16 PIX_FMT_NE(YUV422P16BE, YUV422P16LE) +#define PIX_FMT_YUV444P16 PIX_FMT_NE(YUV444P16BE, YUV444P16LE) + +#endif /* AVUTIL_PIXFMT_H */ diff --git a/extra_lib/include/ffmpeg_android/libavutil/rational.h b/extra_lib/include/ffmpeg_android/libavutil/rational.h new file mode 100644 index 0000000..c5ecf2c --- /dev/null +++ b/extra_lib/include/ffmpeg_android/libavutil/rational.h @@ -0,0 +1,129 @@ +/* + * rational numbers + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg 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.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file libavutil/rational.h + * rational numbers + * @author Michael Niedermayer + */ + +#ifndef AVUTIL_RATIONAL_H +#define AVUTIL_RATIONAL_H + +#include +#include "attributes.h" + +/** + * rational number numerator/denominator + */ +typedef struct AVRational{ + int num; ///< numerator + int den; ///< denominator +} AVRational; + +/** + * Compares two rationals. + * @param a first rational + * @param b second rational + * @return 0 if a==b, 1 if a>b and -1 if a>63)|1; + else return 0; +} + +/** + * Converts rational to double. + * @param a rational to convert + * @return (double) a + */ +static inline double av_q2d(AVRational a){ + return a.num / (double) a.den; +} + +/** + * Reduces a fraction. + * This is useful for framerate calculations. + * @param dst_num destination numerator + * @param dst_den destination denominator + * @param num source numerator + * @param den source denominator + * @param max the maximum allowed for dst_num & dst_den + * @return 1 if exact, 0 otherwise + */ +int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max); + +/** + * Multiplies two rationals. + * @param b first rational + * @param c second rational + * @return b*c + */ +AVRational av_mul_q(AVRational b, AVRational c) av_const; + +/** + * Divides one rational by another. + * @param b first rational + * @param c second rational + * @return b/c + */ +AVRational av_div_q(AVRational b, AVRational c) av_const; + +/** + * Adds two rationals. + * @param b first rational + * @param c second rational + * @return b+c + */ +AVRational av_add_q(AVRational b, AVRational c) av_const; + +/** + * Subtracts one rational from another. + * @param b first rational + * @param c second rational + * @return b-c + */ +AVRational av_sub_q(AVRational b, AVRational c) av_const; + +/** + * Converts a double precision floating point number to a rational. + * @param d double to convert + * @param max the maximum allowed numerator and denominator + * @return (AVRational) d + */ +AVRational av_d2q(double d, int max) av_const; + +/** + * @return 1 if q1 is nearer to q than q2, -1 if q2 is nearer + * than q1, 0 if they have the same distance. + */ +int av_nearer_q(AVRational q, AVRational q1, AVRational q2); + +/** + * Finds the nearest value in q_list to q. + * @param q_list an array of rationals terminated by {0, 0} + * @return the index of the nearest value found in the array + */ +int av_find_nearest_q_idx(AVRational q, const AVRational* q_list); + +#endif /* AVUTIL_RATIONAL_H */ diff --git a/extra_lib/include/ffmpeg_android/libswscale/swscale.h b/extra_lib/include/ffmpeg_android/libswscale/swscale.h new file mode 100644 index 0000000..1e7af3a --- /dev/null +++ b/extra_lib/include/ffmpeg_android/libswscale/swscale.h @@ -0,0 +1,330 @@ +/* + * Copyright (C) 2001-2003 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg 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.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SWSCALE_SWSCALE_H +#define SWSCALE_SWSCALE_H + +/** + * @file + * @brief + * external api for the swscale stuff + */ + +#include "libavutil/avutil.h" + +#define LIBSWSCALE_VERSION_MAJOR 0 +#define LIBSWSCALE_VERSION_MINOR 11 +#define LIBSWSCALE_VERSION_MICRO 0 + +#define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ + LIBSWSCALE_VERSION_MINOR, \ + LIBSWSCALE_VERSION_MICRO) +#define LIBSWSCALE_VERSION AV_VERSION(LIBSWSCALE_VERSION_MAJOR, \ + LIBSWSCALE_VERSION_MINOR, \ + LIBSWSCALE_VERSION_MICRO) +#define LIBSWSCALE_BUILD LIBSWSCALE_VERSION_INT + +#define LIBSWSCALE_IDENT "SwS" AV_STRINGIFY(LIBSWSCALE_VERSION) + +/** + * Returns the LIBSWSCALE_VERSION_INT constant. + */ +unsigned swscale_version(void); + +/** + * Returns the libswscale build-time configuration. + */ +const char *swscale_configuration(void); + +/** + * Returns the libswscale license. + */ +const char *swscale_license(void); + +/* values for the flags, the stuff on the command line is different */ +#define SWS_FAST_BILINEAR 1 +#define SWS_BILINEAR 2 +#define SWS_BICUBIC 4 +#define SWS_X 8 +#define SWS_POINT 0x10 +#define SWS_AREA 0x20 +#define SWS_BICUBLIN 0x40 +#define SWS_GAUSS 0x80 +#define SWS_SINC 0x100 +#define SWS_LANCZOS 0x200 +#define SWS_SPLINE 0x400 + +#define SWS_SRC_V_CHR_DROP_MASK 0x30000 +#define SWS_SRC_V_CHR_DROP_SHIFT 16 + +#define SWS_PARAM_DEFAULT 123456 + +#define SWS_PRINT_INFO 0x1000 + +//the following 3 flags are not completely implemented +//internal chrominace subsampling info +#define SWS_FULL_CHR_H_INT 0x2000 +//input subsampling info +#define SWS_FULL_CHR_H_INP 0x4000 +#define SWS_DIRECT_BGR 0x8000 +#define SWS_ACCURATE_RND 0x40000 +#define SWS_BITEXACT 0x80000 + +#define SWS_CPU_CAPS_MMX 0x80000000 +#define SWS_CPU_CAPS_MMX2 0x20000000 +#define SWS_CPU_CAPS_3DNOW 0x40000000 +#define SWS_CPU_CAPS_ALTIVEC 0x10000000 +#define SWS_CPU_CAPS_BFIN 0x01000000 + +#define SWS_MAX_REDUCE_CUTOFF 0.002 + +#define SWS_CS_ITU709 1 +#define SWS_CS_FCC 4 +#define SWS_CS_ITU601 5 +#define SWS_CS_ITU624 5 +#define SWS_CS_SMPTE170M 5 +#define SWS_CS_SMPTE240M 7 +#define SWS_CS_DEFAULT 5 + +/** + * Returns a pointer to yuv<->rgb coefficients for the given colorspace + * suitable for sws_setColorspaceDetails(). + * + * @param colorspace One of the SWS_CS_* macros. If invalid, + * SWS_CS_DEFAULT is used. + */ +const int *sws_getCoefficients(int colorspace); + + +// when used for filters they must have an odd number of elements +// coeffs cannot be shared between vectors +typedef struct { + double *coeff; ///< pointer to the list of coefficients + int length; ///< number of coefficients in the vector +} SwsVector; + +// vectors can be shared +typedef struct { + SwsVector *lumH; + SwsVector *lumV; + SwsVector *chrH; + SwsVector *chrV; +} SwsFilter; + +struct SwsContext; + +/** + * Returns a positive value if pix_fmt is a supported input format, 0 + * otherwise. + */ +int sws_isSupportedInput(enum PixelFormat pix_fmt); + +/** + * Returns a positive value if pix_fmt is a supported output format, 0 + * otherwise. + */ +int sws_isSupportedOutput(enum PixelFormat pix_fmt); + +/** + * Frees the swscaler context swsContext. + * If swsContext is NULL, then does nothing. + */ +void sws_freeContext(struct SwsContext *swsContext); + +/** + * Allocates and returns a SwsContext. You need it to perform + * scaling/conversion operations using sws_scale(). + * + * @param srcW the width of the source image + * @param srcH the height of the source image + * @param srcFormat the source image format + * @param dstW the width of the destination image + * @param dstH the height of the destination image + * @param dstFormat the destination image format + * @param flags specify which algorithm and options to use for rescaling + * @return a pointer to an allocated context, or NULL in case of error + */ +struct SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, + int dstW, int dstH, enum PixelFormat dstFormat, + int flags, SwsFilter *srcFilter, + SwsFilter *dstFilter, const double *param); + +/** + * Scales the image slice in srcSlice and puts the resulting scaled + * slice in the image in dst. A slice is a sequence of consecutive + * rows in an image. + * + * Slices have to be provided in sequential order, either in + * top-bottom or bottom-top order. If slices are provided in + * non-sequential order the behavior of the function is undefined. + * + * @param context the scaling context previously created with + * sws_getContext() + * @param srcSlice the array containing the pointers to the planes of + * the source slice + * @param srcStride the array containing the strides for each plane of + * the source image + * @param srcSliceY the position in the source image of the slice to + * process, that is the number (counted starting from + * zero) in the image of the first row of the slice + * @param srcSliceH the height of the source slice, that is the number + * of rows in the slice + * @param dst the array containing the pointers to the planes of + * the destination image + * @param dstStride the array containing the strides for each plane of + * the destination image + * @return the height of the output slice + */ +int sws_scale(struct SwsContext *context, const uint8_t* const srcSlice[], const int srcStride[], + int srcSliceY, int srcSliceH, uint8_t* const dst[], const int dstStride[]); +#if LIBSWSCALE_VERSION_MAJOR < 1 +/** + * @deprecated Use sws_scale() instead. + */ +int sws_scale_ordered(struct SwsContext *context, const uint8_t* const src[], + int srcStride[], int srcSliceY, int srcSliceH, + uint8_t* dst[], int dstStride[]) attribute_deprecated; +#endif + +/** + * @param inv_table the yuv2rgb coefficients, normally ff_yuv2rgb_coeffs[x] + * @param fullRange if 1 then the luma range is 0..255 if 0 it is 16..235 + * @return -1 if not supported + */ +int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], + int srcRange, const int table[4], int dstRange, + int brightness, int contrast, int saturation); + +/** + * @return -1 if not supported + */ +int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table, + int *srcRange, int **table, int *dstRange, + int *brightness, int *contrast, int *saturation); + +/** + * Allocates and returns an uninitialized vector with length coefficients. + */ +SwsVector *sws_allocVec(int length); + +/** + * Returns a normalized Gaussian curve used to filter stuff + * quality=3 is high quality, lower is lower quality. + */ +SwsVector *sws_getGaussianVec(double variance, double quality); + +/** + * Allocates and returns a vector with length coefficients, all + * with the same value c. + */ +SwsVector *sws_getConstVec(double c, int length); + +/** + * Allocates and returns a vector with just one coefficient, with + * value 1.0. + */ +SwsVector *sws_getIdentityVec(void); + +/** + * Scales all the coefficients of a by the scalar value. + */ +void sws_scaleVec(SwsVector *a, double scalar); + +/** + * Scales all the coefficients of a so that their sum equals height. + */ +void sws_normalizeVec(SwsVector *a, double height); +void sws_convVec(SwsVector *a, SwsVector *b); +void sws_addVec(SwsVector *a, SwsVector *b); +void sws_subVec(SwsVector *a, SwsVector *b); +void sws_shiftVec(SwsVector *a, int shift); + +/** + * Allocates and returns a clone of the vector a, that is a vector + * with the same coefficients as a. + */ +SwsVector *sws_cloneVec(SwsVector *a); + +#if LIBSWSCALE_VERSION_MAJOR < 1 +/** + * @deprecated Use sws_printVec2() instead. + */ +attribute_deprecated void sws_printVec(SwsVector *a); +#endif + +/** + * Prints with av_log() a textual representation of the vector a + * if log_level <= av_log_level. + */ +void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level); + +void sws_freeVec(SwsVector *a); + +SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur, + float lumaSharpen, float chromaSharpen, + float chromaHShift, float chromaVShift, + int verbose); +void sws_freeFilter(SwsFilter *filter); + +/** + * Checks if context can be reused, otherwise reallocates a new + * one. + * + * If context is NULL, just calls sws_getContext() to get a new + * context. Otherwise, checks if the parameters are the ones already + * saved in context. If that is the case, returns the current + * context. Otherwise, frees context and gets a new context with + * the new parameters. + * + * Be warned that srcFilter and dstFilter are not checked, they + * are assumed to remain the same. + */ +struct SwsContext *sws_getCachedContext(struct SwsContext *context, + int srcW, int srcH, enum PixelFormat srcFormat, + int dstW, int dstH, enum PixelFormat dstFormat, + int flags, SwsFilter *srcFilter, + SwsFilter *dstFilter, const double *param); + +/** + * Converts an 8bit paletted frame into a frame with a color depth of 32-bits. + * + * The output frame will have the same packed format as the palette. + * + * @param src source frame buffer + * @param dst destination frame buffer + * @param num_pixels number of pixels to convert + * @param palette array with [256] entries, which must match color arrangement (RGB or BGR) of src + */ +void sws_convertPalette8ToPacked32(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette); + +/** + * Converts an 8bit paletted frame into a frame with a color depth of 24 bits. + * + * With the palette format "ABCD", the destination frame ends up with the format "ABC". + * + * @param src source frame buffer + * @param dst destination frame buffer + * @param num_pixels number of pixels to convert + * @param palette array with [256] entries, which must match color arrangement (RGB or BGR) of src + */ +void sws_convertPalette8ToPacked24(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette); + + +#endif /* SWSCALE_SWSCALE_H */ diff --git a/extra_lib/include/jpeg/android/jconfig.h b/extra_lib/include/jpeg/android/jconfig.h deleted file mode 100644 index 15a9817..0000000 --- a/extra_lib/include/jpeg/android/jconfig.h +++ /dev/null @@ -1,156 +0,0 @@ -/* android jconfig.h */ -/* - * jconfig.doc - * - * Copyright (C) 1991-1994, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file documents the configuration options that are required to - * customize the JPEG software for a particular system. - * - * The actual configuration options for a particular installation are stored - * in jconfig.h. On many machines, jconfig.h can be generated automatically - * or copied from one of the "canned" jconfig files that we supply. But if - * you need to generate a jconfig.h file by hand, this file tells you how. - * - * DO NOT EDIT THIS FILE --- IT WON'T ACCOMPLISH ANYTHING. - * EDIT A COPY NAMED JCONFIG.H. - */ - - -/* - * These symbols indicate the properties of your machine or compiler. - * #define the symbol if yes, #undef it if no. - */ - -/* Does your compiler support function prototypes? - * (If not, you also need to use ansi2knr, see install.doc) - */ -#define HAVE_PROTOTYPES - -/* Does your compiler support the declaration "unsigned char" ? - * How about "unsigned short" ? - */ -#define HAVE_UNSIGNED_CHAR -#define HAVE_UNSIGNED_SHORT - -/* Define "void" as "char" if your compiler doesn't know about type void. - * NOTE: be sure to define void such that "void *" represents the most general - * pointer type, e.g., that returned by malloc(). - */ -/* #define void char */ - -/* Define "const" as empty if your compiler doesn't know the "const" keyword. - */ -/* #define const */ - -/* Define this if an ordinary "char" type is unsigned. - * If you're not sure, leaving it undefined will work at some cost in speed. - * If you defined HAVE_UNSIGNED_CHAR then the speed difference is minimal. - */ -#undef CHAR_IS_UNSIGNED - -/* Define this if your system has an ANSI-conforming file. - */ -#define HAVE_STDDEF_H - -/* Define this if your system has an ANSI-conforming file. - */ -#define HAVE_STDLIB_H - -/* Define this if your system does not have an ANSI/SysV , - * but does have a BSD-style . - */ -#undef NEED_BSD_STRINGS - -/* Define this if your system does not provide typedef size_t in any of the - * ANSI-standard places (stddef.h, stdlib.h, or stdio.h), but places it in - * instead. - */ -#undef NEED_SYS_TYPES_H - -/* For 80x86 machines, you need to define NEED_FAR_POINTERS, - * unless you are using a large-data memory model or 80386 flat-memory mode. - * On less brain-damaged CPUs this symbol must not be defined. - * (Defining this symbol causes large data structures to be referenced through - * "far" pointers and to be allocated with a special version of malloc.) - */ -#undef NEED_FAR_POINTERS - -/* Define this if your linker needs global names to be unique in less - * than the first 15 characters. - */ -#undef NEED_SHORT_EXTERNAL_NAMES - -/* Although a real ANSI C compiler can deal perfectly well with pointers to - * unspecified structures (see "incomplete types" in the spec), a few pre-ANSI - * and pseudo-ANSI compilers get confused. To keep one of these bozos happy, - * define INCOMPLETE_TYPES_BROKEN. This is not recommended unless you - * actually get "missing structure definition" warnings or errors while - * compiling the JPEG code. - */ -#undef INCOMPLETE_TYPES_BROKEN - - -/* - * The following options affect code selection within the JPEG library, - * but they don't need to be visible to applications using the library. - * To minimize application namespace pollution, the symbols won't be - * defined unless JPEG_INTERNALS has been defined. - */ - -#ifdef JPEG_INTERNALS - -/* Define this if your compiler implements ">>" on signed values as a logical - * (unsigned) shift; leave it undefined if ">>" is a signed (arithmetic) shift, - * which is the normal and rational definition. - */ -#undef RIGHT_SHIFT_IS_UNSIGNED - - -#endif /* JPEG_INTERNALS */ - - -/* - * The remaining options do not affect the JPEG library proper, - * but only the sample applications cjpeg/djpeg (see cjpeg.c, djpeg.c). - * Other applications can ignore these. - */ - -#ifdef JPEG_CJPEG_DJPEG - -/* These defines indicate which image (non-JPEG) file formats are allowed. */ - -#define BMP_SUPPORTED /* BMP image file format */ -#define GIF_SUPPORTED /* GIF image file format */ -#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */ -#undef RLE_SUPPORTED /* Utah RLE image file format */ -#define TARGA_SUPPORTED /* Targa image file format */ - -/* Define this if you want to name both input and output files on the command - * line, rather than using stdout and optionally stdin. You MUST do this if - * your system can't cope with binary I/O to stdin/stdout. See comments at - * head of cjpeg.c or djpeg.c. - */ -#undef TWO_FILE_COMMANDLINE - -/* Define this if your system needs explicit cleanup of temporary files. - * This is crucial under MS-DOS, where the temporary "files" may be areas - * of extended memory; on most other systems it's not as important. - */ -#undef NEED_SIGNAL_CATCHER - -/* By default, we open image files with fopen(...,"rb") or fopen(...,"wb"). - * This is necessary on systems that distinguish text files from binary files, - * and is harmless on most systems that don't. If you have one of the rare - * systems that complains about the "b" spec, define this symbol. - */ -#undef DONT_USE_B_MODE - -/* Define this if you want percent-done progress reports from cjpeg/djpeg. - */ -#undef PROGRESS_REPORT - - -#endif /* JPEG_CJPEG_DJPEG */ diff --git a/extra_lib/include/jpeg/android/jmorecfg.h b/extra_lib/include/jpeg/android/jmorecfg.h deleted file mode 100644 index 236bbcb..0000000 --- a/extra_lib/include/jpeg/android/jmorecfg.h +++ /dev/null @@ -1,387 +0,0 @@ -/* - * jmorecfg.h - * - * Copyright (C) 1991-1997, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file contains additional configuration options that customize the - * JPEG software for special applications or support machine-dependent - * optimizations. Most users will not need to touch this file. - */ - -/* - * Define ANDROID_RGB to enable specific optimizations for Android - * JCS_RGBA_8888 support - * JCS_RGB_565 support - * - */ - -#define ANDROID_RGB - -#ifdef ANDROID_RGB -#define PACK_SHORT_565(r,g,b) ((((r)<<8)&0xf800)|(((g)<<3)&0x7E0)|((b)>>3)) -#define PACK_TWO_PIXELS(l,r) ((r<<16) | l) -#define PACK_NEED_ALIGNMENT(ptr) (((int)(ptr))&3) -#define WRITE_TWO_PIXELS(addr, pixels) do { \ - ((INT16*)(addr))[0] = (pixels); \ - ((INT16*)(addr))[1] = (pixels)>>16; \ - } while(0) -#define WRITE_TWO_ALIGNED_PIXELS(addr, pixels) ((*(INT32*)(addr)) = pixels) -#define DITHER_565_R(r, dither) ((r) + ((dither)&0xFF)) -#define DITHER_565_G(g, dither) ((g) + (((dither)&0xFF)>>1)) -#define DITHER_565_B(b, dither) ((b) + ((dither)&0xFF)) -#endif - -/* - * Define BITS_IN_JSAMPLE as either - * 8 for 8-bit sample values (the usual setting) - * 12 for 12-bit sample values - * Only 8 and 12 are legal data precisions for lossy JPEG according to the - * JPEG standard, and the IJG code does not support anything else! - * We do not support run-time selection of data precision, sorry. - */ - -#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */ - - -/* - * Maximum number of components (color channels) allowed in JPEG image. - * To meet the letter of the JPEG spec, set this to 255. However, darn - * few applications need more than 4 channels (maybe 5 for CMYK + alpha - * mask). We recommend 10 as a reasonable compromise; use 4 if you are - * really short on memory. (Each allowed component costs a hundred or so - * bytes of storage, whether actually used in an image or not.) - */ - -#define MAX_COMPONENTS 10 /* maximum number of image components */ - - -/* - * Basic data types. - * You may need to change these if you have a machine with unusual data - * type sizes; for example, "char" not 8 bits, "short" not 16 bits, - * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits, - * but it had better be at least 16. - */ - -/* Representation of a single sample (pixel element value). - * We frequently allocate large arrays of these, so it's important to keep - * them small. But if you have memory to burn and access to char or short - * arrays is very slow on your hardware, you might want to change these. - */ - -#if BITS_IN_JSAMPLE == 8 -/* JSAMPLE should be the smallest type that will hold the values 0..255. - * You can use a signed char by having GETJSAMPLE mask it with 0xFF. - */ - -#ifdef HAVE_UNSIGNED_CHAR - -typedef unsigned char JSAMPLE; -#define GETJSAMPLE(value) ((int) (value)) - -#else /* not HAVE_UNSIGNED_CHAR */ - -typedef char JSAMPLE; -#ifdef CHAR_IS_UNSIGNED -#define GETJSAMPLE(value) ((int) (value)) -#else -#define GETJSAMPLE(value) ((int) (value) & 0xFF) -#endif /* CHAR_IS_UNSIGNED */ - -#endif /* HAVE_UNSIGNED_CHAR */ - -#define MAXJSAMPLE 255 -#define CENTERJSAMPLE 128 - -#endif /* BITS_IN_JSAMPLE == 8 */ - - -#if BITS_IN_JSAMPLE == 12 -/* JSAMPLE should be the smallest type that will hold the values 0..4095. - * On nearly all machines "short" will do nicely. - */ - -typedef short JSAMPLE; -#define GETJSAMPLE(value) ((int) (value)) - -#define MAXJSAMPLE 4095 -#define CENTERJSAMPLE 2048 - -#endif /* BITS_IN_JSAMPLE == 12 */ - - -/* Representation of a DCT frequency coefficient. - * This should be a signed value of at least 16 bits; "short" is usually OK. - * Again, we allocate large arrays of these, but you can change to int - * if you have memory to burn and "short" is really slow. - */ - -typedef short JCOEF; - - -/* Compressed datastreams are represented as arrays of JOCTET. - * These must be EXACTLY 8 bits wide, at least once they are written to - * external storage. Note that when using the stdio data source/destination - * managers, this is also the data type passed to fread/fwrite. - */ - -#ifdef HAVE_UNSIGNED_CHAR - -typedef unsigned char JOCTET; -#define GETJOCTET(value) (value) - -#else /* not HAVE_UNSIGNED_CHAR */ - -typedef char JOCTET; -#ifdef CHAR_IS_UNSIGNED -#define GETJOCTET(value) (value) -#else -#define GETJOCTET(value) ((value) & 0xFF) -#endif /* CHAR_IS_UNSIGNED */ - -#endif /* HAVE_UNSIGNED_CHAR */ - - -/* These typedefs are used for various table entries and so forth. - * They must be at least as wide as specified; but making them too big - * won't cost a huge amount of memory, so we don't provide special - * extraction code like we did for JSAMPLE. (In other words, these - * typedefs live at a different point on the speed/space tradeoff curve.) - */ - -/* UINT8 must hold at least the values 0..255. */ - -#ifdef HAVE_UNSIGNED_CHAR -typedef unsigned char UINT8; -#else /* not HAVE_UNSIGNED_CHAR */ -#ifdef CHAR_IS_UNSIGNED -typedef char UINT8; -#else /* not CHAR_IS_UNSIGNED */ -typedef short UINT8; -#endif /* CHAR_IS_UNSIGNED */ -#endif /* HAVE_UNSIGNED_CHAR */ - -/* UINT16 must hold at least the values 0..65535. */ - -#ifdef HAVE_UNSIGNED_SHORT -typedef unsigned short UINT16; -#else /* not HAVE_UNSIGNED_SHORT */ -typedef unsigned int UINT16; -#endif /* HAVE_UNSIGNED_SHORT */ - -/* INT16 must hold at least the values -32768..32767. */ - -#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */ -typedef short INT16; -#endif - -/* INT32 must hold at least signed 32-bit values. */ - -#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ -typedef long INT32; -#endif - -/* Datatype used for image dimensions. The JPEG standard only supports - * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore - * "unsigned int" is sufficient on all machines. However, if you need to - * handle larger images and you don't mind deviating from the spec, you - * can change this datatype. - */ - -typedef unsigned int JDIMENSION; - -#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */ - - -/* These macros are used in all function definitions and extern declarations. - * You could modify them if you need to change function linkage conventions; - * in particular, you'll need to do that to make the library a Windows DLL. - * Another application is to make all functions global for use with debuggers - * or code profilers that require it. - */ - -/* a function called through method pointers: */ -#define METHODDEF(type) static type -/* a function used only in its module: */ -#define LOCAL(type) static type -/* a function referenced thru EXTERNs: */ -#define GLOBAL(type) type -/* a reference to a GLOBAL function: */ -#define EXTERN(type) extern type - - -/* This macro is used to declare a "method", that is, a function pointer. - * We want to supply prototype parameters if the compiler can cope. - * Note that the arglist parameter must be parenthesized! - * Again, you can customize this if you need special linkage keywords. - */ - -#ifdef HAVE_PROTOTYPES -#define JMETHOD(type,methodname,arglist) type (*methodname) arglist -#else -#define JMETHOD(type,methodname,arglist) type (*methodname) () -#endif - - -/* Here is the pseudo-keyword for declaring pointers that must be "far" - * on 80x86 machines. Most of the specialized coding for 80x86 is handled - * by just saying "FAR *" where such a pointer is needed. In a few places - * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol. - */ - -#ifdef NEED_FAR_POINTERS -#define FAR far -#else -#define FAR -#endif - - -/* - * On a few systems, type boolean and/or its values FALSE, TRUE may appear - * in standard header files. Or you may have conflicts with application- - * specific header files that you want to include together with these files. - * Defining HAVE_BOOLEAN before including jpeglib.h should make it work. - */ - -#ifndef HAVE_BOOLEAN -typedef int boolean; -#endif -#ifndef FALSE /* in case these macros already exist */ -#define FALSE 0 /* values of boolean */ -#endif -#ifndef TRUE -#define TRUE 1 -#endif - - -/* - * The remaining options affect code selection within the JPEG library, - * but they don't need to be visible to most applications using the library. - * To minimize application namespace pollution, the symbols won't be - * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined. - */ - -#ifdef JPEG_INTERNALS -#define JPEG_INTERNAL_OPTIONS -#endif - -#ifdef JPEG_INTERNAL_OPTIONS - - -/* - * These defines indicate whether to include various optional functions. - * Undefining some of these symbols will produce a smaller but less capable - * library. Note that you can leave certain source files out of the - * compilation/linking process if you've #undef'd the corresponding symbols. - * (You may HAVE to do that if your compiler doesn't like null source files.) - */ - -/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */ - -/* Capability options common to encoder and decoder: */ - -#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */ -#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */ -#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */ - -/* Encoder capability options: */ - -#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ -#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ -#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ -#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ -/* Note: if you selected 12-bit data precision, it is dangerous to turn off - * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit - * precision, so jchuff.c normally uses entropy optimization to compute - * usable tables for higher precision. If you don't want to do optimization, - * you'll have to supply different default Huffman tables. - * The exact same statements apply for progressive JPEG: the default tables - * don't work for progressive mode. (This may get fixed, however.) - */ -#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */ - -/* Decoder capability options: */ - -#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ -#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ -#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ -#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ -#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ -#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ -#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */ -#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */ -#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */ -#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */ - -/* more capability options later, no doubt */ - - -/* - * Ordering of RGB data in scanlines passed to or from the application. - * If your application wants to deal with data in the order B,G,R, just - * change these macros. You can also deal with formats such as R,G,B,X - * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing - * the offsets will also change the order in which colormap data is organized. - * RESTRICTIONS: - * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. - * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not - * useful if you are using JPEG color spaces other than YCbCr or grayscale. - * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE - * is not 3 (they don't understand about dummy color components!). So you - * can't use color quantization if you change that value. - */ - -#define RGB_RED 0 /* Offset of Red in an RGB scanline element */ -#define RGB_GREEN 1 /* Offset of Green */ -#define RGB_BLUE 2 /* Offset of Blue */ -#ifdef ANDROID_RGB -#define RGB_ALPHA 3 /* Offset of Alpha */ -#endif -#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */ - -/* Definitions for speed-related optimizations. */ - - -/* If your compiler supports inline functions, define INLINE - * as the inline keyword; otherwise define it as empty. - */ - -#ifndef INLINE -#ifdef __GNUC__ /* for instance, GNU C knows about inline */ -#define INLINE __inline__ -#endif -#ifndef INLINE -#define INLINE /* default is to define it as empty */ -#endif -#endif - - -/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying - * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER - * as short on such a machine. MULTIPLIER must be at least 16 bits wide. - */ - -#ifndef MULTIPLIER -#define MULTIPLIER int /* type for fastest integer multiply */ -#endif - - -/* FAST_FLOAT should be either float or double, whichever is done faster - * by your compiler. (Note that this type is only used in the floating point - * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.) - * Typically, float is faster in ANSI C compilers, while double is faster in - * pre-ANSI compilers (because they insist on converting to double anyway). - * The code below therefore chooses float if we have ANSI-style prototypes. - */ - -#ifndef FAST_FLOAT -#ifdef HAVE_PROTOTYPES -#define FAST_FLOAT float -#else -#define FAST_FLOAT double -#endif -#endif - -#endif /* JPEG_INTERNAL_OPTIONS */ diff --git a/extra_lib/include/jpeg/android/jpeglib.h b/extra_lib/include/jpeg/android/jpeglib.h deleted file mode 100644 index 0f3a547..0000000 --- a/extra_lib/include/jpeg/android/jpeglib.h +++ /dev/null @@ -1,1100 +0,0 @@ -/* - * jpeglib.h - * - * Copyright (C) 1991-1998, Thomas G. Lane. - * This file is part of the Independent JPEG Group's software. - * For conditions of distribution and use, see the accompanying README file. - * - * This file defines the application interface for the JPEG library. - * Most applications using the library need only include this file, - * and perhaps jerror.h if they want to know the exact error codes. - */ - -#ifndef JPEGLIB_H -#define JPEGLIB_H - -/* - * First we include the configuration files that record how this - * installation of the JPEG library is set up. jconfig.h can be - * generated automatically for many systems. jmorecfg.h contains - * manual configuration options that most people need not worry about. - */ - -#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */ -#include "jconfig.h" /* widely used configuration options */ -#endif -#include "jmorecfg.h" /* seldom changed options */ - - -/* Version ID for the JPEG library. - * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". - */ - -#define JPEG_LIB_VERSION 62 /* Version 6b */ - - -/* Various constants determining the sizes of things. - * All of these are specified by the JPEG standard, so don't change them - * if you want to be compatible. - */ - -#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */ -#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */ -#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */ -#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */ -#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */ -#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */ -#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */ -/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard; - * the PostScript DCT filter can emit files with many more than 10 blocks/MCU. - * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU - * to handle it. We even let you do this from the jconfig.h file. However, - * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe - * sometimes emits noncompliant files doesn't mean you should too. - */ -#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */ -#ifndef D_MAX_BLOCKS_IN_MCU -#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */ -#endif - - -/* Data structures for images (arrays of samples and of DCT coefficients). - * On 80x86 machines, the image arrays are too big for near pointers, - * but the pointer arrays can fit in near memory. - */ - -typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */ -typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */ -typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */ - -typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ -typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */ -typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */ -typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */ - -typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */ - - -/* Types for JPEG compression parameters and working tables. */ - - -/* DCT coefficient quantization tables. */ - -typedef struct { - /* This array gives the coefficient quantizers in natural array order - * (not the zigzag order in which they are stored in a JPEG DQT marker). - * CAUTION: IJG versions prior to v6a kept this array in zigzag order. - */ - UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */ - /* This field is used only during compression. It's initialized FALSE when - * the table is created, and set TRUE when it's been output to the file. - * You could suppress output of a table by setting this to TRUE. - * (See jpeg_suppress_tables for an example.) - */ - boolean sent_table; /* TRUE when table has been output */ -} JQUANT_TBL; - - -/* Huffman coding tables. */ - -typedef struct { - /* These two fields directly represent the contents of a JPEG DHT marker */ - UINT8 bits[17]; /* bits[k] = # of symbols with codes of */ - /* length k bits; bits[0] is unused */ - UINT8 huffval[256]; /* The symbols, in order of incr code length */ - /* This field is used only during compression. It's initialized FALSE when - * the table is created, and set TRUE when it's been output to the file. - * You could suppress output of a table by setting this to TRUE. - * (See jpeg_suppress_tables for an example.) - */ - boolean sent_table; /* TRUE when table has been output */ -} JHUFF_TBL; - - -/* Basic info about one component (color channel). */ - -typedef struct { - /* These values are fixed over the whole image. */ - /* For compression, they must be supplied by parameter setup; */ - /* for decompression, they are read from the SOF marker. */ - int component_id; /* identifier for this component (0..255) */ - int component_index; /* its index in SOF or cinfo->comp_info[] */ - int h_samp_factor; /* horizontal sampling factor (1..4) */ - int v_samp_factor; /* vertical sampling factor (1..4) */ - int quant_tbl_no; /* quantization table selector (0..3) */ - /* These values may vary between scans. */ - /* For compression, they must be supplied by parameter setup; */ - /* for decompression, they are read from the SOS marker. */ - /* The decompressor output side may not use these variables. */ - int dc_tbl_no; /* DC entropy table selector (0..3) */ - int ac_tbl_no; /* AC entropy table selector (0..3) */ - - /* Remaining fields should be treated as private by applications. */ - - /* These values are computed during compression or decompression startup: */ - /* Component's size in DCT blocks. - * Any dummy blocks added to complete an MCU are not counted; therefore - * these values do not depend on whether a scan is interleaved or not. - */ - JDIMENSION width_in_blocks; - JDIMENSION height_in_blocks; - /* Size of a DCT block in samples. Always DCTSIZE for compression. - * For decompression this is the size of the output from one DCT block, - * reflecting any scaling we choose to apply during the IDCT step. - * Values of 1,2,4,8 are likely to be supported. Note that different - * components may receive different IDCT scalings. - */ - int DCT_scaled_size; - /* The downsampled dimensions are the component's actual, unpadded number - * of samples at the main buffer (preprocessing/compression interface), thus - * downsampled_width = ceil(image_width * Hi/Hmax) - * and similarly for height. For decompression, IDCT scaling is included, so - * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE) - */ - JDIMENSION downsampled_width; /* actual width in samples */ - JDIMENSION downsampled_height; /* actual height in samples */ - /* This flag is used only for decompression. In cases where some of the - * components will be ignored (eg grayscale output from YCbCr image), - * we can skip most computations for the unused components. - */ - boolean component_needed; /* do we need the value of this component? */ - - /* These values are computed before starting a scan of the component. */ - /* The decompressor output side may not use these variables. */ - int MCU_width; /* number of blocks per MCU, horizontally */ - int MCU_height; /* number of blocks per MCU, vertically */ - int MCU_blocks; /* MCU_width * MCU_height */ - int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */ - int last_col_width; /* # of non-dummy blocks across in last MCU */ - int last_row_height; /* # of non-dummy blocks down in last MCU */ - - /* Saved quantization table for component; NULL if none yet saved. - * See jdinput.c comments about the need for this information. - * This field is currently used only for decompression. - */ - JQUANT_TBL * quant_table; - - /* Private per-component storage for DCT or IDCT subsystem. */ - void * dct_table; -} jpeg_component_info; - - -/* The script for encoding a multiple-scan file is an array of these: */ - -typedef struct { - int comps_in_scan; /* number of components encoded in this scan */ - int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */ - int Ss, Se; /* progressive JPEG spectral selection parms */ - int Ah, Al; /* progressive JPEG successive approx. parms */ -} jpeg_scan_info; - -/* The decompressor can save APPn and COM markers in a list of these: */ - -typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr; - -struct jpeg_marker_struct { - jpeg_saved_marker_ptr next; /* next in list, or NULL */ - UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */ - unsigned int original_length; /* # bytes of data in the file */ - unsigned int data_length; /* # bytes of data saved at data[] */ - JOCTET FAR * data; /* the data contained in the marker */ - /* the marker length word is not counted in data_length or original_length */ -}; - -/* Known color spaces. */ - -typedef enum { - JCS_UNKNOWN, /* error/unspecified */ - JCS_GRAYSCALE, /* monochrome */ - JCS_RGB, /* red/green/blue */ - JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ - JCS_CMYK, /* C/M/Y/K */ - JCS_YCCK, /* Y/Cb/Cr/K */ -#ifdef ANDROID_RGB - JCS_RGBA_8888, /* red/green/blue/alpha */ - JCS_RGB_565 /* red/green/blue in 565 format */ -#endif -} J_COLOR_SPACE; - -/* DCT/IDCT algorithm options. */ - -typedef enum { - JDCT_ISLOW, /* slow but accurate integer algorithm */ - JDCT_IFAST, /* faster, less accurate integer method */ - JDCT_FLOAT /* floating-point: accurate, fast on fast HW */ -} J_DCT_METHOD; - -#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */ -#define JDCT_DEFAULT JDCT_ISLOW -#endif -#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */ -#define JDCT_FASTEST JDCT_IFAST -#endif - -/* Dithering options for decompression. */ - -typedef enum { - JDITHER_NONE, /* no dithering */ - JDITHER_ORDERED, /* simple ordered dither */ - JDITHER_FS /* Floyd-Steinberg error diffusion dither */ -} J_DITHER_MODE; - - -/* Common fields between JPEG compression and decompression master structs. */ - -#define jpeg_common_fields \ - struct jpeg_error_mgr * err; /* Error handler module */\ - struct jpeg_memory_mgr * mem; /* Memory manager module */\ - struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\ - void * client_data; /* Available for use by application */\ - boolean is_decompressor; /* So common code can tell which is which */\ - int global_state /* For checking call sequence validity */ - -/* Routines that are to be used by both halves of the library are declared - * to receive a pointer to this structure. There are no actual instances of - * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct. - */ -struct jpeg_common_struct { - jpeg_common_fields; /* Fields common to both master struct types */ - /* Additional fields follow in an actual jpeg_compress_struct or - * jpeg_decompress_struct. All three structs must agree on these - * initial fields! (This would be a lot cleaner in C++.) - */ -}; - -typedef struct jpeg_common_struct * j_common_ptr; -typedef struct jpeg_compress_struct * j_compress_ptr; -typedef struct jpeg_decompress_struct * j_decompress_ptr; - - -/* Master record for a compression instance */ - -struct jpeg_compress_struct { - jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */ - - /* Destination for compressed data */ - struct jpeg_destination_mgr * dest; - - /* Description of source image --- these fields must be filled in by - * outer application before starting compression. in_color_space must - * be correct before you can even call jpeg_set_defaults(). - */ - - JDIMENSION image_width; /* input image width */ - JDIMENSION image_height; /* input image height */ - int input_components; /* # of color components in input image */ - J_COLOR_SPACE in_color_space; /* colorspace of input image */ - - double input_gamma; /* image gamma of input image */ - - /* Compression parameters --- these fields must be set before calling - * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to - * initialize everything to reasonable defaults, then changing anything - * the application specifically wants to change. That way you won't get - * burnt when new parameters are added. Also note that there are several - * helper routines to simplify changing parameters. - */ - - int data_precision; /* bits of precision in image data */ - - int num_components; /* # of color components in JPEG image */ - J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ - - jpeg_component_info * comp_info; - /* comp_info[i] describes component that appears i'th in SOF */ - - JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; - /* ptrs to coefficient quantization tables, or NULL if not defined */ - - JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; - JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; - /* ptrs to Huffman coding tables, or NULL if not defined */ - - UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ - UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ - UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ - - int num_scans; /* # of entries in scan_info array */ - const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */ - /* The default value of scan_info is NULL, which causes a single-scan - * sequential JPEG file to be emitted. To create a multi-scan file, - * set num_scans and scan_info to point to an array of scan definitions. - */ - - boolean raw_data_in; /* TRUE=caller supplies downsampled data */ - boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ - boolean optimize_coding; /* TRUE=optimize entropy encoding parms */ - boolean CCIR601_sampling; /* TRUE=first samples are cosited */ - int smoothing_factor; /* 1..100, or 0 for no input smoothing */ - J_DCT_METHOD dct_method; /* DCT algorithm selector */ - - /* The restart interval can be specified in absolute MCUs by setting - * restart_interval, or in MCU rows by setting restart_in_rows - * (in which case the correct restart_interval will be figured - * for each scan). - */ - unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */ - int restart_in_rows; /* if > 0, MCU rows per restart interval */ - - /* Parameters controlling emission of special markers. */ - - boolean write_JFIF_header; /* should a JFIF marker be written? */ - UINT8 JFIF_major_version; /* What to write for the JFIF version number */ - UINT8 JFIF_minor_version; - /* These three values are not used by the JPEG code, merely copied */ - /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */ - /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */ - /* ratio is defined by X_density/Y_density even when density_unit=0. */ - UINT8 density_unit; /* JFIF code for pixel size units */ - UINT16 X_density; /* Horizontal pixel density */ - UINT16 Y_density; /* Vertical pixel density */ - boolean write_Adobe_marker; /* should an Adobe marker be written? */ - - /* State variable: index of next scanline to be written to - * jpeg_write_scanlines(). Application may use this to control its - * processing loop, e.g., "while (next_scanline < image_height)". - */ - - JDIMENSION next_scanline; /* 0 .. image_height-1 */ - - /* Remaining fields are known throughout compressor, but generally - * should not be touched by a surrounding application. - */ - - /* - * These fields are computed during compression startup - */ - boolean progressive_mode; /* TRUE if scan script uses progressive mode */ - int max_h_samp_factor; /* largest h_samp_factor */ - int max_v_samp_factor; /* largest v_samp_factor */ - - JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */ - /* The coefficient controller receives data in units of MCU rows as defined - * for fully interleaved scans (whether the JPEG file is interleaved or not). - * There are v_samp_factor * DCTSIZE sample rows of each component in an - * "iMCU" (interleaved MCU) row. - */ - - /* - * These fields are valid during any one scan. - * They describe the components and MCUs actually appearing in the scan. - */ - int comps_in_scan; /* # of JPEG components in this scan */ - jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; - /* *cur_comp_info[i] describes component that appears i'th in SOS */ - - JDIMENSION MCUs_per_row; /* # of MCUs across the image */ - JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ - - int blocks_in_MCU; /* # of DCT blocks per MCU */ - int MCU_membership[C_MAX_BLOCKS_IN_MCU]; - /* MCU_membership[i] is index in cur_comp_info of component owning */ - /* i'th block in an MCU */ - - int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ - - /* - * Links to compression subobjects (methods and private variables of modules) - */ - struct jpeg_comp_master * master; - struct jpeg_c_main_controller * main; - struct jpeg_c_prep_controller * prep; - struct jpeg_c_coef_controller * coef; - struct jpeg_marker_writer * marker; - struct jpeg_color_converter * cconvert; - struct jpeg_downsampler * downsample; - struct jpeg_forward_dct * fdct; - struct jpeg_entropy_encoder * entropy; - jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */ - int script_space_size; -}; - - -/* Master record for a decompression instance */ - -struct jpeg_decompress_struct { - jpeg_common_fields; /* Fields shared with jpeg_compress_struct */ - - /* Source of compressed data */ - struct jpeg_source_mgr * src; - - /* Basic description of image --- filled in by jpeg_read_header(). */ - /* Application may inspect these values to decide how to process image. */ - - JDIMENSION image_width; /* nominal image width (from SOF marker) */ - JDIMENSION image_height; /* nominal image height */ - int num_components; /* # of color components in JPEG image */ - J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ - - /* Decompression processing parameters --- these fields must be set before - * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes - * them to default values. - */ - - J_COLOR_SPACE out_color_space; /* colorspace for output */ - - unsigned int scale_num, scale_denom; /* fraction by which to scale image */ - - double output_gamma; /* image gamma wanted in output */ - - boolean buffered_image; /* TRUE=multiple output passes */ - boolean raw_data_out; /* TRUE=downsampled data wanted */ - - J_DCT_METHOD dct_method; /* IDCT algorithm selector */ - boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */ - boolean do_block_smoothing; /* TRUE=apply interblock smoothing */ - - boolean quantize_colors; /* TRUE=colormapped output wanted */ - /* the following are ignored if not quantize_colors: */ - J_DITHER_MODE dither_mode; /* type of color dithering to use */ - boolean two_pass_quantize; /* TRUE=use two-pass color quantization */ - int desired_number_of_colors; /* max # colors to use in created colormap */ - /* these are significant only in buffered-image mode: */ - boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */ - boolean enable_external_quant;/* enable future use of external colormap */ - boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */ - - /* Description of actual output image that will be returned to application. - * These fields are computed by jpeg_start_decompress(). - * You can also use jpeg_calc_output_dimensions() to determine these values - * in advance of calling jpeg_start_decompress(). - */ - - JDIMENSION output_width; /* scaled image width */ - JDIMENSION output_height; /* scaled image height */ - int out_color_components; /* # of color components in out_color_space */ - int output_components; /* # of color components returned */ - /* output_components is 1 (a colormap index) when quantizing colors; - * otherwise it equals out_color_components. - */ - int rec_outbuf_height; /* min recommended height of scanline buffer */ - /* If the buffer passed to jpeg_read_scanlines() is less than this many rows - * high, space and time will be wasted due to unnecessary data copying. - * Usually rec_outbuf_height will be 1 or 2, at most 4. - */ - - /* When quantizing colors, the output colormap is described by these fields. - * The application can supply a colormap by setting colormap non-NULL before - * calling jpeg_start_decompress; otherwise a colormap is created during - * jpeg_start_decompress or jpeg_start_output. - * The map has out_color_components rows and actual_number_of_colors columns. - */ - int actual_number_of_colors; /* number of entries in use */ - JSAMPARRAY colormap; /* The color map as a 2-D pixel array */ - - /* State variables: these variables indicate the progress of decompression. - * The application may examine these but must not modify them. - */ - - /* Row index of next scanline to be read from jpeg_read_scanlines(). - * Application may use this to control its processing loop, e.g., - * "while (output_scanline < output_height)". - */ - JDIMENSION output_scanline; /* 0 .. output_height-1 */ - - /* Current input scan number and number of iMCU rows completed in scan. - * These indicate the progress of the decompressor input side. - */ - int input_scan_number; /* Number of SOS markers seen so far */ - JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */ - - /* The "output scan number" is the notional scan being displayed by the - * output side. The decompressor will not allow output scan/row number - * to get ahead of input scan/row, but it can fall arbitrarily far behind. - */ - int output_scan_number; /* Nominal scan number being displayed */ - JDIMENSION output_iMCU_row; /* Number of iMCU rows read */ - - /* Current progression status. coef_bits[c][i] indicates the precision - * with which component c's DCT coefficient i (in zigzag order) is known. - * It is -1 when no data has yet been received, otherwise it is the point - * transform (shift) value for the most recent scan of the coefficient - * (thus, 0 at completion of the progression). - * This pointer is NULL when reading a non-progressive file. - */ - int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */ - - /* Internal JPEG parameters --- the application usually need not look at - * these fields. Note that the decompressor output side may not use - * any parameters that can change between scans. - */ - - /* Quantization and Huffman tables are carried forward across input - * datastreams when processing abbreviated JPEG datastreams. - */ - - JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; - /* ptrs to coefficient quantization tables, or NULL if not defined */ - - JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; - JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; - /* ptrs to Huffman coding tables, or NULL if not defined */ - - /* These parameters are never carried across datastreams, since they - * are given in SOF/SOS markers or defined to be reset by SOI. - */ - - int data_precision; /* bits of precision in image data */ - - jpeg_component_info * comp_info; - /* comp_info[i] describes component that appears i'th in SOF */ - - boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */ - boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ - - UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ - UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ - UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ - - unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */ - - /* These fields record data obtained from optional markers recognized by - * the JPEG library. - */ - boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */ - /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */ - UINT8 JFIF_major_version; /* JFIF version number */ - UINT8 JFIF_minor_version; - UINT8 density_unit; /* JFIF code for pixel size units */ - UINT16 X_density; /* Horizontal pixel density */ - UINT16 Y_density; /* Vertical pixel density */ - boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */ - UINT8 Adobe_transform; /* Color transform code from Adobe marker */ - - boolean CCIR601_sampling; /* TRUE=first samples are cosited */ - - /* Aside from the specific data retained from APPn markers known to the - * library, the uninterpreted contents of any or all APPn and COM markers - * can be saved in a list for examination by the application. - */ - jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */ - - /* Remaining fields are known throughout decompressor, but generally - * should not be touched by a surrounding application. - */ - - /* - * These fields are computed during decompression startup - */ - int max_h_samp_factor; /* largest h_samp_factor */ - int max_v_samp_factor; /* largest v_samp_factor */ - - int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */ - - JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ - /* The coefficient controller's input and output progress is measured in - * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows - * in fully interleaved JPEG scans, but are used whether the scan is - * interleaved or not. We define an iMCU row as v_samp_factor DCT block - * rows of each component. Therefore, the IDCT output contains - * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row. - */ - - JSAMPLE * sample_range_limit; /* table for fast range-limiting */ - - /* - * These fields are valid during any one scan. - * They describe the components and MCUs actually appearing in the scan. - * Note that the decompressor output side must not use these fields. - */ - int comps_in_scan; /* # of JPEG components in this scan */ - jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; - /* *cur_comp_info[i] describes component that appears i'th in SOS */ - - JDIMENSION MCUs_per_row; /* # of MCUs across the image */ - JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ - - int blocks_in_MCU; /* # of DCT blocks per MCU */ - int MCU_membership[D_MAX_BLOCKS_IN_MCU]; - /* MCU_membership[i] is index in cur_comp_info of component owning */ - /* i'th block in an MCU */ - - int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ - - /* This field is shared between entropy decoder and marker parser. - * It is either zero or the code of a JPEG marker that has been - * read from the data source, but has not yet been processed. - */ - int unread_marker; - - /* - * Links to decompression subobjects (methods, private variables of modules) - */ - struct jpeg_decomp_master * master; - struct jpeg_d_main_controller * main; - struct jpeg_d_coef_controller * coef; - struct jpeg_d_post_controller * post; - struct jpeg_input_controller * inputctl; - struct jpeg_marker_reader * marker; - struct jpeg_entropy_decoder * entropy; - struct jpeg_inverse_dct * idct; - struct jpeg_upsampler * upsample; - struct jpeg_color_deconverter * cconvert; - struct jpeg_color_quantizer * cquantize; -}; - - -/* "Object" declarations for JPEG modules that may be supplied or called - * directly by the surrounding application. - * As with all objects in the JPEG library, these structs only define the - * publicly visible methods and state variables of a module. Additional - * private fields may exist after the public ones. - */ - - -/* Error handler object */ - -struct jpeg_error_mgr { - /* Error exit handler: does not return to caller */ - JMETHOD(void, error_exit, (j_common_ptr cinfo)); - /* Conditionally emit a trace or warning message */ - JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level)); - /* Routine that actually outputs a trace or error message */ - JMETHOD(void, output_message, (j_common_ptr cinfo)); - /* Format a message string for the most recent JPEG error or message */ - JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer)); -#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ - /* Reset error state variables at start of a new image */ - JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo)); - - /* The message ID code and any parameters are saved here. - * A message can have one string parameter or up to 8 int parameters. - */ - int msg_code; -#define JMSG_STR_PARM_MAX 80 - union { - int i[8]; - char s[JMSG_STR_PARM_MAX]; - } msg_parm; - - /* Standard state variables for error facility */ - - int trace_level; /* max msg_level that will be displayed */ - - /* For recoverable corrupt-data errors, we emit a warning message, - * but keep going unless emit_message chooses to abort. emit_message - * should count warnings in num_warnings. The surrounding application - * can check for bad data by seeing if num_warnings is nonzero at the - * end of processing. - */ - long num_warnings; /* number of corrupt-data warnings */ - - /* These fields point to the table(s) of error message strings. - * An application can change the table pointer to switch to a different - * message list (typically, to change the language in which errors are - * reported). Some applications may wish to add additional error codes - * that will be handled by the JPEG library error mechanism; the second - * table pointer is used for this purpose. - * - * First table includes all errors generated by JPEG library itself. - * Error code 0 is reserved for a "no such error string" message. - */ - const char * const * jpeg_message_table; /* Library errors */ - int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */ - /* Second table can be added by application (see cjpeg/djpeg for example). - * It contains strings numbered first_addon_message..last_addon_message. - */ - const char * const * addon_message_table; /* Non-library errors */ - int first_addon_message; /* code for first string in addon table */ - int last_addon_message; /* code for last string in addon table */ -}; - - -/* Progress monitor object */ - -struct jpeg_progress_mgr { - JMETHOD(void, progress_monitor, (j_common_ptr cinfo)); - - long pass_counter; /* work units completed in this pass */ - long pass_limit; /* total number of work units in this pass */ - int completed_passes; /* passes completed so far */ - int total_passes; /* total number of passes expected */ -}; - - -/* Data destination object for compression */ - -struct jpeg_destination_mgr { - JOCTET * next_output_byte; /* => next byte to write in buffer */ - size_t free_in_buffer; /* # of byte spaces remaining in buffer */ - - JMETHOD(void, init_destination, (j_compress_ptr cinfo)); - JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo)); - JMETHOD(void, term_destination, (j_compress_ptr cinfo)); -}; - - -/* Data source object for decompression */ - -struct jpeg_source_mgr { - const JOCTET * next_input_byte; /* => next byte to read from buffer */ - size_t bytes_in_buffer; /* # of bytes remaining in buffer */ - - JMETHOD(void, init_source, (j_decompress_ptr cinfo)); - JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo)); - JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes)); - JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired)); - JMETHOD(void, term_source, (j_decompress_ptr cinfo)); -}; - - -/* Memory manager object. - * Allocates "small" objects (a few K total), "large" objects (tens of K), - * and "really big" objects (virtual arrays with backing store if needed). - * The memory manager does not allow individual objects to be freed; rather, - * each created object is assigned to a pool, and whole pools can be freed - * at once. This is faster and more convenient than remembering exactly what - * to free, especially where malloc()/free() are not too speedy. - * NB: alloc routines never return NULL. They exit to error_exit if not - * successful. - */ - -#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */ -#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */ -#define JPOOL_NUMPOOLS 2 - -typedef struct jvirt_sarray_control * jvirt_sarray_ptr; -typedef struct jvirt_barray_control * jvirt_barray_ptr; - - -struct jpeg_memory_mgr { - /* Method pointers */ - JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id, - size_t sizeofobject)); - JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id, - size_t sizeofobject)); - JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id, - JDIMENSION samplesperrow, - JDIMENSION numrows)); - JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id, - JDIMENSION blocksperrow, - JDIMENSION numrows)); - JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo, - int pool_id, - boolean pre_zero, - JDIMENSION samplesperrow, - JDIMENSION numrows, - JDIMENSION maxaccess)); - JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo, - int pool_id, - boolean pre_zero, - JDIMENSION blocksperrow, - JDIMENSION numrows, - JDIMENSION maxaccess)); - JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo)); - JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo, - jvirt_sarray_ptr ptr, - JDIMENSION start_row, - JDIMENSION num_rows, - boolean writable)); - JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo, - jvirt_barray_ptr ptr, - JDIMENSION start_row, - JDIMENSION num_rows, - boolean writable)); - JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id)); - JMETHOD(void, self_destruct, (j_common_ptr cinfo)); - - /* Limit on memory allocation for this JPEG object. (Note that this is - * merely advisory, not a guaranteed maximum; it only affects the space - * used for virtual-array buffers.) May be changed by outer application - * after creating the JPEG object. - */ - long max_memory_to_use; - - /* Maximum allocation request accepted by alloc_large. */ - long max_alloc_chunk; -}; - - -/* Routine signature for application-supplied marker processing methods. - * Need not pass marker code since it is stored in cinfo->unread_marker. - */ -typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); - - -/* Declarations for routines called by application. - * The JPP macro hides prototype parameters from compilers that can't cope. - * Note JPP requires double parentheses. - */ - -#ifdef HAVE_PROTOTYPES -#define JPP(arglist) arglist -#else -#define JPP(arglist) () -#endif - - -/* Short forms of external names for systems with brain-damaged linkers. - * We shorten external names to be unique in the first six letters, which - * is good enough for all known systems. - * (If your compiler itself needs names to be unique in less than 15 - * characters, you are out of luck. Get a better compiler.) - */ - -#ifdef NEED_SHORT_EXTERNAL_NAMES -#define jpeg_std_error jStdError -#define jpeg_CreateCompress jCreaCompress -#define jpeg_CreateDecompress jCreaDecompress -#define jpeg_destroy_compress jDestCompress -#define jpeg_destroy_decompress jDestDecompress -#define jpeg_stdio_dest jStdDest -#define jpeg_stdio_src jStdSrc -#define jpeg_set_defaults jSetDefaults -#define jpeg_set_colorspace jSetColorspace -#define jpeg_default_colorspace jDefColorspace -#define jpeg_set_quality jSetQuality -#define jpeg_set_linear_quality jSetLQuality -#define jpeg_add_quant_table jAddQuantTable -#define jpeg_quality_scaling jQualityScaling -#define jpeg_simple_progression jSimProgress -#define jpeg_suppress_tables jSuppressTables -#define jpeg_alloc_quant_table jAlcQTable -#define jpeg_alloc_huff_table jAlcHTable -#define jpeg_start_compress jStrtCompress -#define jpeg_write_scanlines jWrtScanlines -#define jpeg_finish_compress jFinCompress -#define jpeg_write_raw_data jWrtRawData -#define jpeg_write_marker jWrtMarker -#define jpeg_write_m_header jWrtMHeader -#define jpeg_write_m_byte jWrtMByte -#define jpeg_write_tables jWrtTables -#define jpeg_read_header jReadHeader -#define jpeg_start_decompress jStrtDecompress -#define jpeg_read_scanlines jReadScanlines -#define jpeg_finish_decompress jFinDecompress -#define jpeg_read_raw_data jReadRawData -#define jpeg_has_multiple_scans jHasMultScn -#define jpeg_start_output jStrtOutput -#define jpeg_finish_output jFinOutput -#define jpeg_input_complete jInComplete -#define jpeg_new_colormap jNewCMap -#define jpeg_consume_input jConsumeInput -#define jpeg_calc_output_dimensions jCalcDimensions -#define jpeg_save_markers jSaveMarkers -#define jpeg_set_marker_processor jSetMarker -#define jpeg_read_coefficients jReadCoefs -#define jpeg_write_coefficients jWrtCoefs -#define jpeg_copy_critical_parameters jCopyCrit -#define jpeg_abort_compress jAbrtCompress -#define jpeg_abort_decompress jAbrtDecompress -#define jpeg_abort jAbort -#define jpeg_destroy jDestroy -#define jpeg_resync_to_restart jResyncRestart -#endif /* NEED_SHORT_EXTERNAL_NAMES */ - - -/* Default error-management setup */ -EXTERN(struct jpeg_error_mgr *) jpeg_std_error - JPP((struct jpeg_error_mgr * err)); - -/* Initialization of JPEG compression objects. - * jpeg_create_compress() and jpeg_create_decompress() are the exported - * names that applications should call. These expand to calls on - * jpeg_CreateCompress and jpeg_CreateDecompress with additional information - * passed for version mismatch checking. - * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx. - */ -#define jpeg_create_compress(cinfo) \ - jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \ - (size_t) sizeof(struct jpeg_compress_struct)) -#define jpeg_create_decompress(cinfo) \ - jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \ - (size_t) sizeof(struct jpeg_decompress_struct)) -EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo, - int version, size_t structsize)); -EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo, - int version, size_t structsize)); -/* Destruction of JPEG compression objects */ -EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo)); -EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); - -/* Standard data source and destination managers: stdio streams. */ -/* Caller is responsible for opening the file before and closing after. */ -EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); -EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile)); - -/* Default parameter setup for compression */ -EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo)); -/* Compression parameter setup aids */ -EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo, - J_COLOR_SPACE colorspace)); -EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo)); -EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, - boolean force_baseline)); -EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo, - int scale_factor, - boolean force_baseline)); -EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, - const unsigned int *basic_table, - int scale_factor, - boolean force_baseline)); -EXTERN(int) jpeg_quality_scaling JPP((int quality)); -EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo)); -EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo, - boolean suppress)); -EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); -EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); - -/* Main entry points for compression */ -EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo, - boolean write_all_tables)); -EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo, - JSAMPARRAY scanlines, - JDIMENSION num_lines)); -EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo)); - -/* Replaces jpeg_write_scanlines when writing raw downsampled data. */ -EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo, - JSAMPIMAGE data, - JDIMENSION num_lines)); - -/* Write a special marker. See libjpeg.doc concerning safe usage. */ -EXTERN(void) jpeg_write_marker - JPP((j_compress_ptr cinfo, int marker, - const JOCTET * dataptr, unsigned int datalen)); -/* Same, but piecemeal. */ -EXTERN(void) jpeg_write_m_header - JPP((j_compress_ptr cinfo, int marker, unsigned int datalen)); -EXTERN(void) jpeg_write_m_byte - JPP((j_compress_ptr cinfo, int val)); - -/* Alternate compression function: just write an abbreviated table file */ -EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo)); - -/* Decompression startup: read start of JPEG datastream to see what's there */ -EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo, - boolean require_image)); -/* Return value is one of: */ -#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */ -#define JPEG_HEADER_OK 1 /* Found valid image datastream */ -#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */ -/* If you pass require_image = TRUE (normal case), you need not check for - * a TABLES_ONLY return code; an abbreviated file will cause an error exit. - * JPEG_SUSPENDED is only possible if you use a data source module that can - * give a suspension return (the stdio source module doesn't). - */ - -/* Main entry points for decompression */ -EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo)); -EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo, - JSAMPARRAY scanlines, - JDIMENSION max_lines)); -EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); - -/* Replaces jpeg_read_scanlines when reading raw downsampled data. */ -EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo, - JSAMPIMAGE data, - JDIMENSION max_lines)); - -/* Additional entry points for buffered-image mode. */ -EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); -EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo, - int scan_number)); -EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo)); -EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo)); -EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo)); -EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo)); -/* Return value is one of: */ -/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */ -#define JPEG_REACHED_SOS 1 /* Reached start of new scan */ -#define JPEG_REACHED_EOI 2 /* Reached end of image */ -#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */ -#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */ - -/* Precalculate output dimensions for current decompression parameters. */ -EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); - -/* Control saving of COM and APPn markers into marker_list. */ -EXTERN(void) jpeg_save_markers - JPP((j_decompress_ptr cinfo, int marker_code, - unsigned int length_limit)); - -/* Install a special processing method for COM or APPn markers. */ -EXTERN(void) jpeg_set_marker_processor - JPP((j_decompress_ptr cinfo, int marker_code, - jpeg_marker_parser_method routine)); - -/* Read or write raw DCT coefficients --- useful for lossless transcoding. */ -EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); -EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo, - jvirt_barray_ptr * coef_arrays)); -EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, - j_compress_ptr dstinfo)); - -/* If you choose to abort compression or decompression before completing - * jpeg_finish_(de)compress, then you need to clean up to release memory, - * temporary files, etc. You can just call jpeg_destroy_(de)compress - * if you're done with the JPEG object, but if you want to clean it up and - * reuse it, call this: - */ -EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo)); -EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo)); - -/* Generic versions of jpeg_abort and jpeg_destroy that work on either - * flavor of JPEG object. These may be more convenient in some places. - */ -EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo)); -EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo)); - -/* Default restart-marker-resync procedure for use by data source modules */ -EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, - int desired)); - - -/* These marker codes are exported since applications and data source modules - * are likely to want to use them. - */ - -#define JPEG_RST0 0xD0 /* RST0 marker code */ -#define JPEG_EOI 0xD9 /* EOI marker code */ -#define JPEG_APP0 0xE0 /* APP0 marker code */ -#define JPEG_COM 0xFE /* COM marker code */ - - -/* If we have a brain-damaged compiler that emits warnings (or worse, errors) - * for structure definitions that are never filled in, keep it quiet by - * supplying dummy definitions for the various substructures. - */ - -#ifdef INCOMPLETE_TYPES_BROKEN -#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */ -struct jvirt_sarray_control { long dummy; }; -struct jvirt_barray_control { long dummy; }; -struct jpeg_comp_master { long dummy; }; -struct jpeg_c_main_controller { long dummy; }; -struct jpeg_c_prep_controller { long dummy; }; -struct jpeg_c_coef_controller { long dummy; }; -struct jpeg_marker_writer { long dummy; }; -struct jpeg_color_converter { long dummy; }; -struct jpeg_downsampler { long dummy; }; -struct jpeg_forward_dct { long dummy; }; -struct jpeg_entropy_encoder { long dummy; }; -struct jpeg_decomp_master { long dummy; }; -struct jpeg_d_main_controller { long dummy; }; -struct jpeg_d_coef_controller { long dummy; }; -struct jpeg_d_post_controller { long dummy; }; -struct jpeg_input_controller { long dummy; }; -struct jpeg_marker_reader { long dummy; }; -struct jpeg_entropy_decoder { long dummy; }; -struct jpeg_inverse_dct { long dummy; }; -struct jpeg_upsampler { long dummy; }; -struct jpeg_color_deconverter { long dummy; }; -struct jpeg_color_quantizer { long dummy; }; -#endif /* JPEG_INTERNALS */ -#endif /* INCOMPLETE_TYPES_BROKEN */ - - -/* - * The JPEG library modules define JPEG_INTERNALS before including this file. - * The internal structure declarations are read only when that is true. - * Applications using the library should not include jpegint.h, but may wish - * to include jerror.h. - */ - -#ifdef JPEG_INTERNALS -#include "jpegint.h" /* fetch private declarations */ -#include "jerror.h" /* fetch error codes too */ -#endif - -#endif /* JPEGLIB_H */ diff --git a/extra_lib/include/jpeg/jconfig.h b/extra_lib/include/jpeg/jconfig.h index 7143622..1ca60d8 100644 --- a/extra_lib/include/jpeg/jconfig.h +++ b/extra_lib/include/jpeg/jconfig.h @@ -1,17 +1,29 @@ -/*jconfig.h for Microsoft Visual C++ and MinGW32 platform*/ +/* jconfig.h. Generated automatically by configure. */ /* jconfig.cfg --- source file edited by configure script */ /* see jconfig.doc for explanations */ -#define HAVE_PROTOTYPES -#define HAVE_UNSIGNED_CHAR -#define HAVE_UNSIGNED_SHORT -#ifdef __MINGW32__ +#ifdef _WIN32_WCE +#define HAVE_PROTOTYPES +#define HAVE_UNSIGNED_CHAR +#define HAVE_UNSIGNED_SHORT +#define HAVE_STDDEF_H +#define HAVE_STDLIB_H + +#ifndef __RPCNDR_H__ +typedef unsigned char boolean; +#endif +#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ +#else +#undef HAVE_PROTOTYPES +#undef HAVE_UNSIGNED_CHAR +#undef HAVE_UNSIGNED_SHORT +#undef HAVE_STDDEF_H +#undef HAVE_STDLIB_H +#endif + #undef void #undef const -#endif #undef CHAR_IS_UNSIGNED -#define HAVE_STDDEF_H -#define HAVE_STDLIB_H #undef NEED_BSD_STRINGS #undef NEED_SYS_TYPES_H #undef NEED_FAR_POINTERS @@ -19,26 +31,18 @@ /* Define this if you get warnings about undefined structures. */ #undef INCOMPLETE_TYPES_BROKEN -#ifndef __MINGW32__ - -/* Define "boolean" as unsigned char, not int, per Windows custom */ -#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */ -typedef unsigned char boolean; -#endif -#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */ -#endif - #ifdef JPEG_INTERNALS #undef RIGHT_SHIFT_IS_UNSIGNED - -#ifdef __MINGW32__ -#define INLINE __inline__ +#undef INLINE /* These are for configuring the JPEG memory manager. */ #undef DEFAULT_MAX_MEM #undef NO_MKTEMP -#endif + +#ifdef __MINGW32__ +#define INLINE __inline__ +#endif //__MINGW32__ #endif /* JPEG_INTERNALS */ diff --git a/extra_lib/include/jpeg/jmorecfg.h b/extra_lib/include/jpeg/jmorecfg.h index c7ed28a..96b501a 100644 --- a/extra_lib/include/jpeg/jmorecfg.h +++ b/extra_lib/include/jpeg/jmorecfg.h @@ -159,8 +159,8 @@ typedef short INT16; #ifndef XMD_H /* X11/xmd.h correctly defines INT32 */ #ifndef INT32 -//typedef long INT32; -#endif +typedef long INT32; +#endif #endif /* Datatype used for image dimensions. The JPEG standard only supports diff --git a/extra_lib/include/jpeg/jpeglib.h b/extra_lib/include/jpeg/jpeglib.h index 0f3a547..d1be8dd 100644 --- a/extra_lib/include/jpeg/jpeglib.h +++ b/extra_lib/include/jpeg/jpeglib.h @@ -128,9 +128,9 @@ typedef struct { /* The decompressor output side may not use these variables. */ int dc_tbl_no; /* DC entropy table selector (0..3) */ int ac_tbl_no; /* AC entropy table selector (0..3) */ - + /* Remaining fields should be treated as private by applications. */ - + /* These values are computed during compression or decompression startup: */ /* Component's size in DCT blocks. * Any dummy blocks added to complete an MCU are not counted; therefore @@ -209,11 +209,7 @@ typedef enum { JCS_RGB, /* red/green/blue */ JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ JCS_CMYK, /* C/M/Y/K */ - JCS_YCCK, /* Y/Cb/Cr/K */ -#ifdef ANDROID_RGB - JCS_RGBA_8888, /* red/green/blue/alpha */ - JCS_RGB_565 /* red/green/blue in 565 format */ -#endif + JCS_YCCK /* Y/Cb/Cr/K */ } J_COLOR_SPACE; /* DCT/IDCT algorithm options. */ @@ -302,14 +298,14 @@ struct jpeg_compress_struct { jpeg_component_info * comp_info; /* comp_info[i] describes component that appears i'th in SOF */ - + JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]; /* ptrs to coefficient quantization tables, or NULL if not defined */ - + JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]; JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]; /* ptrs to Huffman coding tables, or NULL if not defined */ - + UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */ UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */ UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */ @@ -349,7 +345,7 @@ struct jpeg_compress_struct { UINT16 X_density; /* Horizontal pixel density */ UINT16 Y_density; /* Vertical pixel density */ boolean write_Adobe_marker; /* should an Adobe marker be written? */ - + /* State variable: index of next scanline to be written to * jpeg_write_scanlines(). Application may use this to control its * processing loop, e.g., "while (next_scanline < image_height)". @@ -374,7 +370,7 @@ struct jpeg_compress_struct { * There are v_samp_factor * DCTSIZE sample rows of each component in an * "iMCU" (interleaved MCU) row. */ - + /* * These fields are valid during any one scan. * They describe the components and MCUs actually appearing in the scan. @@ -382,10 +378,10 @@ struct jpeg_compress_struct { int comps_in_scan; /* # of JPEG components in this scan */ jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN]; /* *cur_comp_info[i] describes component that appears i'th in SOS */ - + JDIMENSION MCUs_per_row; /* # of MCUs across the image */ JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */ - + int blocks_in_MCU; /* # of DCT blocks per MCU */ int MCU_membership[C_MAX_BLOCKS_IN_MCU]; /* MCU_membership[i] is index in cur_comp_info of component owning */ @@ -656,7 +652,7 @@ struct jpeg_error_mgr { #define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */ /* Reset error state variables at start of a new image */ JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo)); - + /* The message ID code and any parameters are saved here. * A message can have one string parameter or up to 8 int parameters. */ @@ -666,11 +662,11 @@ struct jpeg_error_mgr { int i[8]; char s[JMSG_STR_PARM_MAX]; } msg_parm; - + /* Standard state variables for error facility */ - + int trace_level; /* max msg_level that will be displayed */ - + /* For recoverable corrupt-data errors, we emit a warning message, * but keep going unless emit_message chooses to abort. emit_message * should count warnings in num_warnings. The surrounding application @@ -828,7 +824,7 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); /* Short forms of external names for systems with brain-damaged linkers. * We shorten external names to be unique in the first six letters, which * is good enough for all known systems. - * (If your compiler itself needs names to be unique in less than 15 + * (If your compiler itself needs names to be unique in less than 15 * characters, you are out of luck. Get a better compiler.) */ diff --git a/extra_lib/include/openssl/asn1.h b/extra_lib/include/openssl/asn1.h new file mode 100644 index 0000000..59540e4 --- /dev/null +++ b/extra_lib/include/openssl/asn1.h @@ -0,0 +1,1402 @@ +/* crypto/asn1/asn1.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_ASN1_H +#define HEADER_ASN1_H + +#include +#include +#ifndef OPENSSL_NO_BIO +#include +#endif +#include +#include + +#include + +#include +#ifndef OPENSSL_NO_DEPRECATED +#include +#endif + +#ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define V_ASN1_UNIVERSAL 0x00 +#define V_ASN1_APPLICATION 0x40 +#define V_ASN1_CONTEXT_SPECIFIC 0x80 +#define V_ASN1_PRIVATE 0xc0 + +#define V_ASN1_CONSTRUCTED 0x20 +#define V_ASN1_PRIMITIVE_TAG 0x1f +#define V_ASN1_PRIMATIVE_TAG 0x1f + +#define V_ASN1_APP_CHOOSE -2 /* let the recipient choose */ +#define V_ASN1_OTHER -3 /* used in ASN1_TYPE */ +#define V_ASN1_ANY -4 /* used in ASN1 template code */ + +#define V_ASN1_NEG 0x100 /* negative flag */ + +#define V_ASN1_UNDEF -1 +#define V_ASN1_EOC 0 +#define V_ASN1_BOOLEAN 1 /**/ +#define V_ASN1_INTEGER 2 +#define V_ASN1_NEG_INTEGER (2 | V_ASN1_NEG) +#define V_ASN1_BIT_STRING 3 +#define V_ASN1_OCTET_STRING 4 +#define V_ASN1_NULL 5 +#define V_ASN1_OBJECT 6 +#define V_ASN1_OBJECT_DESCRIPTOR 7 +#define V_ASN1_EXTERNAL 8 +#define V_ASN1_REAL 9 +#define V_ASN1_ENUMERATED 10 +#define V_ASN1_NEG_ENUMERATED (10 | V_ASN1_NEG) +#define V_ASN1_UTF8STRING 12 +#define V_ASN1_SEQUENCE 16 +#define V_ASN1_SET 17 +#define V_ASN1_NUMERICSTRING 18 /**/ +#define V_ASN1_PRINTABLESTRING 19 +#define V_ASN1_T61STRING 20 +#define V_ASN1_TELETEXSTRING 20 /* alias */ +#define V_ASN1_VIDEOTEXSTRING 21 /**/ +#define V_ASN1_IA5STRING 22 +#define V_ASN1_UTCTIME 23 +#define V_ASN1_GENERALIZEDTIME 24 /**/ +#define V_ASN1_GRAPHICSTRING 25 /**/ +#define V_ASN1_ISO64STRING 26 /**/ +#define V_ASN1_VISIBLESTRING 26 /* alias */ +#define V_ASN1_GENERALSTRING 27 /**/ +#define V_ASN1_UNIVERSALSTRING 28 /**/ +#define V_ASN1_BMPSTRING 30 + +/* For use with d2i_ASN1_type_bytes() */ +#define B_ASN1_NUMERICSTRING 0x0001 +#define B_ASN1_PRINTABLESTRING 0x0002 +#define B_ASN1_T61STRING 0x0004 +#define B_ASN1_TELETEXSTRING 0x0004 +#define B_ASN1_VIDEOTEXSTRING 0x0008 +#define B_ASN1_IA5STRING 0x0010 +#define B_ASN1_GRAPHICSTRING 0x0020 +#define B_ASN1_ISO64STRING 0x0040 +#define B_ASN1_VISIBLESTRING 0x0040 +#define B_ASN1_GENERALSTRING 0x0080 +#define B_ASN1_UNIVERSALSTRING 0x0100 +#define B_ASN1_OCTET_STRING 0x0200 +#define B_ASN1_BIT_STRING 0x0400 +#define B_ASN1_BMPSTRING 0x0800 +#define B_ASN1_UNKNOWN 0x1000 +#define B_ASN1_UTF8STRING 0x2000 +#define B_ASN1_UTCTIME 0x4000 +#define B_ASN1_GENERALIZEDTIME 0x8000 +#define B_ASN1_SEQUENCE 0x10000 + +/* For use with ASN1_mbstring_copy() */ +#define MBSTRING_FLAG 0x1000 +#define MBSTRING_UTF8 (MBSTRING_FLAG) +#define MBSTRING_ASC (MBSTRING_FLAG|1) +#define MBSTRING_BMP (MBSTRING_FLAG|2) +#define MBSTRING_UNIV (MBSTRING_FLAG|4) + +#define SMIME_OLDMIME 0x400 +#define SMIME_CRLFEOL 0x800 +#define SMIME_STREAM 0x1000 + +struct X509_algor_st; +DECLARE_STACK_OF(X509_ALGOR) + +#define DECLARE_ASN1_SET_OF(type) /* filled in by mkstack.pl */ +#define IMPLEMENT_ASN1_SET_OF(type) /* nothing, no longer needed */ + +/* We MUST make sure that, except for constness, asn1_ctx_st and + asn1_const_ctx are exactly the same. Fortunately, as soon as + the old ASN1 parsing macros are gone, we can throw this away + as well... */ +typedef struct asn1_ctx_st + { + unsigned char *p;/* work char pointer */ + int eos; /* end of sequence read for indefinite encoding */ + int error; /* error code to use when returning an error */ + int inf; /* constructed if 0x20, indefinite is 0x21 */ + int tag; /* tag from last 'get object' */ + int xclass; /* class from last 'get object' */ + long slen; /* length of last 'get object' */ + unsigned char *max; /* largest value of p allowed */ + unsigned char *q;/* temporary variable */ + unsigned char **pp;/* variable */ + int line; /* used in error processing */ + } ASN1_CTX; + +typedef struct asn1_const_ctx_st + { + const unsigned char *p;/* work char pointer */ + int eos; /* end of sequence read for indefinite encoding */ + int error; /* error code to use when returning an error */ + int inf; /* constructed if 0x20, indefinite is 0x21 */ + int tag; /* tag from last 'get object' */ + int xclass; /* class from last 'get object' */ + long slen; /* length of last 'get object' */ + const unsigned char *max; /* largest value of p allowed */ + const unsigned char *q;/* temporary variable */ + const unsigned char **pp;/* variable */ + int line; /* used in error processing */ + } ASN1_const_CTX; + +/* These are used internally in the ASN1_OBJECT to keep track of + * whether the names and data need to be free()ed */ +#define ASN1_OBJECT_FLAG_DYNAMIC 0x01 /* internal use */ +#define ASN1_OBJECT_FLAG_CRITICAL 0x02 /* critical x509v3 object id */ +#define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04 /* internal use */ +#define ASN1_OBJECT_FLAG_DYNAMIC_DATA 0x08 /* internal use */ +typedef struct asn1_object_st + { + const char *sn,*ln; + int nid; + int length; + const unsigned char *data; /* data remains const after init */ + int flags; /* Should we free this one */ + } ASN1_OBJECT; + +#define ASN1_STRING_FLAG_BITS_LEFT 0x08 /* Set if 0x07 has bits left value */ +/* This indicates that the ASN1_STRING is not a real value but just a place + * holder for the location where indefinite length constructed data should + * be inserted in the memory buffer + */ +#define ASN1_STRING_FLAG_NDEF 0x010 + +/* This flag is used by the CMS code to indicate that a string is not + * complete and is a place holder for content when it had all been + * accessed. The flag will be reset when content has been written to it. + */ + +#define ASN1_STRING_FLAG_CONT 0x020 +/* This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING + * type. + */ +#define ASN1_STRING_FLAG_MSTRING 0x040 +/* This is the base type that holds just about everything :-) */ +typedef struct asn1_string_st + { + int length; + int type; + unsigned char *data; + /* The value of the following field depends on the type being + * held. It is mostly being used for BIT_STRING so if the + * input data has a non-zero 'unused bits' value, it will be + * handled correctly */ + long flags; + } ASN1_STRING; + +/* ASN1_ENCODING structure: this is used to save the received + * encoding of an ASN1 type. This is useful to get round + * problems with invalid encodings which can break signatures. + */ + +typedef struct ASN1_ENCODING_st + { + unsigned char *enc; /* DER encoding */ + long len; /* Length of encoding */ + int modified; /* set to 1 if 'enc' is invalid */ + } ASN1_ENCODING; + +/* Used with ASN1 LONG type: if a long is set to this it is omitted */ +#define ASN1_LONG_UNDEF 0x7fffffffL + +#define STABLE_FLAGS_MALLOC 0x01 +#define STABLE_NO_MASK 0x02 +#define DIRSTRING_TYPE \ + (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING) +#define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING) + +typedef struct asn1_string_table_st { + int nid; + long minsize; + long maxsize; + unsigned long mask; + unsigned long flags; +} ASN1_STRING_TABLE; + +DECLARE_STACK_OF(ASN1_STRING_TABLE) + +/* size limits: this stuff is taken straight from RFC2459 */ + +#define ub_name 32768 +#define ub_common_name 64 +#define ub_locality_name 128 +#define ub_state_name 128 +#define ub_organization_name 64 +#define ub_organization_unit_name 64 +#define ub_title 64 +#define ub_email_address 128 + +/* Declarations for template structures: for full definitions + * see asn1t.h + */ +typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE; +typedef struct ASN1_ITEM_st ASN1_ITEM; +typedef struct ASN1_TLC_st ASN1_TLC; +/* This is just an opaque pointer */ +typedef struct ASN1_VALUE_st ASN1_VALUE; + +/* Declare ASN1 functions: the implement macro in in asn1t.h */ + +#define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type) + +#define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type) + +#define DECLARE_ASN1_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) + +#define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) + +#define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \ + type *d2i_##name(type **a, const unsigned char **in, long len); \ + int i2d_##name(type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(itname) + +#define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \ + type *d2i_##name(type **a, const unsigned char **in, long len); \ + int i2d_##name(const type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(name) + +#define DECLARE_ASN1_NDEF_FUNCTION(name) \ + int i2d_##name##_NDEF(name *a, unsigned char **out); + +#define DECLARE_ASN1_FUNCTIONS_const(name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS(name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name) + +#define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + type *name##_new(void); \ + void name##_free(type *a); + +#define DECLARE_ASN1_PRINT_FUNCTION(stname) \ + DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname) + +#define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \ + int fname##_print_ctx(BIO *out, stname *x, int indent, \ + const ASN1_PCTX *pctx); + +#define D2I_OF(type) type *(*)(type **,const unsigned char **,long) +#define I2D_OF(type) int (*)(type *,unsigned char **) +#define I2D_OF_const(type) int (*)(const type *,unsigned char **) + +#define CHECKED_D2I_OF(type, d2i) \ + ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0))) +#define CHECKED_I2D_OF(type, i2d) \ + ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0))) +#define CHECKED_NEW_OF(type, xnew) \ + ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0))) +#define CHECKED_PTR_OF(type, p) \ + ((void*) (1 ? p : (type*)0)) +#define CHECKED_PPTR_OF(type, p) \ + ((void**) (1 ? p : (type**)0)) + +#define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long) +#define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **) +#define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type) + +TYPEDEF_D2I2D_OF(void); + +/* The following macros and typedefs allow an ASN1_ITEM + * to be embedded in a structure and referenced. Since + * the ASN1_ITEM pointers need to be globally accessible + * (possibly from shared libraries) they may exist in + * different forms. On platforms that support it the + * ASN1_ITEM structure itself will be globally exported. + * Other platforms will export a function that returns + * an ASN1_ITEM pointer. + * + * To handle both cases transparently the macros below + * should be used instead of hard coding an ASN1_ITEM + * pointer in a structure. + * + * The structure will look like this: + * + * typedef struct SOMETHING_st { + * ... + * ASN1_ITEM_EXP *iptr; + * ... + * } SOMETHING; + * + * It would be initialised as e.g.: + * + * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...}; + * + * and the actual pointer extracted with: + * + * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr); + * + * Finally an ASN1_ITEM pointer can be extracted from an + * appropriate reference with: ASN1_ITEM_rptr(X509). This + * would be used when a function takes an ASN1_ITEM * argument. + * + */ + +#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION + +/* ASN1_ITEM pointer exported type */ +typedef const ASN1_ITEM ASN1_ITEM_EXP; + +/* Macro to obtain ASN1_ITEM pointer from exported type */ +#define ASN1_ITEM_ptr(iptr) (iptr) + +/* Macro to include ASN1_ITEM pointer from base type */ +#define ASN1_ITEM_ref(iptr) (&(iptr##_it)) + +#define ASN1_ITEM_rptr(ref) (&(ref##_it)) + +#define DECLARE_ASN1_ITEM(name) \ + OPENSSL_EXTERN const ASN1_ITEM name##_it; + +#else + +/* Platforms that can't easily handle shared global variables are declared + * as functions returning ASN1_ITEM pointers. + */ + +/* ASN1_ITEM pointer exported type */ +typedef const ASN1_ITEM * ASN1_ITEM_EXP(void); + +/* Macro to obtain ASN1_ITEM pointer from exported type */ +#define ASN1_ITEM_ptr(iptr) (iptr()) + +/* Macro to include ASN1_ITEM pointer from base type */ +#define ASN1_ITEM_ref(iptr) (iptr##_it) + +#define ASN1_ITEM_rptr(ref) (ref##_it()) + +#define DECLARE_ASN1_ITEM(name) \ + const ASN1_ITEM * name##_it(void); + +#endif + +/* Parameters used by ASN1_STRING_print_ex() */ + +/* These determine which characters to escape: + * RFC2253 special characters, control characters and + * MSB set characters + */ + +#define ASN1_STRFLGS_ESC_2253 1 +#define ASN1_STRFLGS_ESC_CTRL 2 +#define ASN1_STRFLGS_ESC_MSB 4 + + +/* This flag determines how we do escaping: normally + * RC2253 backslash only, set this to use backslash and + * quote. + */ + +#define ASN1_STRFLGS_ESC_QUOTE 8 + + +/* These three flags are internal use only. */ + +/* Character is a valid PrintableString character */ +#define CHARTYPE_PRINTABLESTRING 0x10 +/* Character needs escaping if it is the first character */ +#define CHARTYPE_FIRST_ESC_2253 0x20 +/* Character needs escaping if it is the last character */ +#define CHARTYPE_LAST_ESC_2253 0x40 + +/* NB the internal flags are safely reused below by flags + * handled at the top level. + */ + +/* If this is set we convert all character strings + * to UTF8 first + */ + +#define ASN1_STRFLGS_UTF8_CONVERT 0x10 + +/* If this is set we don't attempt to interpret content: + * just assume all strings are 1 byte per character. This + * will produce some pretty odd looking output! + */ + +#define ASN1_STRFLGS_IGNORE_TYPE 0x20 + +/* If this is set we include the string type in the output */ +#define ASN1_STRFLGS_SHOW_TYPE 0x40 + +/* This determines which strings to display and which to + * 'dump' (hex dump of content octets or DER encoding). We can + * only dump non character strings or everything. If we + * don't dump 'unknown' they are interpreted as character + * strings with 1 octet per character and are subject to + * the usual escaping options. + */ + +#define ASN1_STRFLGS_DUMP_ALL 0x80 +#define ASN1_STRFLGS_DUMP_UNKNOWN 0x100 + +/* These determine what 'dumping' does, we can dump the + * content octets or the DER encoding: both use the + * RFC2253 #XXXXX notation. + */ + +#define ASN1_STRFLGS_DUMP_DER 0x200 + +/* All the string flags consistent with RFC2253, + * escaping control characters isn't essential in + * RFC2253 but it is advisable anyway. + */ + +#define ASN1_STRFLGS_RFC2253 (ASN1_STRFLGS_ESC_2253 | \ + ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + ASN1_STRFLGS_UTF8_CONVERT | \ + ASN1_STRFLGS_DUMP_UNKNOWN | \ + ASN1_STRFLGS_DUMP_DER) + +DECLARE_STACK_OF(ASN1_INTEGER) +DECLARE_ASN1_SET_OF(ASN1_INTEGER) + +DECLARE_STACK_OF(ASN1_GENERALSTRING) + +typedef struct asn1_type_st + { + int type; + union { + char *ptr; + ASN1_BOOLEAN boolean; + ASN1_STRING * asn1_string; + ASN1_OBJECT * object; + ASN1_INTEGER * integer; + ASN1_ENUMERATED * enumerated; + ASN1_BIT_STRING * bit_string; + ASN1_OCTET_STRING * octet_string; + ASN1_PRINTABLESTRING * printablestring; + ASN1_T61STRING * t61string; + ASN1_IA5STRING * ia5string; + ASN1_GENERALSTRING * generalstring; + ASN1_BMPSTRING * bmpstring; + ASN1_UNIVERSALSTRING * universalstring; + ASN1_UTCTIME * utctime; + ASN1_GENERALIZEDTIME * generalizedtime; + ASN1_VISIBLESTRING * visiblestring; + ASN1_UTF8STRING * utf8string; + /* set and sequence are left complete and still + * contain the set or sequence bytes */ + ASN1_STRING * set; + ASN1_STRING * sequence; + ASN1_VALUE * asn1_value; + } value; + } ASN1_TYPE; + +DECLARE_STACK_OF(ASN1_TYPE) +DECLARE_ASN1_SET_OF(ASN1_TYPE) + +typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY; + +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY) + +typedef struct NETSCAPE_X509_st + { + ASN1_OCTET_STRING *header; + X509 *cert; + } NETSCAPE_X509; + +/* This is used to contain a list of bit names */ +typedef struct BIT_STRING_BITNAME_st { + int bitnum; + const char *lname; + const char *sname; +} BIT_STRING_BITNAME; + + +#define M_ASN1_STRING_length(x) ((x)->length) +#define M_ASN1_STRING_length_set(x, n) ((x)->length = (n)) +#define M_ASN1_STRING_type(x) ((x)->type) +#define M_ASN1_STRING_data(x) ((x)->data) + +/* Macros for string operations */ +#define M_ASN1_BIT_STRING_new() (ASN1_BIT_STRING *)\ + ASN1_STRING_type_new(V_ASN1_BIT_STRING) +#define M_ASN1_BIT_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +#define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) +#define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c) + +#define M_ASN1_INTEGER_new() (ASN1_INTEGER *)\ + ASN1_STRING_type_new(V_ASN1_INTEGER) +#define M_ASN1_INTEGER_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +#define M_ASN1_INTEGER_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) + +#define M_ASN1_ENUMERATED_new() (ASN1_ENUMERATED *)\ + ASN1_STRING_type_new(V_ASN1_ENUMERATED) +#define M_ASN1_ENUMERATED_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +#define M_ASN1_ENUMERATED_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) + +#define M_ASN1_OCTET_STRING_new() (ASN1_OCTET_STRING *)\ + ASN1_STRING_type_new(V_ASN1_OCTET_STRING) +#define M_ASN1_OCTET_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +#define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) +#define M_ASN1_OCTET_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c) +#define M_ASN1_OCTET_STRING_print(a,b) ASN1_STRING_print(a,(ASN1_STRING *)b) +#define M_i2d_ASN1_OCTET_STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_OCTET_STRING,\ + V_ASN1_UNIVERSAL) + +#define B_ASN1_TIME \ + B_ASN1_UTCTIME | \ + B_ASN1_GENERALIZEDTIME + +#define B_ASN1_PRINTABLE \ + B_ASN1_NUMERICSTRING| \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_T61STRING| \ + B_ASN1_IA5STRING| \ + B_ASN1_BIT_STRING| \ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING|\ + B_ASN1_SEQUENCE|\ + B_ASN1_UNKNOWN + +#define B_ASN1_DIRECTORYSTRING \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_TELETEXSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_UTF8STRING + +#define B_ASN1_DISPLAYTEXT \ + B_ASN1_IA5STRING| \ + B_ASN1_VISIBLESTRING| \ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING + +#define M_ASN1_PRINTABLE_new() ASN1_STRING_type_new(V_ASN1_T61STRING) +#define M_ASN1_PRINTABLE_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_ASN1_PRINTABLE(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\ + pp,a->type,V_ASN1_UNIVERSAL) +#define M_d2i_ASN1_PRINTABLE(a,pp,l) \ + d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \ + B_ASN1_PRINTABLE) + +#define M_DIRECTORYSTRING_new() ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING) +#define M_DIRECTORYSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_DIRECTORYSTRING(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\ + pp,a->type,V_ASN1_UNIVERSAL) +#define M_d2i_DIRECTORYSTRING(a,pp,l) \ + d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \ + B_ASN1_DIRECTORYSTRING) + +#define M_DISPLAYTEXT_new() ASN1_STRING_type_new(V_ASN1_VISIBLESTRING) +#define M_DISPLAYTEXT_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_DISPLAYTEXT(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\ + pp,a->type,V_ASN1_UNIVERSAL) +#define M_d2i_DISPLAYTEXT(a,pp,l) \ + d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \ + B_ASN1_DISPLAYTEXT) + +#define M_ASN1_PRINTABLESTRING_new() (ASN1_PRINTABLESTRING *)\ + ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING) +#define M_ASN1_PRINTABLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_ASN1_PRINTABLESTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_PRINTABLESTRING,\ + V_ASN1_UNIVERSAL) +#define M_d2i_ASN1_PRINTABLESTRING(a,pp,l) \ + (ASN1_PRINTABLESTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_PRINTABLESTRING) + +#define M_ASN1_T61STRING_new() (ASN1_T61STRING *)\ + ASN1_STRING_type_new(V_ASN1_T61STRING) +#define M_ASN1_T61STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_ASN1_T61STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_T61STRING,\ + V_ASN1_UNIVERSAL) +#define M_d2i_ASN1_T61STRING(a,pp,l) \ + (ASN1_T61STRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_T61STRING) + +#define M_ASN1_IA5STRING_new() (ASN1_IA5STRING *)\ + ASN1_STRING_type_new(V_ASN1_IA5STRING) +#define M_ASN1_IA5STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_ASN1_IA5STRING_dup(a) \ + (ASN1_IA5STRING *)ASN1_STRING_dup((const ASN1_STRING *)a) +#define M_i2d_ASN1_IA5STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\ + V_ASN1_UNIVERSAL) +#define M_d2i_ASN1_IA5STRING(a,pp,l) \ + (ASN1_IA5STRING *)d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l,\ + B_ASN1_IA5STRING) + +#define M_ASN1_UTCTIME_new() (ASN1_UTCTIME *)\ + ASN1_STRING_type_new(V_ASN1_UTCTIME) +#define M_ASN1_UTCTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) + +#define M_ASN1_GENERALIZEDTIME_new() (ASN1_GENERALIZEDTIME *)\ + ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME) +#define M_ASN1_GENERALIZEDTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\ + (const ASN1_STRING *)a) + +#define M_ASN1_TIME_new() (ASN1_TIME *)\ + ASN1_STRING_type_new(V_ASN1_UTCTIME) +#define M_ASN1_TIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_ASN1_TIME_dup(a) (ASN1_TIME *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) + +#define M_ASN1_GENERALSTRING_new() (ASN1_GENERALSTRING *)\ + ASN1_STRING_type_new(V_ASN1_GENERALSTRING) +#define M_ASN1_GENERALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_ASN1_GENERALSTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_GENERALSTRING,\ + V_ASN1_UNIVERSAL) +#define M_d2i_ASN1_GENERALSTRING(a,pp,l) \ + (ASN1_GENERALSTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_GENERALSTRING) + +#define M_ASN1_UNIVERSALSTRING_new() (ASN1_UNIVERSALSTRING *)\ + ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING) +#define M_ASN1_UNIVERSALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_ASN1_UNIVERSALSTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UNIVERSALSTRING,\ + V_ASN1_UNIVERSAL) +#define M_d2i_ASN1_UNIVERSALSTRING(a,pp,l) \ + (ASN1_UNIVERSALSTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_UNIVERSALSTRING) + +#define M_ASN1_BMPSTRING_new() (ASN1_BMPSTRING *)\ + ASN1_STRING_type_new(V_ASN1_BMPSTRING) +#define M_ASN1_BMPSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_ASN1_BMPSTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_BMPSTRING,\ + V_ASN1_UNIVERSAL) +#define M_d2i_ASN1_BMPSTRING(a,pp,l) \ + (ASN1_BMPSTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_BMPSTRING) + +#define M_ASN1_VISIBLESTRING_new() (ASN1_VISIBLESTRING *)\ + ASN1_STRING_type_new(V_ASN1_VISIBLESTRING) +#define M_ASN1_VISIBLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_ASN1_VISIBLESTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_VISIBLESTRING,\ + V_ASN1_UNIVERSAL) +#define M_d2i_ASN1_VISIBLESTRING(a,pp,l) \ + (ASN1_VISIBLESTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_VISIBLESTRING) + +#define M_ASN1_UTF8STRING_new() (ASN1_UTF8STRING *)\ + ASN1_STRING_type_new(V_ASN1_UTF8STRING) +#define M_ASN1_UTF8STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +#define M_i2d_ASN1_UTF8STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UTF8STRING,\ + V_ASN1_UNIVERSAL) +#define M_d2i_ASN1_UTF8STRING(a,pp,l) \ + (ASN1_UTF8STRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_UTF8STRING) + + /* for the is_set parameter to i2d_ASN1_SET */ +#define IS_SEQUENCE 0 +#define IS_SET 1 + +DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) + +int ASN1_TYPE_get(ASN1_TYPE *a); +void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value); +int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value); +int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b); + +ASN1_OBJECT * ASN1_OBJECT_new(void ); +void ASN1_OBJECT_free(ASN1_OBJECT *a); +int i2d_ASN1_OBJECT(ASN1_OBJECT *a,unsigned char **pp); +ASN1_OBJECT * c2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp, + long length); +ASN1_OBJECT * d2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp, + long length); + +DECLARE_ASN1_ITEM(ASN1_OBJECT) + +DECLARE_STACK_OF(ASN1_OBJECT) +DECLARE_ASN1_SET_OF(ASN1_OBJECT) + +ASN1_STRING * ASN1_STRING_new(void); +void ASN1_STRING_free(ASN1_STRING *a); +int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str); +ASN1_STRING * ASN1_STRING_dup(const ASN1_STRING *a); +ASN1_STRING * ASN1_STRING_type_new(int type ); +int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b); + /* Since this is used to store all sorts of things, via macros, for now, make + its data void * */ +int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); +void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); +int ASN1_STRING_length(const ASN1_STRING *x); +void ASN1_STRING_length_set(ASN1_STRING *x, int n); +int ASN1_STRING_type(ASN1_STRING *x); +unsigned char * ASN1_STRING_data(ASN1_STRING *x); + +DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING) +int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp); +ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,const unsigned char **pp, + long length); +int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, + int length ); +int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value); +int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n); +int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a, + unsigned char *flags, int flags_len); + +#ifndef OPENSSL_NO_BIO +int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs, + BIT_STRING_BITNAME *tbl, int indent); +#endif +int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl); +int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value, + BIT_STRING_BITNAME *tbl); + +int i2d_ASN1_BOOLEAN(int a,unsigned char **pp); +int d2i_ASN1_BOOLEAN(int *a,const unsigned char **pp,long length); + +DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER) +int i2c_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp); +ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a,const unsigned char **pp, + long length); +ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,const unsigned char **pp, + long length); +ASN1_INTEGER * ASN1_INTEGER_dup(const ASN1_INTEGER *x); +int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y); + +DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED) + +int ASN1_UTCTIME_check(ASN1_UTCTIME *a); +ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s,time_t t); +ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, + int offset_day, long offset_sec); +int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str); +int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t); +#if 0 +time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s); +#endif + +int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *a); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,time_t t); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, + time_t t, int offset_day, long offset_sec); +int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str); + +DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING) +ASN1_OCTET_STRING * ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a); +int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b); +int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, int len); + +DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_NULL) +DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING) + +int UTF8_getc(const unsigned char *str, int len, unsigned long *val); +int UTF8_putc(unsigned char *str, int len, unsigned long value); + +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE) + +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING) +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT) +DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME) +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME) +DECLARE_ASN1_FUNCTIONS(ASN1_TIME) + +DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF) + +ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t); +ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s,time_t t, + int offset_day, long offset_sec); +int ASN1_TIME_check(ASN1_TIME *t); +ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out); +int ASN1_TIME_set_string(ASN1_TIME *s, const char *str); + +int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp, + i2d_of_void *i2d, int ex_tag, int ex_class, + int is_set); +STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a, + const unsigned char **pp, + long length, d2i_of_void *d2i, + void (*free_func)(OPENSSL_BLOCK), int ex_tag, + int ex_class); + +#ifndef OPENSSL_NO_BIO +int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a); +int a2i_ASN1_INTEGER(BIO *bp,ASN1_INTEGER *bs,char *buf,int size); +int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a); +int a2i_ASN1_ENUMERATED(BIO *bp,ASN1_ENUMERATED *bs,char *buf,int size); +int i2a_ASN1_OBJECT(BIO *bp,ASN1_OBJECT *a); +int a2i_ASN1_STRING(BIO *bp,ASN1_STRING *bs,char *buf,int size); +int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type); +#endif +int i2t_ASN1_OBJECT(char *buf,int buf_len,ASN1_OBJECT *a); + +int a2d_ASN1_OBJECT(unsigned char *out,int olen, const char *buf, int num); +ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data,int len, + const char *sn, const char *ln); + +int ASN1_INTEGER_set(ASN1_INTEGER *a, long v); +long ASN1_INTEGER_get(const ASN1_INTEGER *a); +ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai); +BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai,BIGNUM *bn); + +int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); +long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a); +ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai); +BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai,BIGNUM *bn); + +/* General */ +/* given a string, return the correct type, max is the maximum length */ +int ASN1_PRINTABLE_type(const unsigned char *s, int max); + +int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass); +ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp, + long length, int Ptag, int Pclass); +unsigned long ASN1_tag2bit(int tag); +/* type is one or more of the B_ASN1_ values. */ +ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a,const unsigned char **pp, + long length,int type); + +/* PARSING */ +int asn1_Finish(ASN1_CTX *c); +int asn1_const_Finish(ASN1_const_CTX *c); + +/* SPECIALS */ +int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, + int *pclass, long omax); +int ASN1_check_infinite_end(unsigned char **p,long len); +int ASN1_const_check_infinite_end(const unsigned char **p,long len); +void ASN1_put_object(unsigned char **pp, int constructed, int length, + int tag, int xclass); +int ASN1_put_eoc(unsigned char **pp); +int ASN1_object_size(int constructed, int length, int tag); + +/* Used to implement other functions */ +void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x); + +#define ASN1_dup_of(type,i2d,d2i,x) \ + ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(type, x))) + +#define ASN1_dup_of_const(type,i2d,d2i,x) \ + ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(const type, x))) + +void *ASN1_item_dup(const ASN1_ITEM *it, void *x); + +/* ASN1 alloc/free macros for when a type is only used internally */ + +#define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type)) +#define M_ASN1_free_of(x, type) \ + ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type)) + +#ifndef OPENSSL_NO_FP_API +void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x); + +#define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x); +int ASN1_i2d_fp(i2d_of_void *i2d,FILE *out,void *x); + +#define ASN1_i2d_fp_of(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +#define ASN1_i2d_fp_of_const(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x); +int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags); +#endif + +int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in); + +#ifndef OPENSSL_NO_BIO +void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x); + +#define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x); +int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, unsigned char *x); + +#define ASN1_i2d_bio_of(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +#define ASN1_i2d_bio_of_const(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x); +int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a); +int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a); +int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a); +int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v); +int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags); +int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num, + unsigned char *buf, int off); +int ASN1_parse(BIO *bp,const unsigned char *pp,long len,int indent); +int ASN1_parse_dump(BIO *bp,const unsigned char *pp,long len,int indent,int dump); +#endif +const char *ASN1_tag2str(int tag); + +/* Used to load and write netscape format cert */ + +DECLARE_ASN1_FUNCTIONS(NETSCAPE_X509) + +int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s); + +int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, + unsigned char *data, int len); +int ASN1_TYPE_get_octetstring(ASN1_TYPE *a, + unsigned char *data, int max_len); +int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, + unsigned char *data, int len); +int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a,long *num, + unsigned char *data, int max_len); + +STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len, + d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK)); +unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d, + unsigned char **buf, int *len ); +void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i); +void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it); +ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, + ASN1_OCTET_STRING **oct); + +#define ASN1_pack_string_of(type,obj,i2d,oct) \ + (ASN1_pack_string(CHECKED_PTR_OF(type, obj), \ + CHECKED_I2D_OF(type, i2d), \ + oct)) + +ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct); + +void ASN1_STRING_set_default_mask(unsigned long mask); +int ASN1_STRING_set_default_mask_asc(const char *p); +unsigned long ASN1_STRING_get_default_mask(void); +int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask); +int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask, + long minsize, long maxsize); + +ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, + const unsigned char *in, int inlen, int inform, int nid); +ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid); +int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long); +void ASN1_STRING_TABLE_cleanup(void); + +/* ASN1 template functions */ + +/* Old API compatible functions */ +ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it); +void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it); +ASN1_VALUE * ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it); +int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); +int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); + +void ASN1_add_oid_module(void); + +ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf); +ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf); + +/* ASN1 Print flags */ + +/* Indicate missing OPTIONAL fields */ +#define ASN1_PCTX_FLAGS_SHOW_ABSENT 0x001 +/* Mark start and end of SEQUENCE */ +#define ASN1_PCTX_FLAGS_SHOW_SEQUENCE 0x002 +/* Mark start and end of SEQUENCE/SET OF */ +#define ASN1_PCTX_FLAGS_SHOW_SSOF 0x004 +/* Show the ASN1 type of primitives */ +#define ASN1_PCTX_FLAGS_SHOW_TYPE 0x008 +/* Don't show ASN1 type of ANY */ +#define ASN1_PCTX_FLAGS_NO_ANY_TYPE 0x010 +/* Don't show ASN1 type of MSTRINGs */ +#define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE 0x020 +/* Don't show field names in SEQUENCE */ +#define ASN1_PCTX_FLAGS_NO_FIELD_NAME 0x040 +/* Show structure names of each SEQUENCE field */ +#define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME 0x080 +/* Don't show structure name even at top level */ +#define ASN1_PCTX_FLAGS_NO_STRUCT_NAME 0x100 + +int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, + const ASN1_ITEM *it, const ASN1_PCTX *pctx); +ASN1_PCTX *ASN1_PCTX_new(void); +void ASN1_PCTX_free(ASN1_PCTX *p); +unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags); + +BIO_METHOD *BIO_f_asn1(void); + +BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it); + +int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const ASN1_ITEM *it); +int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const char *hdr, + const ASN1_ITEM *it); +int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, + int ctype_nid, int econt_nid, + STACK_OF(X509_ALGOR) *mdalgs, + const ASN1_ITEM *it); +ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it); +int SMIME_crlf_copy(BIO *in, BIO *out, int flags); +int SMIME_text(BIO *in, BIO *out); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_ASN1_strings(void); + +/* Error codes for the ASN1 functions. */ + +/* Function codes. */ +#define ASN1_F_A2D_ASN1_OBJECT 100 +#define ASN1_F_A2I_ASN1_ENUMERATED 101 +#define ASN1_F_A2I_ASN1_INTEGER 102 +#define ASN1_F_A2I_ASN1_STRING 103 +#define ASN1_F_APPEND_EXP 176 +#define ASN1_F_ASN1_BIT_STRING_SET_BIT 183 +#define ASN1_F_ASN1_CB 177 +#define ASN1_F_ASN1_CHECK_TLEN 104 +#define ASN1_F_ASN1_COLLATE_PRIMITIVE 105 +#define ASN1_F_ASN1_COLLECT 106 +#define ASN1_F_ASN1_D2I_EX_PRIMITIVE 108 +#define ASN1_F_ASN1_D2I_FP 109 +#define ASN1_F_ASN1_D2I_READ_BIO 107 +#define ASN1_F_ASN1_DIGEST 184 +#define ASN1_F_ASN1_DO_ADB 110 +#define ASN1_F_ASN1_DUP 111 +#define ASN1_F_ASN1_ENUMERATED_SET 112 +#define ASN1_F_ASN1_ENUMERATED_TO_BN 113 +#define ASN1_F_ASN1_EX_C2I 204 +#define ASN1_F_ASN1_FIND_END 190 +#define ASN1_F_ASN1_GENERALIZEDTIME_ADJ 216 +#define ASN1_F_ASN1_GENERALIZEDTIME_SET 185 +#define ASN1_F_ASN1_GENERATE_V3 178 +#define ASN1_F_ASN1_GET_OBJECT 114 +#define ASN1_F_ASN1_HEADER_NEW 115 +#define ASN1_F_ASN1_I2D_BIO 116 +#define ASN1_F_ASN1_I2D_FP 117 +#define ASN1_F_ASN1_INTEGER_SET 118 +#define ASN1_F_ASN1_INTEGER_TO_BN 119 +#define ASN1_F_ASN1_ITEM_D2I_FP 206 +#define ASN1_F_ASN1_ITEM_DUP 191 +#define ASN1_F_ASN1_ITEM_EX_COMBINE_NEW 121 +#define ASN1_F_ASN1_ITEM_EX_D2I 120 +#define ASN1_F_ASN1_ITEM_I2D_BIO 192 +#define ASN1_F_ASN1_ITEM_I2D_FP 193 +#define ASN1_F_ASN1_ITEM_PACK 198 +#define ASN1_F_ASN1_ITEM_SIGN 195 +#define ASN1_F_ASN1_ITEM_UNPACK 199 +#define ASN1_F_ASN1_ITEM_VERIFY 197 +#define ASN1_F_ASN1_MBSTRING_NCOPY 122 +#define ASN1_F_ASN1_OBJECT_NEW 123 +#define ASN1_F_ASN1_OUTPUT_DATA 214 +#define ASN1_F_ASN1_PACK_STRING 124 +#define ASN1_F_ASN1_PCTX_NEW 205 +#define ASN1_F_ASN1_PKCS5_PBE_SET 125 +#define ASN1_F_ASN1_SEQ_PACK 126 +#define ASN1_F_ASN1_SEQ_UNPACK 127 +#define ASN1_F_ASN1_SIGN 128 +#define ASN1_F_ASN1_STR2TYPE 179 +#define ASN1_F_ASN1_STRING_SET 186 +#define ASN1_F_ASN1_STRING_TABLE_ADD 129 +#define ASN1_F_ASN1_STRING_TYPE_NEW 130 +#define ASN1_F_ASN1_TEMPLATE_EX_D2I 132 +#define ASN1_F_ASN1_TEMPLATE_NEW 133 +#define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I 131 +#define ASN1_F_ASN1_TIME_ADJ 217 +#define ASN1_F_ASN1_TIME_SET 175 +#define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 134 +#define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 135 +#define ASN1_F_ASN1_UNPACK_STRING 136 +#define ASN1_F_ASN1_UTCTIME_ADJ 218 +#define ASN1_F_ASN1_UTCTIME_SET 187 +#define ASN1_F_ASN1_VERIFY 137 +#define ASN1_F_B64_READ_ASN1 209 +#define ASN1_F_B64_WRITE_ASN1 210 +#define ASN1_F_BIO_NEW_NDEF 208 +#define ASN1_F_BITSTR_CB 180 +#define ASN1_F_BN_TO_ASN1_ENUMERATED 138 +#define ASN1_F_BN_TO_ASN1_INTEGER 139 +#define ASN1_F_C2I_ASN1_BIT_STRING 189 +#define ASN1_F_C2I_ASN1_INTEGER 194 +#define ASN1_F_C2I_ASN1_OBJECT 196 +#define ASN1_F_COLLECT_DATA 140 +#define ASN1_F_D2I_ASN1_BIT_STRING 141 +#define ASN1_F_D2I_ASN1_BOOLEAN 142 +#define ASN1_F_D2I_ASN1_BYTES 143 +#define ASN1_F_D2I_ASN1_GENERALIZEDTIME 144 +#define ASN1_F_D2I_ASN1_HEADER 145 +#define ASN1_F_D2I_ASN1_INTEGER 146 +#define ASN1_F_D2I_ASN1_OBJECT 147 +#define ASN1_F_D2I_ASN1_SET 148 +#define ASN1_F_D2I_ASN1_TYPE_BYTES 149 +#define ASN1_F_D2I_ASN1_UINTEGER 150 +#define ASN1_F_D2I_ASN1_UTCTIME 151 +#define ASN1_F_D2I_AUTOPRIVATEKEY 207 +#define ASN1_F_D2I_NETSCAPE_RSA 152 +#define ASN1_F_D2I_NETSCAPE_RSA_2 153 +#define ASN1_F_D2I_PRIVATEKEY 154 +#define ASN1_F_D2I_PUBLICKEY 155 +#define ASN1_F_D2I_RSA_NET 200 +#define ASN1_F_D2I_RSA_NET_2 201 +#define ASN1_F_D2I_X509 156 +#define ASN1_F_D2I_X509_CINF 157 +#define ASN1_F_D2I_X509_PKEY 159 +#define ASN1_F_I2D_ASN1_BIO_STREAM 211 +#define ASN1_F_I2D_ASN1_SET 188 +#define ASN1_F_I2D_ASN1_TIME 160 +#define ASN1_F_I2D_DSA_PUBKEY 161 +#define ASN1_F_I2D_EC_PUBKEY 181 +#define ASN1_F_I2D_PRIVATEKEY 163 +#define ASN1_F_I2D_PUBLICKEY 164 +#define ASN1_F_I2D_RSA_NET 162 +#define ASN1_F_I2D_RSA_PUBKEY 165 +#define ASN1_F_LONG_C2I 166 +#define ASN1_F_OID_MODULE_INIT 174 +#define ASN1_F_PARSE_TAGGING 182 +#define ASN1_F_PKCS5_PBE2_SET_IV 167 +#define ASN1_F_PKCS5_PBE_SET 202 +#define ASN1_F_PKCS5_PBE_SET0_ALGOR 215 +#define ASN1_F_SMIME_READ_ASN1 212 +#define ASN1_F_SMIME_TEXT 213 +#define ASN1_F_X509_CINF_NEW 168 +#define ASN1_F_X509_CRL_ADD0_REVOKED 169 +#define ASN1_F_X509_INFO_NEW 170 +#define ASN1_F_X509_NAME_ENCODE 203 +#define ASN1_F_X509_NAME_EX_D2I 158 +#define ASN1_F_X509_NAME_EX_NEW 171 +#define ASN1_F_X509_NEW 172 +#define ASN1_F_X509_PKEY_NEW 173 + +/* Reason codes. */ +#define ASN1_R_ADDING_OBJECT 171 +#define ASN1_R_ASN1_PARSE_ERROR 203 +#define ASN1_R_ASN1_SIG_PARSE_ERROR 204 +#define ASN1_R_AUX_ERROR 100 +#define ASN1_R_BAD_CLASS 101 +#define ASN1_R_BAD_OBJECT_HEADER 102 +#define ASN1_R_BAD_PASSWORD_READ 103 +#define ASN1_R_BAD_TAG 104 +#define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214 +#define ASN1_R_BN_LIB 105 +#define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106 +#define ASN1_R_BUFFER_TOO_SMALL 107 +#define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 108 +#define ASN1_R_DATA_IS_WRONG 109 +#define ASN1_R_DECODE_ERROR 110 +#define ASN1_R_DECODING_ERROR 111 +#define ASN1_R_DEPTH_EXCEEDED 174 +#define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 198 +#define ASN1_R_ENCODE_ERROR 112 +#define ASN1_R_ERROR_GETTING_TIME 173 +#define ASN1_R_ERROR_LOADING_SECTION 172 +#define ASN1_R_ERROR_PARSING_SET_ELEMENT 113 +#define ASN1_R_ERROR_SETTING_CIPHER_PARAMS 114 +#define ASN1_R_EXPECTING_AN_INTEGER 115 +#define ASN1_R_EXPECTING_AN_OBJECT 116 +#define ASN1_R_EXPECTING_A_BOOLEAN 117 +#define ASN1_R_EXPECTING_A_TIME 118 +#define ASN1_R_EXPLICIT_LENGTH_MISMATCH 119 +#define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 120 +#define ASN1_R_FIELD_MISSING 121 +#define ASN1_R_FIRST_NUM_TOO_LARGE 122 +#define ASN1_R_HEADER_TOO_LONG 123 +#define ASN1_R_ILLEGAL_BITSTRING_FORMAT 175 +#define ASN1_R_ILLEGAL_BOOLEAN 176 +#define ASN1_R_ILLEGAL_CHARACTERS 124 +#define ASN1_R_ILLEGAL_FORMAT 177 +#define ASN1_R_ILLEGAL_HEX 178 +#define ASN1_R_ILLEGAL_IMPLICIT_TAG 179 +#define ASN1_R_ILLEGAL_INTEGER 180 +#define ASN1_R_ILLEGAL_NESTED_TAGGING 181 +#define ASN1_R_ILLEGAL_NULL 125 +#define ASN1_R_ILLEGAL_NULL_VALUE 182 +#define ASN1_R_ILLEGAL_OBJECT 183 +#define ASN1_R_ILLEGAL_OPTIONAL_ANY 126 +#define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 170 +#define ASN1_R_ILLEGAL_TAGGED_ANY 127 +#define ASN1_R_ILLEGAL_TIME_VALUE 184 +#define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185 +#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128 +#define ASN1_R_INVALID_BMPSTRING_LENGTH 129 +#define ASN1_R_INVALID_DIGIT 130 +#define ASN1_R_INVALID_MIME_TYPE 205 +#define ASN1_R_INVALID_MODIFIER 186 +#define ASN1_R_INVALID_NUMBER 187 +#define ASN1_R_INVALID_OBJECT_ENCODING 216 +#define ASN1_R_INVALID_SEPARATOR 131 +#define ASN1_R_INVALID_TIME_FORMAT 132 +#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133 +#define ASN1_R_INVALID_UTF8STRING 134 +#define ASN1_R_IV_TOO_LARGE 135 +#define ASN1_R_LENGTH_ERROR 136 +#define ASN1_R_LIST_ERROR 188 +#define ASN1_R_MIME_NO_CONTENT_TYPE 206 +#define ASN1_R_MIME_PARSE_ERROR 207 +#define ASN1_R_MIME_SIG_PARSE_ERROR 208 +#define ASN1_R_MISSING_EOC 137 +#define ASN1_R_MISSING_SECOND_NUMBER 138 +#define ASN1_R_MISSING_VALUE 189 +#define ASN1_R_MSTRING_NOT_UNIVERSAL 139 +#define ASN1_R_MSTRING_WRONG_TAG 140 +#define ASN1_R_NESTED_ASN1_STRING 197 +#define ASN1_R_NON_HEX_CHARACTERS 141 +#define ASN1_R_NOT_ASCII_FORMAT 190 +#define ASN1_R_NOT_ENOUGH_DATA 142 +#define ASN1_R_NO_CONTENT_TYPE 209 +#define ASN1_R_NO_DEFAULT_DIGEST 201 +#define ASN1_R_NO_MATCHING_CHOICE_TYPE 143 +#define ASN1_R_NO_MULTIPART_BODY_FAILURE 210 +#define ASN1_R_NO_MULTIPART_BOUNDARY 211 +#define ASN1_R_NO_SIG_CONTENT_TYPE 212 +#define ASN1_R_NULL_IS_WRONG_LENGTH 144 +#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191 +#define ASN1_R_ODD_NUMBER_OF_CHARS 145 +#define ASN1_R_PRIVATE_KEY_HEADER_MISSING 146 +#define ASN1_R_SECOND_NUMBER_TOO_LARGE 147 +#define ASN1_R_SEQUENCE_LENGTH_MISMATCH 148 +#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149 +#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 192 +#define ASN1_R_SHORT_LINE 150 +#define ASN1_R_SIG_INVALID_MIME_TYPE 213 +#define ASN1_R_STREAMING_NOT_SUPPORTED 202 +#define ASN1_R_STRING_TOO_LONG 151 +#define ASN1_R_STRING_TOO_SHORT 152 +#define ASN1_R_TAG_VALUE_TOO_HIGH 153 +#define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154 +#define ASN1_R_TIME_NOT_ASCII_FORMAT 193 +#define ASN1_R_TOO_LONG 155 +#define ASN1_R_TYPE_NOT_CONSTRUCTED 156 +#define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157 +#define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 158 +#define ASN1_R_UNEXPECTED_EOC 159 +#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 215 +#define ASN1_R_UNKNOWN_FORMAT 160 +#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161 +#define ASN1_R_UNKNOWN_OBJECT_TYPE 162 +#define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE 163 +#define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 199 +#define ASN1_R_UNKNOWN_TAG 194 +#define ASN1_R_UNKOWN_FORMAT 195 +#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 164 +#define ASN1_R_UNSUPPORTED_CIPHER 165 +#define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM 166 +#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 167 +#define ASN1_R_UNSUPPORTED_TYPE 196 +#define ASN1_R_WRONG_PUBLIC_KEY_TYPE 200 +#define ASN1_R_WRONG_TAG 168 +#define ASN1_R_WRONG_TYPE 169 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/bio.h b/extra_lib/include/openssl/bio.h new file mode 100644 index 0000000..152802f --- /dev/null +++ b/extra_lib/include/openssl/bio.h @@ -0,0 +1,770 @@ +/* crypto/bio/bio.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BIO_H +#define HEADER_BIO_H + +#include + +#ifndef OPENSSL_NO_FP_API +# include +#endif +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* These are the 'types' of BIOs */ +#define BIO_TYPE_NONE 0 +#define BIO_TYPE_MEM (1|0x0400) +#define BIO_TYPE_FILE (2|0x0400) + +#define BIO_TYPE_FD (4|0x0400|0x0100) +#define BIO_TYPE_SOCKET (5|0x0400|0x0100) +#define BIO_TYPE_NULL (6|0x0400) +#define BIO_TYPE_SSL (7|0x0200) +#define BIO_TYPE_MD (8|0x0200) /* passive filter */ +#define BIO_TYPE_BUFFER (9|0x0200) /* filter */ +#define BIO_TYPE_CIPHER (10|0x0200) /* filter */ +#define BIO_TYPE_BASE64 (11|0x0200) /* filter */ +#define BIO_TYPE_CONNECT (12|0x0400|0x0100) /* socket - connect */ +#define BIO_TYPE_ACCEPT (13|0x0400|0x0100) /* socket for accept */ +#define BIO_TYPE_PROXY_CLIENT (14|0x0200) /* client proxy BIO */ +#define BIO_TYPE_PROXY_SERVER (15|0x0200) /* server proxy BIO */ +#define BIO_TYPE_NBIO_TEST (16|0x0200) /* server proxy BIO */ +#define BIO_TYPE_NULL_FILTER (17|0x0200) +#define BIO_TYPE_BER (18|0x0200) /* BER -> bin filter */ +#define BIO_TYPE_BIO (19|0x0400) /* (half a) BIO pair */ +#define BIO_TYPE_LINEBUFFER (20|0x0200) /* filter */ +#define BIO_TYPE_DGRAM (21|0x0400|0x0100) +#define BIO_TYPE_ASN1 (22|0x0200) /* filter */ +#define BIO_TYPE_COMP (23|0x0200) /* filter */ + +#define BIO_TYPE_DESCRIPTOR 0x0100 /* socket, fd, connect or accept */ +#define BIO_TYPE_FILTER 0x0200 +#define BIO_TYPE_SOURCE_SINK 0x0400 + +/* BIO_FILENAME_READ|BIO_CLOSE to open or close on free. + * BIO_set_fp(in,stdin,BIO_NOCLOSE); */ +#define BIO_NOCLOSE 0x00 +#define BIO_CLOSE 0x01 + +/* These are used in the following macros and are passed to + * BIO_ctrl() */ +#define BIO_CTRL_RESET 1 /* opt - rewind/zero etc */ +#define BIO_CTRL_EOF 2 /* opt - are we at the eof */ +#define BIO_CTRL_INFO 3 /* opt - extra tit-bits */ +#define BIO_CTRL_SET 4 /* man - set the 'IO' type */ +#define BIO_CTRL_GET 5 /* man - get the 'IO' type */ +#define BIO_CTRL_PUSH 6 /* opt - internal, used to signify change */ +#define BIO_CTRL_POP 7 /* opt - internal, used to signify change */ +#define BIO_CTRL_GET_CLOSE 8 /* man - set the 'close' on free */ +#define BIO_CTRL_SET_CLOSE 9 /* man - set the 'close' on free */ +#define BIO_CTRL_PENDING 10 /* opt - is their more data buffered */ +#define BIO_CTRL_FLUSH 11 /* opt - 'flush' buffered output */ +#define BIO_CTRL_DUP 12 /* man - extra stuff for 'duped' BIO */ +#define BIO_CTRL_WPENDING 13 /* opt - number of bytes still to write */ +/* callback is int cb(BIO *bio,state,ret); */ +#define BIO_CTRL_SET_CALLBACK 14 /* opt - set callback function */ +#define BIO_CTRL_GET_CALLBACK 15 /* opt - set callback function */ + +#define BIO_CTRL_SET_FILENAME 30 /* BIO_s_file special */ + +/* dgram BIO stuff */ +#define BIO_CTRL_DGRAM_CONNECT 31 /* BIO dgram special */ +#define BIO_CTRL_DGRAM_SET_CONNECTED 32 /* allow for an externally + * connected socket to be + * passed in */ +#define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33 /* setsockopt, essentially */ +#define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34 /* getsockopt, essentially */ +#define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35 /* setsockopt, essentially */ +#define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36 /* getsockopt, essentially */ + +#define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37 /* flag whether the last */ +#define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38 /* I/O operation tiemd out */ + +/* #ifdef IP_MTU_DISCOVER */ +#define BIO_CTRL_DGRAM_MTU_DISCOVER 39 /* set DF bit on egress packets */ +/* #endif */ + +#define BIO_CTRL_DGRAM_QUERY_MTU 40 /* as kernel for current MTU */ +#define BIO_CTRL_DGRAM_GET_MTU 41 /* get cached value for MTU */ +#define BIO_CTRL_DGRAM_SET_MTU 42 /* set cached value for + * MTU. want to use this + * if asking the kernel + * fails */ + +#define BIO_CTRL_DGRAM_MTU_EXCEEDED 43 /* check whether the MTU + * was exceed in the + * previous write + * operation */ + +#define BIO_CTRL_DGRAM_GET_PEER 46 +#define BIO_CTRL_DGRAM_SET_PEER 44 /* Destination for the data */ + +#define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45 /* Next DTLS handshake timeout to + * adjust socket timeouts */ + +/* modifiers */ +#define BIO_FP_READ 0x02 +#define BIO_FP_WRITE 0x04 +#define BIO_FP_APPEND 0x08 +#define BIO_FP_TEXT 0x10 + +#define BIO_FLAGS_READ 0x01 +#define BIO_FLAGS_WRITE 0x02 +#define BIO_FLAGS_IO_SPECIAL 0x04 +#define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL) +#define BIO_FLAGS_SHOULD_RETRY 0x08 +#ifndef BIO_FLAGS_UPLINK +/* "UPLINK" flag denotes file descriptors provided by application. + It defaults to 0, as most platforms don't require UPLINK interface. */ +#define BIO_FLAGS_UPLINK 0 +#endif + +/* Used in BIO_gethostbyname() */ +#define BIO_GHBN_CTRL_HITS 1 +#define BIO_GHBN_CTRL_MISSES 2 +#define BIO_GHBN_CTRL_CACHE_SIZE 3 +#define BIO_GHBN_CTRL_GET_ENTRY 4 +#define BIO_GHBN_CTRL_FLUSH 5 + +/* Mostly used in the SSL BIO */ +/* Not used anymore + * #define BIO_FLAGS_PROTOCOL_DELAYED_READ 0x10 + * #define BIO_FLAGS_PROTOCOL_DELAYED_WRITE 0x20 + * #define BIO_FLAGS_PROTOCOL_STARTUP 0x40 + */ + +#define BIO_FLAGS_BASE64_NO_NL 0x100 + +/* This is used with memory BIOs: it means we shouldn't free up or change the + * data in any way. + */ +#define BIO_FLAGS_MEM_RDONLY 0x200 + +typedef struct bio_st BIO; + +void BIO_set_flags(BIO *b, int flags); +int BIO_test_flags(const BIO *b, int flags); +void BIO_clear_flags(BIO *b, int flags); + +#define BIO_get_flags(b) BIO_test_flags(b, ~(0x0)) +#define BIO_set_retry_special(b) \ + BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY)) +#define BIO_set_retry_read(b) \ + BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)) +#define BIO_set_retry_write(b) \ + BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY)) + +/* These are normally used internally in BIOs */ +#define BIO_clear_retry_flags(b) \ + BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) +#define BIO_get_retry_flags(b) \ + BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) + +/* These should be used by the application to tell why we should retry */ +#define BIO_should_read(a) BIO_test_flags(a, BIO_FLAGS_READ) +#define BIO_should_write(a) BIO_test_flags(a, BIO_FLAGS_WRITE) +#define BIO_should_io_special(a) BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL) +#define BIO_retry_type(a) BIO_test_flags(a, BIO_FLAGS_RWS) +#define BIO_should_retry(a) BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY) + +/* The next three are used in conjunction with the + * BIO_should_io_special() condition. After this returns true, + * BIO *BIO_get_retry_BIO(BIO *bio, int *reason); will walk the BIO + * stack and return the 'reason' for the special and the offending BIO. + * Given a BIO, BIO_get_retry_reason(bio) will return the code. */ +/* Returned from the SSL bio when the certificate retrieval code had an error */ +#define BIO_RR_SSL_X509_LOOKUP 0x01 +/* Returned from the connect BIO when a connect would have blocked */ +#define BIO_RR_CONNECT 0x02 +/* Returned from the accept BIO when an accept would have blocked */ +#define BIO_RR_ACCEPT 0x03 + +/* These are passed by the BIO callback */ +#define BIO_CB_FREE 0x01 +#define BIO_CB_READ 0x02 +#define BIO_CB_WRITE 0x03 +#define BIO_CB_PUTS 0x04 +#define BIO_CB_GETS 0x05 +#define BIO_CB_CTRL 0x06 + +/* The callback is called before and after the underling operation, + * The BIO_CB_RETURN flag indicates if it is after the call */ +#define BIO_CB_RETURN 0x80 +#define BIO_CB_return(a) ((a)|BIO_CB_RETURN)) +#define BIO_cb_pre(a) (!((a)&BIO_CB_RETURN)) +#define BIO_cb_post(a) ((a)&BIO_CB_RETURN) + +long (*BIO_get_callback(const BIO *b)) (struct bio_st *,int,const char *,int, long,long); +void BIO_set_callback(BIO *b, + long (*callback)(struct bio_st *,int,const char *,int, long,long)); +char *BIO_get_callback_arg(const BIO *b); +void BIO_set_callback_arg(BIO *b, char *arg); + +const char * BIO_method_name(const BIO *b); +int BIO_method_type(const BIO *b); + +typedef void bio_info_cb(struct bio_st *, int, const char *, int, long, long); + +typedef struct bio_method_st + { + int type; + const char *name; + int (*bwrite)(BIO *, const char *, int); + int (*bread)(BIO *, char *, int); + int (*bputs)(BIO *, const char *); + int (*bgets)(BIO *, char *, int); + long (*ctrl)(BIO *, int, long, void *); + int (*create)(BIO *); + int (*destroy)(BIO *); + long (*callback_ctrl)(BIO *, int, bio_info_cb *); + } BIO_METHOD; + +struct bio_st + { + BIO_METHOD *method; + /* bio, mode, argp, argi, argl, ret */ + long (*callback)(struct bio_st *,int,const char *,int, long,long); + char *cb_arg; /* first argument for the callback */ + + int init; + int shutdown; + int flags; /* extra storage */ + int retry_reason; + int num; + void *ptr; + struct bio_st *next_bio; /* used by filter BIOs */ + struct bio_st *prev_bio; /* used by filter BIOs */ + int references; + unsigned long num_read; + unsigned long num_write; + + CRYPTO_EX_DATA ex_data; + }; + +DECLARE_STACK_OF(BIO) + +typedef struct bio_f_buffer_ctx_struct + { + /* BIO *bio; */ /* this is now in the BIO struct */ + int ibuf_size; /* how big is the input buffer */ + int obuf_size; /* how big is the output buffer */ + + char *ibuf; /* the char array */ + int ibuf_len; /* how many bytes are in it */ + int ibuf_off; /* write/read offset */ + + char *obuf; /* the char array */ + int obuf_len; /* how many bytes are in it */ + int obuf_off; /* write/read offset */ + } BIO_F_BUFFER_CTX; + +/* Prefix and suffix callback in ASN1 BIO */ +typedef int asn1_ps_func(BIO *b, unsigned char **pbuf, int *plen, void *parg); + +/* connect BIO stuff */ +#define BIO_CONN_S_BEFORE 1 +#define BIO_CONN_S_GET_IP 2 +#define BIO_CONN_S_GET_PORT 3 +#define BIO_CONN_S_CREATE_SOCKET 4 +#define BIO_CONN_S_CONNECT 5 +#define BIO_CONN_S_OK 6 +#define BIO_CONN_S_BLOCKED_CONNECT 7 +#define BIO_CONN_S_NBIO 8 +/*#define BIO_CONN_get_param_hostname BIO_ctrl */ + +#define BIO_C_SET_CONNECT 100 +#define BIO_C_DO_STATE_MACHINE 101 +#define BIO_C_SET_NBIO 102 +#define BIO_C_SET_PROXY_PARAM 103 +#define BIO_C_SET_FD 104 +#define BIO_C_GET_FD 105 +#define BIO_C_SET_FILE_PTR 106 +#define BIO_C_GET_FILE_PTR 107 +#define BIO_C_SET_FILENAME 108 +#define BIO_C_SET_SSL 109 +#define BIO_C_GET_SSL 110 +#define BIO_C_SET_MD 111 +#define BIO_C_GET_MD 112 +#define BIO_C_GET_CIPHER_STATUS 113 +#define BIO_C_SET_BUF_MEM 114 +#define BIO_C_GET_BUF_MEM_PTR 115 +#define BIO_C_GET_BUFF_NUM_LINES 116 +#define BIO_C_SET_BUFF_SIZE 117 +#define BIO_C_SET_ACCEPT 118 +#define BIO_C_SSL_MODE 119 +#define BIO_C_GET_MD_CTX 120 +#define BIO_C_GET_PROXY_PARAM 121 +#define BIO_C_SET_BUFF_READ_DATA 122 /* data to read first */ +#define BIO_C_GET_CONNECT 123 +#define BIO_C_GET_ACCEPT 124 +#define BIO_C_SET_SSL_RENEGOTIATE_BYTES 125 +#define BIO_C_GET_SSL_NUM_RENEGOTIATES 126 +#define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT 127 +#define BIO_C_FILE_SEEK 128 +#define BIO_C_GET_CIPHER_CTX 129 +#define BIO_C_SET_BUF_MEM_EOF_RETURN 130/*return end of input value*/ +#define BIO_C_SET_BIND_MODE 131 +#define BIO_C_GET_BIND_MODE 132 +#define BIO_C_FILE_TELL 133 +#define BIO_C_GET_SOCKS 134 +#define BIO_C_SET_SOCKS 135 + +#define BIO_C_SET_WRITE_BUF_SIZE 136/* for BIO_s_bio */ +#define BIO_C_GET_WRITE_BUF_SIZE 137 +#define BIO_C_MAKE_BIO_PAIR 138 +#define BIO_C_DESTROY_BIO_PAIR 139 +#define BIO_C_GET_WRITE_GUARANTEE 140 +#define BIO_C_GET_READ_REQUEST 141 +#define BIO_C_SHUTDOWN_WR 142 +#define BIO_C_NREAD0 143 +#define BIO_C_NREAD 144 +#define BIO_C_NWRITE0 145 +#define BIO_C_NWRITE 146 +#define BIO_C_RESET_READ_REQUEST 147 +#define BIO_C_SET_MD_CTX 148 + +#define BIO_C_SET_PREFIX 149 +#define BIO_C_GET_PREFIX 150 +#define BIO_C_SET_SUFFIX 151 +#define BIO_C_GET_SUFFIX 152 + +#define BIO_C_SET_EX_ARG 153 +#define BIO_C_GET_EX_ARG 154 + +#define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,arg) +#define BIO_get_app_data(s) BIO_get_ex_data(s,0) + +/* BIO_s_connect() and BIO_s_socks4a_connect() */ +#define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name) +#define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port) +#define BIO_set_conn_ip(b,ip) BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip) +#define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port) +#define BIO_get_conn_hostname(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0) +#define BIO_get_conn_port(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1) +#define BIO_get_conn_ip(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2) +#define BIO_get_conn_int_port(b) BIO_int_ctrl(b,BIO_C_GET_CONNECT,3,0) + + +#define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) + +/* BIO_s_accept_socket() */ +#define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name) +#define BIO_get_accept_port(b) BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0) +/* #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */ +#define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?(void *)"a":NULL) +#define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio) + +#define BIO_BIND_NORMAL 0 +#define BIO_BIND_REUSEADDR_IF_UNUSED 1 +#define BIO_BIND_REUSEADDR 2 +#define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL) +#define BIO_get_bind_mode(b,mode) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL) + +#define BIO_do_connect(b) BIO_do_handshake(b) +#define BIO_do_accept(b) BIO_do_handshake(b) +#define BIO_do_handshake(b) BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL) + +/* BIO_s_proxy_client() */ +#define BIO_set_url(b,url) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,0,(char *)(url)) +#define BIO_set_proxies(b,p) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,1,(char *)(p)) +/* BIO_set_nbio(b,n) */ +#define BIO_set_filter_bio(b,s) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,2,(char *)(s)) +/* BIO *BIO_get_filter_bio(BIO *bio); */ +#define BIO_set_proxy_cb(b,cb) BIO_callback_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(void *(*cb)())) +#define BIO_set_proxy_header(b,sk) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,4,(char *)sk) +#define BIO_set_no_connect_return(b,bool) BIO_int_ctrl(b,BIO_C_SET_PROXY_PARAM,5,bool) + +#define BIO_get_proxy_header(b,skp) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,0,(char *)skp) +#define BIO_get_proxies(b,pxy_p) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,1,(char *)(pxy_p)) +#define BIO_get_url(b,url) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,2,(char *)(url)) +#define BIO_get_no_connect_return(b) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,5,NULL) + +#define BIO_set_fd(b,fd,c) BIO_int_ctrl(b,BIO_C_SET_FD,c,fd) +#define BIO_get_fd(b,c) BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c) + +#define BIO_set_fp(b,fp,c) BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp) +#define BIO_get_fp(b,fpp) BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp) + +#define BIO_seek(b,ofs) (int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL) +#define BIO_tell(b) (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL) + +/* name is cast to lose const, but might be better to route through a function + so we can do it safely */ +#ifdef CONST_STRICT +/* If you are wondering why this isn't defined, its because CONST_STRICT is + * purely a compile-time kludge to allow const to be checked. + */ +int BIO_read_filename(BIO *b,const char *name); +#else +#define BIO_read_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ,(char *)name) +#endif +#define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_WRITE,name) +#define BIO_append_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_APPEND,name) +#define BIO_rw_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name) + +/* WARNING WARNING, this ups the reference count on the read bio of the + * SSL structure. This is because the ssl read BIO is now pointed to by + * the next_bio field in the bio. So when you free the BIO, make sure + * you are doing a BIO_free_all() to catch the underlying BIO. */ +#define BIO_set_ssl(b,ssl,c) BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl) +#define BIO_get_ssl(b,sslp) BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp) +#define BIO_set_ssl_mode(b,client) BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL) +#define BIO_set_ssl_renegotiate_bytes(b,num) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL); +#define BIO_get_num_renegotiates(b) \ + BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL); +#define BIO_set_ssl_renegotiate_timeout(b,seconds) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL); + +/* defined in evp.h */ +/* #define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */ + +#define BIO_get_mem_data(b,pp) BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp) +#define BIO_set_mem_buf(b,bm,c) BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)bm) +#define BIO_get_mem_ptr(b,pp) BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0,(char *)pp) +#define BIO_set_mem_eof_return(b,v) \ + BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL) + +/* For the BIO_f_buffer() type */ +#define BIO_get_buffer_num_lines(b) BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL) +#define BIO_set_buffer_size(b,size) BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL) +#define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0) +#define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1) +#define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf) + +/* Don't use the next one unless you know what you are doing :-) */ +#define BIO_dup_state(b,ret) BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret)) + +#define BIO_reset(b) (int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL) +#define BIO_eof(b) (int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL) +#define BIO_set_close(b,c) (int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL) +#define BIO_get_close(b) (int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL) +#define BIO_pending(b) (int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL) +#define BIO_wpending(b) (int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL) +/* ...pending macros have inappropriate return type */ +size_t BIO_ctrl_pending(BIO *b); +size_t BIO_ctrl_wpending(BIO *b); +#define BIO_flush(b) (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL) +#define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \ + cbp) +#define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb) + +/* For the BIO_f_buffer() type */ +#define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL) + +/* For BIO_s_bio() */ +#define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL) +#define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL) +#define BIO_make_bio_pair(b1,b2) (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2) +#define BIO_destroy_bio_pair(b) (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL) +#define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL) +/* macros with inappropriate type -- but ...pending macros use int too: */ +#define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL) +#define BIO_get_read_request(b) (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL) +size_t BIO_ctrl_get_write_guarantee(BIO *b); +size_t BIO_ctrl_get_read_request(BIO *b); +int BIO_ctrl_reset_read_request(BIO *b); + +/* ctrl macros for dgram */ +#define BIO_ctrl_dgram_connect(b,peer) \ + (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)peer) +#define BIO_ctrl_set_connected(b, state, peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, state, (char *)peer) +#define BIO_dgram_recv_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL) +#define BIO_dgram_send_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL) +#define BIO_dgram_get_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer) +#define BIO_dgram_set_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer) + +/* These two aren't currently implemented */ +/* int BIO_get_ex_num(BIO *bio); */ +/* void BIO_set_ex_free_func(BIO *bio,int idx,void (*cb)()); */ +int BIO_set_ex_data(BIO *bio,int idx,void *data); +void *BIO_get_ex_data(BIO *bio,int idx); +int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +unsigned long BIO_number_read(BIO *bio); +unsigned long BIO_number_written(BIO *bio); + +/* For BIO_f_asn1() */ +int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, + asn1_ps_func *prefix_free); +int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, + asn1_ps_func **pprefix_free); +int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, + asn1_ps_func *suffix_free); +int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, + asn1_ps_func **psuffix_free); + +# ifndef OPENSSL_NO_FP_API +BIO_METHOD *BIO_s_file(void ); +BIO *BIO_new_file(const char *filename, const char *mode); +BIO *BIO_new_fp(FILE *stream, int close_flag); +# define BIO_s_file_internal BIO_s_file +# endif +BIO * BIO_new(BIO_METHOD *type); +int BIO_set(BIO *a,BIO_METHOD *type); +int BIO_free(BIO *a); +void BIO_vfree(BIO *a); +int BIO_read(BIO *b, void *data, int len); +int BIO_gets(BIO *bp,char *buf, int size); +int BIO_write(BIO *b, const void *data, int len); +int BIO_puts(BIO *bp,const char *buf); +int BIO_indent(BIO *b,int indent,int max); +long BIO_ctrl(BIO *bp,int cmd,long larg,void *parg); +long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)(struct bio_st *, int, const char *, int, long, long)); +char * BIO_ptr_ctrl(BIO *bp,int cmd,long larg); +long BIO_int_ctrl(BIO *bp,int cmd,long larg,int iarg); +BIO * BIO_push(BIO *b,BIO *append); +BIO * BIO_pop(BIO *b); +void BIO_free_all(BIO *a); +BIO * BIO_find_type(BIO *b,int bio_type); +BIO * BIO_next(BIO *b); +BIO * BIO_get_retry_BIO(BIO *bio, int *reason); +int BIO_get_retry_reason(BIO *bio); +BIO * BIO_dup_chain(BIO *in); + +int BIO_nread0(BIO *bio, char **buf); +int BIO_nread(BIO *bio, char **buf, int num); +int BIO_nwrite0(BIO *bio, char **buf); +int BIO_nwrite(BIO *bio, char **buf, int num); + +long BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi, + long argl,long ret); + +BIO_METHOD *BIO_s_mem(void); +BIO *BIO_new_mem_buf(void *buf, int len); +BIO_METHOD *BIO_s_socket(void); +BIO_METHOD *BIO_s_connect(void); +BIO_METHOD *BIO_s_accept(void); +BIO_METHOD *BIO_s_fd(void); +#ifndef OPENSSL_SYS_OS2 +BIO_METHOD *BIO_s_log(void); +#endif +BIO_METHOD *BIO_s_bio(void); +BIO_METHOD *BIO_s_null(void); +BIO_METHOD *BIO_f_null(void); +BIO_METHOD *BIO_f_buffer(void); +#ifdef OPENSSL_SYS_VMS +BIO_METHOD *BIO_f_linebuffer(void); +#endif +BIO_METHOD *BIO_f_nbio_test(void); +#ifndef OPENSSL_NO_DGRAM +BIO_METHOD *BIO_s_datagram(void); +#endif + +/* BIO_METHOD *BIO_f_ber(void); */ + +int BIO_sock_should_retry(int i); +int BIO_sock_non_fatal_error(int error); +int BIO_dgram_non_fatal_error(int error); + +int BIO_fd_should_retry(int i); +int BIO_fd_non_fatal_error(int error); +int BIO_dump_cb(int (*cb)(const void *data, size_t len, void *u), + void *u, const char *s, int len); +int BIO_dump_indent_cb(int (*cb)(const void *data, size_t len, void *u), + void *u, const char *s, int len, int indent); +int BIO_dump(BIO *b,const char *bytes,int len); +int BIO_dump_indent(BIO *b,const char *bytes,int len,int indent); +#ifndef OPENSSL_NO_FP_API +int BIO_dump_fp(FILE *fp, const char *s, int len); +int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent); +#endif +struct hostent *BIO_gethostbyname(const char *name); +/* We might want a thread-safe interface too: + * struct hostent *BIO_gethostbyname_r(const char *name, + * struct hostent *result, void *buffer, size_t buflen); + * or something similar (caller allocates a struct hostent, + * pointed to by "result", and additional buffer space for the various + * substructures; if the buffer does not suffice, NULL is returned + * and an appropriate error code is set). + */ +int BIO_sock_error(int sock); +int BIO_socket_ioctl(int fd, long type, void *arg); +int BIO_socket_nbio(int fd,int mode); +int BIO_get_port(const char *str, unsigned short *port_ptr); +int BIO_get_host_ip(const char *str, unsigned char *ip); +int BIO_get_accept_socket(char *host_port,int mode); +int BIO_accept(int sock,char **ip_port); +int BIO_sock_init(void ); +void BIO_sock_cleanup(void); +int BIO_set_tcp_ndelay(int sock,int turn_on); + +BIO *BIO_new_socket(int sock, int close_flag); +BIO *BIO_new_dgram(int fd, int close_flag); +BIO *BIO_new_fd(int fd, int close_flag); +BIO *BIO_new_connect(char *host_port); +BIO *BIO_new_accept(char *host_port); + +int BIO_new_bio_pair(BIO **bio1, size_t writebuf1, + BIO **bio2, size_t writebuf2); +/* If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints. + * Otherwise returns 0 and sets *bio1 and *bio2 to NULL. + * Size 0 uses default value. + */ + +void BIO_copy_next_retry(BIO *b); + +/*long BIO_ghbn_ctrl(int cmd,int iarg,char *parg);*/ + +#ifdef __GNUC__ +# define __bio_h__attr__ __attribute__ +#else +# define __bio_h__attr__(x) +#endif +int BIO_printf(BIO *bio, const char *format, ...) + __bio_h__attr__((__format__(__printf__,2,3))); +int BIO_vprintf(BIO *bio, const char *format, va_list args) + __bio_h__attr__((__format__(__printf__,2,0))); +int BIO_snprintf(char *buf, size_t n, const char *format, ...) + __bio_h__attr__((__format__(__printf__,3,4))); +int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) + __bio_h__attr__((__format__(__printf__,3,0))); +#undef __bio_h__attr__ + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_BIO_strings(void); + +/* Error codes for the BIO functions. */ + +/* Function codes. */ +#define BIO_F_ACPT_STATE 100 +#define BIO_F_BIO_ACCEPT 101 +#define BIO_F_BIO_BER_GET_HEADER 102 +#define BIO_F_BIO_CALLBACK_CTRL 131 +#define BIO_F_BIO_CTRL 103 +#define BIO_F_BIO_GETHOSTBYNAME 120 +#define BIO_F_BIO_GETS 104 +#define BIO_F_BIO_GET_ACCEPT_SOCKET 105 +#define BIO_F_BIO_GET_HOST_IP 106 +#define BIO_F_BIO_GET_PORT 107 +#define BIO_F_BIO_MAKE_PAIR 121 +#define BIO_F_BIO_NEW 108 +#define BIO_F_BIO_NEW_FILE 109 +#define BIO_F_BIO_NEW_MEM_BUF 126 +#define BIO_F_BIO_NREAD 123 +#define BIO_F_BIO_NREAD0 124 +#define BIO_F_BIO_NWRITE 125 +#define BIO_F_BIO_NWRITE0 122 +#define BIO_F_BIO_PUTS 110 +#define BIO_F_BIO_READ 111 +#define BIO_F_BIO_SOCK_INIT 112 +#define BIO_F_BIO_WRITE 113 +#define BIO_F_BUFFER_CTRL 114 +#define BIO_F_CONN_CTRL 127 +#define BIO_F_CONN_STATE 115 +#define BIO_F_FILE_CTRL 116 +#define BIO_F_FILE_READ 130 +#define BIO_F_LINEBUFFER_CTRL 129 +#define BIO_F_MEM_READ 128 +#define BIO_F_MEM_WRITE 117 +#define BIO_F_SSL_NEW 118 +#define BIO_F_WSASTARTUP 119 + +/* Reason codes. */ +#define BIO_R_ACCEPT_ERROR 100 +#define BIO_R_BAD_FOPEN_MODE 101 +#define BIO_R_BAD_HOSTNAME_LOOKUP 102 +#define BIO_R_BROKEN_PIPE 124 +#define BIO_R_CONNECT_ERROR 103 +#define BIO_R_EOF_ON_MEMORY_BIO 127 +#define BIO_R_ERROR_SETTING_NBIO 104 +#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET 105 +#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET 106 +#define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107 +#define BIO_R_INVALID_ARGUMENT 125 +#define BIO_R_INVALID_IP_ADDRESS 108 +#define BIO_R_IN_USE 123 +#define BIO_R_KEEPALIVE 109 +#define BIO_R_NBIO_CONNECT_ERROR 110 +#define BIO_R_NO_ACCEPT_PORT_SPECIFIED 111 +#define BIO_R_NO_HOSTNAME_SPECIFIED 112 +#define BIO_R_NO_PORT_DEFINED 113 +#define BIO_R_NO_PORT_SPECIFIED 114 +#define BIO_R_NO_SUCH_FILE 128 +#define BIO_R_NULL_PARAMETER 115 +#define BIO_R_TAG_MISMATCH 116 +#define BIO_R_UNABLE_TO_BIND_SOCKET 117 +#define BIO_R_UNABLE_TO_CREATE_SOCKET 118 +#define BIO_R_UNABLE_TO_LISTEN_SOCKET 119 +#define BIO_R_UNINITIALIZED 120 +#define BIO_R_UNSUPPORTED_METHOD 121 +#define BIO_R_WRITE_TO_READ_ONLY_BIO 126 +#define BIO_R_WSASTARTUP 122 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/bn.h b/extra_lib/include/openssl/bn.h new file mode 100644 index 0000000..e484b7f --- /dev/null +++ b/extra_lib/include/openssl/bn.h @@ -0,0 +1,858 @@ +/* crypto/bn/bn.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the Eric Young open source + * license provided above. + * + * The binary polynomial arithmetic software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#ifndef HEADER_BN_H +#define HEADER_BN_H + +#include +#ifndef OPENSSL_NO_FP_API +#include /* FILE */ +#endif +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* These preprocessor symbols control various aspects of the bignum headers and + * library code. They're not defined by any "normal" configuration, as they are + * intended for development and testing purposes. NB: defining all three can be + * useful for debugging application code as well as openssl itself. + * + * BN_DEBUG - turn on various debugging alterations to the bignum code + * BN_DEBUG_RAND - uses random poisoning of unused words to trip up + * mismanagement of bignum internals. You must also define BN_DEBUG. + */ +/* #define BN_DEBUG */ +/* #define BN_DEBUG_RAND */ + +#ifndef OPENSSL_SMALL_FOOTPRINT +#define BN_MUL_COMBA +#define BN_SQR_COMBA +#define BN_RECURSION +#endif + +/* This next option uses the C libraries (2 word)/(1 word) function. + * If it is not defined, I use my C version (which is slower). + * The reason for this flag is that when the particular C compiler + * library routine is used, and the library is linked with a different + * compiler, the library is missing. This mostly happens when the + * library is built with gcc and then linked using normal cc. This would + * be a common occurrence because gcc normally produces code that is + * 2 times faster than system compilers for the big number stuff. + * For machines with only one compiler (or shared libraries), this should + * be on. Again this in only really a problem on machines + * using "long long's", are 32bit, and are not using my assembler code. */ +#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || \ + defined(OPENSSL_SYS_WIN32) || defined(linux) +# ifndef BN_DIV2W +# define BN_DIV2W +# endif +#endif + +/* assuming long is 64bit - this is the DEC Alpha + * unsigned long long is only 64 bits :-(, don't define + * BN_LLONG for the DEC Alpha */ +#ifdef SIXTY_FOUR_BIT_LONG +#define BN_ULLONG unsigned long long +#define BN_ULONG unsigned long +#define BN_LONG long +#define BN_BITS 128 +#define BN_BYTES 8 +#define BN_BITS2 64 +#define BN_BITS4 32 +#define BN_MASK (0xffffffffffffffffffffffffffffffffLL) +#define BN_MASK2 (0xffffffffffffffffL) +#define BN_MASK2l (0xffffffffL) +#define BN_MASK2h (0xffffffff00000000L) +#define BN_MASK2h1 (0xffffffff80000000L) +#define BN_TBIT (0x8000000000000000L) +#define BN_DEC_CONV (10000000000000000000UL) +#define BN_DEC_FMT1 "%lu" +#define BN_DEC_FMT2 "%019lu" +#define BN_DEC_NUM 19 +#define BN_HEX_FMT1 "%lX" +#define BN_HEX_FMT2 "%016lX" +#endif + +/* This is where the long long data type is 64 bits, but long is 32. + * For machines where there are 64bit registers, this is the mode to use. + * IRIX, on R4000 and above should use this mode, along with the relevant + * assembler code :-). Do NOT define BN_LLONG. + */ +#ifdef SIXTY_FOUR_BIT +#undef BN_LLONG +#undef BN_ULLONG +#define BN_ULONG unsigned long long +#define BN_LONG long long +#define BN_BITS 128 +#define BN_BYTES 8 +#define BN_BITS2 64 +#define BN_BITS4 32 +#define BN_MASK2 (0xffffffffffffffffLL) +#define BN_MASK2l (0xffffffffL) +#define BN_MASK2h (0xffffffff00000000LL) +#define BN_MASK2h1 (0xffffffff80000000LL) +#define BN_TBIT (0x8000000000000000LL) +#define BN_DEC_CONV (10000000000000000000ULL) +#define BN_DEC_FMT1 "%llu" +#define BN_DEC_FMT2 "%019llu" +#define BN_DEC_NUM 19 +#define BN_HEX_FMT1 "%llX" +#define BN_HEX_FMT2 "%016llX" +#endif + +#ifdef THIRTY_TWO_BIT +#ifdef BN_LLONG +# if defined(_WIN32) && !defined(__GNUC__) +# define BN_ULLONG unsigned __int64 +# define BN_MASK (0xffffffffffffffffI64) +# else +# define BN_ULLONG unsigned long long +# define BN_MASK (0xffffffffffffffffLL) +# endif +#endif +#define BN_ULONG unsigned int +#define BN_LONG int +#define BN_BITS 64 +#define BN_BYTES 4 +#define BN_BITS2 32 +#define BN_BITS4 16 +#define BN_MASK2 (0xffffffffL) +#define BN_MASK2l (0xffff) +#define BN_MASK2h1 (0xffff8000L) +#define BN_MASK2h (0xffff0000L) +#define BN_TBIT (0x80000000L) +#define BN_DEC_CONV (1000000000L) +#define BN_DEC_FMT1 "%u" +#define BN_DEC_FMT2 "%09u" +#define BN_DEC_NUM 9 +#define BN_HEX_FMT1 "%X" +#define BN_HEX_FMT2 "%08X" +#endif + +#define BN_DEFAULT_BITS 1280 + +#define BN_FLG_MALLOCED 0x01 +#define BN_FLG_STATIC_DATA 0x02 +#define BN_FLG_CONSTTIME 0x04 /* avoid leaking exponent information through timing, + * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime, + * BN_div() will call BN_div_no_branch, + * BN_mod_inverse() will call BN_mod_inverse_no_branch. + */ + +#ifndef OPENSSL_NO_DEPRECATED +#define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME /* deprecated name for the flag */ + /* avoid leaking exponent information through timings + * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) */ +#endif + +#ifndef OPENSSL_NO_DEPRECATED +#define BN_FLG_FREE 0x8000 /* used for debuging */ +#endif +#define BN_set_flags(b,n) ((b)->flags|=(n)) +#define BN_get_flags(b,n) ((b)->flags&(n)) + +/* get a clone of a BIGNUM with changed flags, for *temporary* use only + * (the two BIGNUMs cannot not be used in parallel!) */ +#define BN_with_flags(dest,b,n) ((dest)->d=(b)->d, \ + (dest)->top=(b)->top, \ + (dest)->dmax=(b)->dmax, \ + (dest)->neg=(b)->neg, \ + (dest)->flags=(((dest)->flags & BN_FLG_MALLOCED) \ + | ((b)->flags & ~BN_FLG_MALLOCED) \ + | BN_FLG_STATIC_DATA \ + | (n))) + +/* Already declared in ossl_typ.h */ +#if 0 +typedef struct bignum_st BIGNUM; +/* Used for temp variables (declaration hidden in bn_lcl.h) */ +typedef struct bignum_ctx BN_CTX; +typedef struct bn_blinding_st BN_BLINDING; +typedef struct bn_mont_ctx_st BN_MONT_CTX; +typedef struct bn_recp_ctx_st BN_RECP_CTX; +typedef struct bn_gencb_st BN_GENCB; +#endif + +struct bignum_st + { + BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */ + int top; /* Index of last used d +1. */ + /* The next are internal book keeping for bn_expand. */ + int dmax; /* Size of the d array. */ + int neg; /* one if the number is negative */ + int flags; + }; + +/* Used for montgomery multiplication */ +struct bn_mont_ctx_st + { + int ri; /* number of bits in R */ + BIGNUM RR; /* used to convert to montgomery form */ + BIGNUM N; /* The modulus */ + BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1 + * (Ni is only stored for bignum algorithm) */ + BN_ULONG n0[2];/* least significant word(s) of Ni; + (type changed with 0.9.9, was "BN_ULONG n0;" before) */ + int flags; + }; + +/* Used for reciprocal division/mod functions + * It cannot be shared between threads + */ +struct bn_recp_ctx_st + { + BIGNUM N; /* the divisor */ + BIGNUM Nr; /* the reciprocal */ + int num_bits; + int shift; + int flags; + }; + +/* Used for slow "generation" functions. */ +struct bn_gencb_st + { + unsigned int ver; /* To handle binary (in)compatibility */ + void *arg; /* callback-specific data */ + union + { + /* if(ver==1) - handles old style callbacks */ + void (*cb_1)(int, int, void *); + /* if(ver==2) - new callback style */ + int (*cb_2)(int, int, BN_GENCB *); + } cb; + }; +/* Wrapper function to make using BN_GENCB easier, */ +int BN_GENCB_call(BN_GENCB *cb, int a, int b); +/* Macro to populate a BN_GENCB structure with an "old"-style callback */ +#define BN_GENCB_set_old(gencb, callback, cb_arg) { \ + BN_GENCB *tmp_gencb = (gencb); \ + tmp_gencb->ver = 1; \ + tmp_gencb->arg = (cb_arg); \ + tmp_gencb->cb.cb_1 = (callback); } +/* Macro to populate a BN_GENCB structure with a "new"-style callback */ +#define BN_GENCB_set(gencb, callback, cb_arg) { \ + BN_GENCB *tmp_gencb = (gencb); \ + tmp_gencb->ver = 2; \ + tmp_gencb->arg = (cb_arg); \ + tmp_gencb->cb.cb_2 = (callback); } + +#define BN_prime_checks 0 /* default: select number of iterations + based on the size of the number */ + +/* number of Miller-Rabin iterations for an error rate of less than 2^-80 + * for random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook + * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996]; + * original paper: Damgaard, Landrock, Pomerance: Average case error estimates + * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */ +#define BN_prime_checks_for_size(b) ((b) >= 1300 ? 2 : \ + (b) >= 850 ? 3 : \ + (b) >= 650 ? 4 : \ + (b) >= 550 ? 5 : \ + (b) >= 450 ? 6 : \ + (b) >= 400 ? 7 : \ + (b) >= 350 ? 8 : \ + (b) >= 300 ? 9 : \ + (b) >= 250 ? 12 : \ + (b) >= 200 ? 15 : \ + (b) >= 150 ? 18 : \ + /* b >= 100 */ 27) + +#define BN_num_bytes(a) ((BN_num_bits(a)+7)/8) + +/* Note that BN_abs_is_word didn't work reliably for w == 0 until 0.9.8 */ +#define BN_abs_is_word(a,w) ((((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) || \ + (((w) == 0) && ((a)->top == 0))) +#define BN_is_zero(a) ((a)->top == 0) +#define BN_is_one(a) (BN_abs_is_word((a),1) && !(a)->neg) +#define BN_is_word(a,w) (BN_abs_is_word((a),(w)) && (!(w) || !(a)->neg)) +#define BN_is_odd(a) (((a)->top > 0) && ((a)->d[0] & 1)) + +#define BN_one(a) (BN_set_word((a),1)) +#define BN_zero_ex(a) \ + do { \ + BIGNUM *_tmp_bn = (a); \ + _tmp_bn->top = 0; \ + _tmp_bn->neg = 0; \ + } while(0) +#ifdef OPENSSL_NO_DEPRECATED +#define BN_zero(a) BN_zero_ex(a) +#else +#define BN_zero(a) (BN_set_word((a),0)) +#endif + +const BIGNUM *BN_value_one(void); +char * BN_options(void); +BN_CTX *BN_CTX_new(void); +#ifndef OPENSSL_NO_DEPRECATED +void BN_CTX_init(BN_CTX *c); +#endif +void BN_CTX_free(BN_CTX *c); +void BN_CTX_start(BN_CTX *ctx); +BIGNUM *BN_CTX_get(BN_CTX *ctx); +void BN_CTX_end(BN_CTX *ctx); +int BN_rand(BIGNUM *rnd, int bits, int top,int bottom); +int BN_pseudo_rand(BIGNUM *rnd, int bits, int top,int bottom); +int BN_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_num_bits(const BIGNUM *a); +int BN_num_bits_word(BN_ULONG); +BIGNUM *BN_new(void); +void BN_init(BIGNUM *); +void BN_clear_free(BIGNUM *a); +BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b); +void BN_swap(BIGNUM *a, BIGNUM *b); +BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret); +int BN_bn2bin(const BIGNUM *a, unsigned char *to); +BIGNUM *BN_mpi2bn(const unsigned char *s,int len,BIGNUM *ret); +int BN_bn2mpi(const BIGNUM *a, unsigned char *to); +int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int BN_sqr(BIGNUM *r, const BIGNUM *a,BN_CTX *ctx); +/** BN_set_negative sets sign of a BIGNUM + * \param b pointer to the BIGNUM object + * \param n 0 if the BIGNUM b should be positive and a value != 0 otherwise + */ +void BN_set_negative(BIGNUM *b, int n); +/** BN_is_negative returns 1 if the BIGNUM is negative + * \param a pointer to the BIGNUM object + * \return 1 if a < 0 and 0 otherwise + */ +#define BN_is_negative(a) ((a)->neg != 0) + +int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, + BN_CTX *ctx); +#define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx)) +int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx); +int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m); +int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m); +int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx); +int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m); +int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m); + +BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w); +BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w); +int BN_mul_word(BIGNUM *a, BN_ULONG w); +int BN_add_word(BIGNUM *a, BN_ULONG w); +int BN_sub_word(BIGNUM *a, BN_ULONG w); +int BN_set_word(BIGNUM *a, BN_ULONG w); +BN_ULONG BN_get_word(const BIGNUM *a); + +int BN_cmp(const BIGNUM *a, const BIGNUM *b); +void BN_free(BIGNUM *a); +int BN_is_bit_set(const BIGNUM *a, int n); +int BN_lshift(BIGNUM *r, const BIGNUM *a, int n); +int BN_lshift1(BIGNUM *r, const BIGNUM *a); +int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,BN_CTX *ctx); + +int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m,BN_CTX *ctx); +int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont); +int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1, + const BIGNUM *a2, const BIGNUM *p2,const BIGNUM *m, + BN_CTX *ctx,BN_MONT_CTX *m_ctx); +int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m,BN_CTX *ctx); + +int BN_mask_bits(BIGNUM *a,int n); +#ifndef OPENSSL_NO_FP_API +int BN_print_fp(FILE *fp, const BIGNUM *a); +#endif +#ifdef HEADER_BIO_H +int BN_print(BIO *fp, const BIGNUM *a); +#else +int BN_print(void *fp, const BIGNUM *a); +#endif +int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx); +int BN_rshift(BIGNUM *r, const BIGNUM *a, int n); +int BN_rshift1(BIGNUM *r, const BIGNUM *a); +void BN_clear(BIGNUM *a); +BIGNUM *BN_dup(const BIGNUM *a); +int BN_ucmp(const BIGNUM *a, const BIGNUM *b); +int BN_set_bit(BIGNUM *a, int n); +int BN_clear_bit(BIGNUM *a, int n); +char * BN_bn2hex(const BIGNUM *a); +char * BN_bn2dec(const BIGNUM *a); +int BN_hex2bn(BIGNUM **a, const char *str); +int BN_dec2bn(BIGNUM **a, const char *str); +int BN_asc2bn(BIGNUM **a, const char *str); +int BN_gcd(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx); +int BN_kronecker(const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx); /* returns -2 for error */ +BIGNUM *BN_mod_inverse(BIGNUM *ret, + const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx); +BIGNUM *BN_mod_sqrt(BIGNUM *ret, + const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx); + +/* Deprecated versions */ +#ifndef OPENSSL_NO_DEPRECATED +BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe, + const BIGNUM *add, const BIGNUM *rem, + void (*callback)(int,int,void *),void *cb_arg); +int BN_is_prime(const BIGNUM *p,int nchecks, + void (*callback)(int,int,void *), + BN_CTX *ctx,void *cb_arg); +int BN_is_prime_fasttest(const BIGNUM *p,int nchecks, + void (*callback)(int,int,void *),BN_CTX *ctx,void *cb_arg, + int do_trial_division); +#endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* Newer versions */ +int BN_generate_prime_ex(BIGNUM *ret,int bits,int safe, const BIGNUM *add, + const BIGNUM *rem, BN_GENCB *cb); +int BN_is_prime_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx, BN_GENCB *cb); +int BN_is_prime_fasttest_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx, + int do_trial_division, BN_GENCB *cb); + +BN_MONT_CTX *BN_MONT_CTX_new(void ); +void BN_MONT_CTX_init(BN_MONT_CTX *ctx); +int BN_mod_mul_montgomery(BIGNUM *r,const BIGNUM *a,const BIGNUM *b, + BN_MONT_CTX *mont, BN_CTX *ctx); +#define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\ + (r),(a),&((mont)->RR),(mont),(ctx)) +int BN_from_montgomery(BIGNUM *r,const BIGNUM *a, + BN_MONT_CTX *mont, BN_CTX *ctx); +void BN_MONT_CTX_free(BN_MONT_CTX *mont); +int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *mod,BN_CTX *ctx); +BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from); +BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, + const BIGNUM *mod, BN_CTX *ctx); + +/* BN_BLINDING flags */ +#define BN_BLINDING_NO_UPDATE 0x00000001 +#define BN_BLINDING_NO_RECREATE 0x00000002 + +BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod); +void BN_BLINDING_free(BN_BLINDING *b); +int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx); +int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *); +int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *); +#ifndef OPENSSL_NO_DEPRECATED +unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *); +void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long); +#endif +CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *); +unsigned long BN_BLINDING_get_flags(const BN_BLINDING *); +void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long); +BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, + const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, + int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx), + BN_MONT_CTX *m_ctx); + +#ifndef OPENSSL_NO_DEPRECATED +void BN_set_params(int mul,int high,int low,int mont); +int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */ +#endif + +void BN_RECP_CTX_init(BN_RECP_CTX *recp); +BN_RECP_CTX *BN_RECP_CTX_new(void); +void BN_RECP_CTX_free(BN_RECP_CTX *recp); +int BN_RECP_CTX_set(BN_RECP_CTX *recp,const BIGNUM *rdiv,BN_CTX *ctx); +int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, + BN_RECP_CTX *recp,BN_CTX *ctx); +int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, + BN_RECP_CTX *recp, BN_CTX *ctx); + +/* Functions for arithmetic over binary polynomials represented by BIGNUMs. + * + * The BIGNUM::neg property of BIGNUMs representing binary polynomials is + * ignored. + * + * Note that input arguments are not const so that their bit arrays can + * be expanded to the appropriate size if needed. + */ + +int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); /*r = a + b*/ +#define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b) +int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p); /*r=a mod p*/ +int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); /* r = (a * b) mod p */ +int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); /* r = (a * a) mod p */ +int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p, + BN_CTX *ctx); /* r = (1 / b) mod p */ +int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); /* r = (a / b) mod p */ +int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); /* r = (a ^ b) mod p */ +int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); /* r = sqrt(a) mod p */ +int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); /* r^2 + r = a mod p */ +#define BN_GF2m_cmp(a, b) BN_ucmp((a), (b)) +/* Some functions allow for representation of the irreducible polynomials + * as an unsigned int[], say p. The irreducible f(t) is then of the form: + * t^p[0] + t^p[1] + ... + t^p[k] + * where m = p[0] > p[1] > ... > p[k] = 0. + */ +int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]); + /* r = a mod p */ +int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); /* r = (a * b) mod p */ +int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], + BN_CTX *ctx); /* r = (a * a) mod p */ +int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[], + BN_CTX *ctx); /* r = (1 / b) mod p */ +int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); /* r = (a / b) mod p */ +int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); /* r = (a ^ b) mod p */ +int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, + const int p[], BN_CTX *ctx); /* r = sqrt(a) mod p */ +int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a, + const int p[], BN_CTX *ctx); /* r^2 + r = a mod p */ +int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max); +int BN_GF2m_arr2poly(const int p[], BIGNUM *a); + +/* faster mod functions for the 'NIST primes' + * 0 <= a < p^2 */ +int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); + +const BIGNUM *BN_get0_nist_prime_192(void); +const BIGNUM *BN_get0_nist_prime_224(void); +const BIGNUM *BN_get0_nist_prime_256(void); +const BIGNUM *BN_get0_nist_prime_384(void); +const BIGNUM *BN_get0_nist_prime_521(void); + +/* library internal functions */ + +#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\ + (a):bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2)) +#define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words))) +BIGNUM *bn_expand2(BIGNUM *a, int words); +#ifndef OPENSSL_NO_DEPRECATED +BIGNUM *bn_dup_expand(const BIGNUM *a, int words); /* unused */ +#endif + +/* Bignum consistency macros + * There is one "API" macro, bn_fix_top(), for stripping leading zeroes from + * bignum data after direct manipulations on the data. There is also an + * "internal" macro, bn_check_top(), for verifying that there are no leading + * zeroes. Unfortunately, some auditing is required due to the fact that + * bn_fix_top() has become an overabused duct-tape because bignum data is + * occasionally passed around in an inconsistent state. So the following + * changes have been made to sort this out; + * - bn_fix_top()s implementation has been moved to bn_correct_top() + * - if BN_DEBUG isn't defined, bn_fix_top() maps to bn_correct_top(), and + * bn_check_top() is as before. + * - if BN_DEBUG *is* defined; + * - bn_check_top() tries to pollute unused words even if the bignum 'top' is + * consistent. (ed: only if BN_DEBUG_RAND is defined) + * - bn_fix_top() maps to bn_check_top() rather than "fixing" anything. + * The idea is to have debug builds flag up inconsistent bignums when they + * occur. If that occurs in a bn_fix_top(), we examine the code in question; if + * the use of bn_fix_top() was appropriate (ie. it follows directly after code + * that manipulates the bignum) it is converted to bn_correct_top(), and if it + * was not appropriate, we convert it permanently to bn_check_top() and track + * down the cause of the bug. Eventually, no internal code should be using the + * bn_fix_top() macro. External applications and libraries should try this with + * their own code too, both in terms of building against the openssl headers + * with BN_DEBUG defined *and* linking with a version of OpenSSL built with it + * defined. This not only improves external code, it provides more test + * coverage for openssl's own code. + */ + +#ifdef BN_DEBUG + +/* We only need assert() when debugging */ +#include + +#ifdef BN_DEBUG_RAND +/* To avoid "make update" cvs wars due to BN_DEBUG, use some tricks */ +#ifndef RAND_pseudo_bytes +int RAND_pseudo_bytes(unsigned char *buf,int num); +#define BN_DEBUG_TRIX +#endif +#define bn_pollute(a) \ + do { \ + const BIGNUM *_bnum1 = (a); \ + if(_bnum1->top < _bnum1->dmax) { \ + unsigned char _tmp_char; \ + /* We cast away const without the compiler knowing, any \ + * *genuinely* constant variables that aren't mutable \ + * wouldn't be constructed with top!=dmax. */ \ + BN_ULONG *_not_const; \ + memcpy(&_not_const, &_bnum1->d, sizeof(BN_ULONG*)); \ + RAND_pseudo_bytes(&_tmp_char, 1); \ + memset((unsigned char *)(_not_const + _bnum1->top), _tmp_char, \ + (_bnum1->dmax - _bnum1->top) * sizeof(BN_ULONG)); \ + } \ + } while(0) +#ifdef BN_DEBUG_TRIX +#undef RAND_pseudo_bytes +#endif +#else +#define bn_pollute(a) +#endif +#define bn_check_top(a) \ + do { \ + const BIGNUM *_bnum2 = (a); \ + if (_bnum2 != NULL) { \ + assert((_bnum2->top == 0) || \ + (_bnum2->d[_bnum2->top - 1] != 0)); \ + bn_pollute(_bnum2); \ + } \ + } while(0) + +#define bn_fix_top(a) bn_check_top(a) + +#else /* !BN_DEBUG */ + +#define bn_pollute(a) +#define bn_check_top(a) +#define bn_fix_top(a) bn_correct_top(a) + +#endif + +#define bn_correct_top(a) \ + { \ + BN_ULONG *ftl; \ + int tmp_top = (a)->top; \ + if (tmp_top > 0) \ + { \ + for (ftl= &((a)->d[tmp_top-1]); tmp_top > 0; tmp_top--) \ + if (*(ftl--)) break; \ + (a)->top = tmp_top; \ + } \ + bn_pollute(a); \ + } + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w); +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w); +void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num); +BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d); +BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num); +BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num); + +/* Primes from RFC 2409 */ +BIGNUM *get_rfc2409_prime_768(BIGNUM *bn); +BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn); + +/* Primes from RFC 3526 */ +BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn); + +int BN_bntest_rand(BIGNUM *rnd, int bits, int top,int bottom); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_BN_strings(void); + +/* Error codes for the BN functions. */ + +/* Function codes. */ +#define BN_F_BNRAND 127 +#define BN_F_BN_BLINDING_CONVERT_EX 100 +#define BN_F_BN_BLINDING_CREATE_PARAM 128 +#define BN_F_BN_BLINDING_INVERT_EX 101 +#define BN_F_BN_BLINDING_NEW 102 +#define BN_F_BN_BLINDING_UPDATE 103 +#define BN_F_BN_BN2DEC 104 +#define BN_F_BN_BN2HEX 105 +#define BN_F_BN_CTX_GET 116 +#define BN_F_BN_CTX_NEW 106 +#define BN_F_BN_CTX_START 129 +#define BN_F_BN_DIV 107 +#define BN_F_BN_DIV_NO_BRANCH 138 +#define BN_F_BN_DIV_RECP 130 +#define BN_F_BN_EXP 123 +#define BN_F_BN_EXPAND2 108 +#define BN_F_BN_EXPAND_INTERNAL 120 +#define BN_F_BN_GF2M_MOD 131 +#define BN_F_BN_GF2M_MOD_EXP 132 +#define BN_F_BN_GF2M_MOD_MUL 133 +#define BN_F_BN_GF2M_MOD_SOLVE_QUAD 134 +#define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR 135 +#define BN_F_BN_GF2M_MOD_SQR 136 +#define BN_F_BN_GF2M_MOD_SQRT 137 +#define BN_F_BN_MOD_EXP2_MONT 118 +#define BN_F_BN_MOD_EXP_MONT 109 +#define BN_F_BN_MOD_EXP_MONT_CONSTTIME 124 +#define BN_F_BN_MOD_EXP_MONT_WORD 117 +#define BN_F_BN_MOD_EXP_RECP 125 +#define BN_F_BN_MOD_EXP_SIMPLE 126 +#define BN_F_BN_MOD_INVERSE 110 +#define BN_F_BN_MOD_INVERSE_NO_BRANCH 139 +#define BN_F_BN_MOD_LSHIFT_QUICK 119 +#define BN_F_BN_MOD_MUL_RECIPROCAL 111 +#define BN_F_BN_MOD_SQRT 121 +#define BN_F_BN_MPI2BN 112 +#define BN_F_BN_NEW 113 +#define BN_F_BN_RAND 114 +#define BN_F_BN_RAND_RANGE 122 +#define BN_F_BN_USUB 115 + +/* Reason codes. */ +#define BN_R_ARG2_LT_ARG3 100 +#define BN_R_BAD_RECIPROCAL 101 +#define BN_R_BIGNUM_TOO_LONG 114 +#define BN_R_CALLED_WITH_EVEN_MODULUS 102 +#define BN_R_DIV_BY_ZERO 103 +#define BN_R_ENCODING_ERROR 104 +#define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 105 +#define BN_R_INPUT_NOT_REDUCED 110 +#define BN_R_INVALID_LENGTH 106 +#define BN_R_INVALID_RANGE 115 +#define BN_R_NOT_A_SQUARE 111 +#define BN_R_NOT_INITIALIZED 107 +#define BN_R_NO_INVERSE 108 +#define BN_R_NO_SOLUTION 116 +#define BN_R_P_IS_NOT_PRIME 112 +#define BN_R_TOO_MANY_ITERATIONS 113 +#define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/buffer.h b/extra_lib/include/openssl/buffer.h new file mode 100644 index 0000000..178e418 --- /dev/null +++ b/extra_lib/include/openssl/buffer.h @@ -0,0 +1,119 @@ +/* crypto/buffer/buffer.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BUFFER_H +#define HEADER_BUFFER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#if !defined(NO_SYS_TYPES_H) +#include +#endif + +/* Already declared in ossl_typ.h */ +/* typedef struct buf_mem_st BUF_MEM; */ + +struct buf_mem_st + { + size_t length; /* current number of bytes */ + char *data; + size_t max; /* size of buffer */ + }; + +BUF_MEM *BUF_MEM_new(void); +void BUF_MEM_free(BUF_MEM *a); +int BUF_MEM_grow(BUF_MEM *str, size_t len); +int BUF_MEM_grow_clean(BUF_MEM *str, size_t len); +char * BUF_strdup(const char *str); +char * BUF_strndup(const char *str, size_t siz); +void * BUF_memdup(const void *data, size_t siz); +void BUF_reverse(unsigned char *out, unsigned char *in, size_t siz); + +/* safe string functions */ +size_t BUF_strlcpy(char *dst,const char *src,size_t siz); +size_t BUF_strlcat(char *dst,const char *src,size_t siz); + + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_BUF_strings(void); + +/* Error codes for the BUF functions. */ + +/* Function codes. */ +#define BUF_F_BUF_MEMDUP 103 +#define BUF_F_BUF_MEM_GROW 100 +#define BUF_F_BUF_MEM_GROW_CLEAN 105 +#define BUF_F_BUF_MEM_NEW 101 +#define BUF_F_BUF_STRDUP 102 +#define BUF_F_BUF_STRNDUP 104 + +/* Reason codes. */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/comp.h b/extra_lib/include/openssl/comp.h new file mode 100644 index 0000000..4b405c7 --- /dev/null +++ b/extra_lib/include/openssl/comp.h @@ -0,0 +1,80 @@ + +#ifndef HEADER_COMP_H +#define HEADER_COMP_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct comp_ctx_st COMP_CTX; + +typedef struct comp_method_st + { + int type; /* NID for compression library */ + const char *name; /* A text string to identify the library */ + int (*init)(COMP_CTX *ctx); + void (*finish)(COMP_CTX *ctx); + int (*compress)(COMP_CTX *ctx, + unsigned char *out, unsigned int olen, + unsigned char *in, unsigned int ilen); + int (*expand)(COMP_CTX *ctx, + unsigned char *out, unsigned int olen, + unsigned char *in, unsigned int ilen); + /* The following two do NOTHING, but are kept for backward compatibility */ + long (*ctrl)(void); + long (*callback_ctrl)(void); + } COMP_METHOD; + +struct comp_ctx_st + { + COMP_METHOD *meth; + unsigned long compress_in; + unsigned long compress_out; + unsigned long expand_in; + unsigned long expand_out; + + CRYPTO_EX_DATA ex_data; + }; + + +COMP_CTX *COMP_CTX_new(COMP_METHOD *meth); +void COMP_CTX_free(COMP_CTX *ctx); +int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen); +int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen); +COMP_METHOD *COMP_rle(void ); +COMP_METHOD *COMP_zlib(void ); +void COMP_zlib_cleanup(void); + +#ifdef HEADER_BIO_H +#ifdef ZLIB +BIO_METHOD *BIO_f_zlib(void); +#endif +#endif + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_COMP_strings(void); + +/* Error codes for the COMP functions. */ + +/* Function codes. */ +#define COMP_F_BIO_ZLIB_FLUSH 99 +#define COMP_F_BIO_ZLIB_NEW 100 +#define COMP_F_BIO_ZLIB_READ 101 +#define COMP_F_BIO_ZLIB_WRITE 102 + +/* Reason codes. */ +#define COMP_R_ZLIB_DEFLATE_ERROR 99 +#define COMP_R_ZLIB_INFLATE_ERROR 100 +#define COMP_R_ZLIB_NOT_SUPPORTED 101 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/conf.h b/extra_lib/include/openssl/conf.h new file mode 100644 index 0000000..c219997 --- /dev/null +++ b/extra_lib/include/openssl/conf.h @@ -0,0 +1,263 @@ +/* crypto/conf/conf.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CONF_H +#define HEADER_CONF_H + +#include +#include +#include +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct + { + char *section; + char *name; + char *value; + } CONF_VALUE; + +DECLARE_STACK_OF(CONF_VALUE) +DECLARE_LHASH_OF(CONF_VALUE); + +struct conf_st; +struct conf_method_st; +typedef struct conf_method_st CONF_METHOD; + +struct conf_method_st + { + const char *name; + CONF *(*create)(CONF_METHOD *meth); + int (*init)(CONF *conf); + int (*destroy)(CONF *conf); + int (*destroy_data)(CONF *conf); + int (*load_bio)(CONF *conf, BIO *bp, long *eline); + int (*dump)(const CONF *conf, BIO *bp); + int (*is_number)(const CONF *conf, char c); + int (*to_int)(const CONF *conf, char c); + int (*load)(CONF *conf, const char *name, long *eline); + }; + +/* Module definitions */ + +typedef struct conf_imodule_st CONF_IMODULE; +typedef struct conf_module_st CONF_MODULE; + +DECLARE_STACK_OF(CONF_MODULE) +DECLARE_STACK_OF(CONF_IMODULE) + +/* DSO module function typedefs */ +typedef int conf_init_func(CONF_IMODULE *md, const CONF *cnf); +typedef void conf_finish_func(CONF_IMODULE *md); + +#define CONF_MFLAGS_IGNORE_ERRORS 0x1 +#define CONF_MFLAGS_IGNORE_RETURN_CODES 0x2 +#define CONF_MFLAGS_SILENT 0x4 +#define CONF_MFLAGS_NO_DSO 0x8 +#define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10 +#define CONF_MFLAGS_DEFAULT_SECTION 0x20 + +int CONF_set_default_method(CONF_METHOD *meth); +void CONF_set_nconf(CONF *conf,LHASH_OF(CONF_VALUE) *hash); +LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf,const char *file, + long *eline); +#ifndef OPENSSL_NO_FP_API +LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, + long *eline); +#endif +LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp,long *eline); +STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, + const char *section); +char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf,const char *group, + const char *name); +long CONF_get_number(LHASH_OF(CONF_VALUE) *conf,const char *group, + const char *name); +void CONF_free(LHASH_OF(CONF_VALUE) *conf); +int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out); +int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out); + +void OPENSSL_config(const char *config_name); +void OPENSSL_no_config(void); + +/* New conf code. The semantics are different from the functions above. + If that wasn't the case, the above functions would have been replaced */ + +struct conf_st + { + CONF_METHOD *meth; + void *meth_data; + LHASH_OF(CONF_VALUE) *data; + }; + +CONF *NCONF_new(CONF_METHOD *meth); +CONF_METHOD *NCONF_default(void); +CONF_METHOD *NCONF_WIN32(void); +#if 0 /* Just to give you an idea of what I have in mind */ +CONF_METHOD *NCONF_XML(void); +#endif +void NCONF_free(CONF *conf); +void NCONF_free_data(CONF *conf); + +int NCONF_load(CONF *conf,const char *file,long *eline); +#ifndef OPENSSL_NO_FP_API +int NCONF_load_fp(CONF *conf, FILE *fp,long *eline); +#endif +int NCONF_load_bio(CONF *conf, BIO *bp,long *eline); +STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf,const char *section); +char *NCONF_get_string(const CONF *conf,const char *group,const char *name); +int NCONF_get_number_e(const CONF *conf,const char *group,const char *name, + long *result); +int NCONF_dump_fp(const CONF *conf, FILE *out); +int NCONF_dump_bio(const CONF *conf, BIO *out); + +#if 0 /* The following function has no error checking, + and should therefore be avoided */ +long NCONF_get_number(CONF *conf,char *group,char *name); +#else +#define NCONF_get_number(c,g,n,r) NCONF_get_number_e(c,g,n,r) +#endif + +/* Module functions */ + +int CONF_modules_load(const CONF *cnf, const char *appname, + unsigned long flags); +int CONF_modules_load_file(const char *filename, const char *appname, + unsigned long flags); +void CONF_modules_unload(int all); +void CONF_modules_finish(void); +void CONF_modules_free(void); +int CONF_module_add(const char *name, conf_init_func *ifunc, + conf_finish_func *ffunc); + +const char *CONF_imodule_get_name(const CONF_IMODULE *md); +const char *CONF_imodule_get_value(const CONF_IMODULE *md); +void *CONF_imodule_get_usr_data(const CONF_IMODULE *md); +void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data); +CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md); +unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md); +void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags); +void *CONF_module_get_usr_data(CONF_MODULE *pmod); +void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data); + +char *CONF_get1_default_config_file(void); + +int CONF_parse_list(const char *list, int sep, int nospc, + int (*list_cb)(const char *elem, int len, void *usr), void *arg); + +void OPENSSL_load_builtin_modules(void); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_CONF_strings(void); + +/* Error codes for the CONF functions. */ + +/* Function codes. */ +#define CONF_F_CONF_DUMP_FP 104 +#define CONF_F_CONF_LOAD 100 +#define CONF_F_CONF_LOAD_BIO 102 +#define CONF_F_CONF_LOAD_FP 103 +#define CONF_F_CONF_MODULES_LOAD 116 +#define CONF_F_CONF_PARSE_LIST 119 +#define CONF_F_DEF_LOAD 120 +#define CONF_F_DEF_LOAD_BIO 121 +#define CONF_F_MODULE_INIT 115 +#define CONF_F_MODULE_LOAD_DSO 117 +#define CONF_F_MODULE_RUN 118 +#define CONF_F_NCONF_DUMP_BIO 105 +#define CONF_F_NCONF_DUMP_FP 106 +#define CONF_F_NCONF_GET_NUMBER 107 +#define CONF_F_NCONF_GET_NUMBER_E 112 +#define CONF_F_NCONF_GET_SECTION 108 +#define CONF_F_NCONF_GET_STRING 109 +#define CONF_F_NCONF_LOAD 113 +#define CONF_F_NCONF_LOAD_BIO 110 +#define CONF_F_NCONF_LOAD_FP 114 +#define CONF_F_NCONF_NEW 111 +#define CONF_F_STR_COPY 101 + +/* Reason codes. */ +#define CONF_R_ERROR_LOADING_DSO 110 +#define CONF_R_LIST_CANNOT_BE_NULL 115 +#define CONF_R_MISSING_CLOSE_SQUARE_BRACKET 100 +#define CONF_R_MISSING_EQUAL_SIGN 101 +#define CONF_R_MISSING_FINISH_FUNCTION 111 +#define CONF_R_MISSING_INIT_FUNCTION 112 +#define CONF_R_MODULE_INITIALIZATION_ERROR 109 +#define CONF_R_NO_CLOSE_BRACE 102 +#define CONF_R_NO_CONF 105 +#define CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE 106 +#define CONF_R_NO_SECTION 107 +#define CONF_R_NO_SUCH_FILE 114 +#define CONF_R_NO_VALUE 108 +#define CONF_R_UNABLE_TO_CREATE_NEW_SECTION 103 +#define CONF_R_UNKNOWN_MODULE_NAME 113 +#define CONF_R_VARIABLE_HAS_NO_VALUE 104 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/crypto.h b/extra_lib/include/openssl/crypto.h new file mode 100644 index 0000000..b0360ce --- /dev/null +++ b/extra_lib/include/openssl/crypto.h @@ -0,0 +1,575 @@ +/* crypto/crypto.h */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_CRYPTO_H +#define HEADER_CRYPTO_H + +#include + +#include + +#ifndef OPENSSL_NO_FP_API +#include +#endif + +#include +#include +#include +#include + +#ifdef CHARSET_EBCDIC +#include +#endif + +/* Resolve problems on some operating systems with symbol names that clash + one way or another */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Backward compatibility to SSLeay */ +/* This is more to be used to check the correct DLL is being used + * in the MS world. */ +#define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER +#define SSLEAY_VERSION 0 +/* #define SSLEAY_OPTIONS 1 no longer supported */ +#define SSLEAY_CFLAGS 2 +#define SSLEAY_BUILT_ON 3 +#define SSLEAY_PLATFORM 4 +#define SSLEAY_DIR 5 + +/* Already declared in ossl_typ.h */ +#if 0 +typedef struct crypto_ex_data_st CRYPTO_EX_DATA; +/* Called when a new object is created */ +typedef int CRYPTO_EX_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +/* Called when an object is free()ed */ +typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +/* Called when we need to dup an object */ +typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d, + int idx, long argl, void *argp); +#endif + +/* A generic structure to pass assorted data in a expandable way */ +typedef struct openssl_item_st + { + int code; + void *value; /* Not used for flag attributes */ + size_t value_size; /* Max size of value for output, length for input */ + size_t *value_length; /* Returned length of value for output */ + } OPENSSL_ITEM; + + +/* When changing the CRYPTO_LOCK_* list, be sure to maintin the text lock + * names in cryptlib.c + */ + +#define CRYPTO_LOCK_ERR 1 +#define CRYPTO_LOCK_EX_DATA 2 +#define CRYPTO_LOCK_X509 3 +#define CRYPTO_LOCK_X509_INFO 4 +#define CRYPTO_LOCK_X509_PKEY 5 +#define CRYPTO_LOCK_X509_CRL 6 +#define CRYPTO_LOCK_X509_REQ 7 +#define CRYPTO_LOCK_DSA 8 +#define CRYPTO_LOCK_RSA 9 +#define CRYPTO_LOCK_EVP_PKEY 10 +#define CRYPTO_LOCK_X509_STORE 11 +#define CRYPTO_LOCK_SSL_CTX 12 +#define CRYPTO_LOCK_SSL_CERT 13 +#define CRYPTO_LOCK_SSL_SESSION 14 +#define CRYPTO_LOCK_SSL_SESS_CERT 15 +#define CRYPTO_LOCK_SSL 16 +#define CRYPTO_LOCK_SSL_METHOD 17 +#define CRYPTO_LOCK_RAND 18 +#define CRYPTO_LOCK_RAND2 19 +#define CRYPTO_LOCK_MALLOC 20 +#define CRYPTO_LOCK_BIO 21 +#define CRYPTO_LOCK_GETHOSTBYNAME 22 +#define CRYPTO_LOCK_GETSERVBYNAME 23 +#define CRYPTO_LOCK_READDIR 24 +#define CRYPTO_LOCK_RSA_BLINDING 25 +#define CRYPTO_LOCK_DH 26 +#define CRYPTO_LOCK_MALLOC2 27 +#define CRYPTO_LOCK_DSO 28 +#define CRYPTO_LOCK_DYNLOCK 29 +#define CRYPTO_LOCK_ENGINE 30 +#define CRYPTO_LOCK_UI 31 +#define CRYPTO_LOCK_ECDSA 32 +#define CRYPTO_LOCK_EC 33 +#define CRYPTO_LOCK_ECDH 34 +#define CRYPTO_LOCK_BN 35 +#define CRYPTO_LOCK_EC_PRE_COMP 36 +#define CRYPTO_LOCK_STORE 37 +#define CRYPTO_LOCK_COMP 38 +#define CRYPTO_LOCK_FIPS 39 +#define CRYPTO_LOCK_FIPS2 40 +#define CRYPTO_NUM_LOCKS 41 + +#define CRYPTO_LOCK 1 +#define CRYPTO_UNLOCK 2 +#define CRYPTO_READ 4 +#define CRYPTO_WRITE 8 + +#ifndef OPENSSL_NO_LOCKING +#ifndef CRYPTO_w_lock +#define CRYPTO_w_lock(type) \ + CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) +#define CRYPTO_w_unlock(type) \ + CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) +#define CRYPTO_r_lock(type) \ + CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__) +#define CRYPTO_r_unlock(type) \ + CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__) +#define CRYPTO_add(addr,amount,type) \ + CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__) +#endif +#else +#define CRYPTO_w_lock(a) +#define CRYPTO_w_unlock(a) +#define CRYPTO_r_lock(a) +#define CRYPTO_r_unlock(a) +#define CRYPTO_add(a,b,c) ((*(a))+=(b)) +#endif + +/* Some applications as well as some parts of OpenSSL need to allocate + and deallocate locks in a dynamic fashion. The following typedef + makes this possible in a type-safe manner. */ +/* struct CRYPTO_dynlock_value has to be defined by the application. */ +typedef struct + { + int references; + struct CRYPTO_dynlock_value *data; + } CRYPTO_dynlock; + + +/* The following can be used to detect memory leaks in the SSLeay library. + * It used, it turns on malloc checking */ + +#define CRYPTO_MEM_CHECK_OFF 0x0 /* an enume */ +#define CRYPTO_MEM_CHECK_ON 0x1 /* a bit */ +#define CRYPTO_MEM_CHECK_ENABLE 0x2 /* a bit */ +#define CRYPTO_MEM_CHECK_DISABLE 0x3 /* an enume */ + +/* The following are bit values to turn on or off options connected to the + * malloc checking functionality */ + +/* Adds time to the memory checking information */ +#define V_CRYPTO_MDEBUG_TIME 0x1 /* a bit */ +/* Adds thread number to the memory checking information */ +#define V_CRYPTO_MDEBUG_THREAD 0x2 /* a bit */ + +#define V_CRYPTO_MDEBUG_ALL (V_CRYPTO_MDEBUG_TIME | V_CRYPTO_MDEBUG_THREAD) + + +/* predec of the BIO type */ +typedef struct bio_st BIO_dummy; + +struct crypto_ex_data_st + { + STACK_OF(void) *sk; + int dummy; /* gcc is screwing up this data structure :-( */ + }; +DECLARE_STACK_OF(void) + +/* This stuff is basically class callback functions + * The current classes are SSL_CTX, SSL, SSL_SESSION, and a few more */ + +typedef struct crypto_ex_data_func_st + { + long argl; /* Arbitary long */ + void *argp; /* Arbitary void * */ + CRYPTO_EX_new *new_func; + CRYPTO_EX_free *free_func; + CRYPTO_EX_dup *dup_func; + } CRYPTO_EX_DATA_FUNCS; + +DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS) + +/* Per class, we have a STACK of CRYPTO_EX_DATA_FUNCS for each CRYPTO_EX_DATA + * entry. + */ + +#define CRYPTO_EX_INDEX_BIO 0 +#define CRYPTO_EX_INDEX_SSL 1 +#define CRYPTO_EX_INDEX_SSL_CTX 2 +#define CRYPTO_EX_INDEX_SSL_SESSION 3 +#define CRYPTO_EX_INDEX_X509_STORE 4 +#define CRYPTO_EX_INDEX_X509_STORE_CTX 5 +#define CRYPTO_EX_INDEX_RSA 6 +#define CRYPTO_EX_INDEX_DSA 7 +#define CRYPTO_EX_INDEX_DH 8 +#define CRYPTO_EX_INDEX_ENGINE 9 +#define CRYPTO_EX_INDEX_X509 10 +#define CRYPTO_EX_INDEX_UI 11 +#define CRYPTO_EX_INDEX_ECDSA 12 +#define CRYPTO_EX_INDEX_ECDH 13 +#define CRYPTO_EX_INDEX_COMP 14 +#define CRYPTO_EX_INDEX_STORE 15 + +/* Dynamically assigned indexes start from this value (don't use directly, use + * via CRYPTO_ex_data_new_class). */ +#define CRYPTO_EX_INDEX_USER 100 + + +/* This is the default callbacks, but we can have others as well: + * this is needed in Win32 where the application malloc and the + * library malloc may not be the same. + */ +#define CRYPTO_malloc_init() CRYPTO_set_mem_functions(\ + malloc, realloc, free) + +#if defined CRYPTO_MDEBUG_ALL || defined CRYPTO_MDEBUG_TIME || defined CRYPTO_MDEBUG_THREAD +# ifndef CRYPTO_MDEBUG /* avoid duplicate #define */ +# define CRYPTO_MDEBUG +# endif +#endif + +/* Set standard debugging functions (not done by default + * unless CRYPTO_MDEBUG is defined) */ +#define CRYPTO_malloc_debug_init() do {\ + CRYPTO_set_mem_debug_functions(\ + CRYPTO_dbg_malloc,\ + CRYPTO_dbg_realloc,\ + CRYPTO_dbg_free,\ + CRYPTO_dbg_set_options,\ + CRYPTO_dbg_get_options);\ + } while(0) + +int CRYPTO_mem_ctrl(int mode); +int CRYPTO_is_mem_check_on(void); + +/* for applications */ +#define MemCheck_start() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) +#define MemCheck_stop() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF) + +/* for library-internal use */ +#define MemCheck_on() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE) +#define MemCheck_off() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE) +#define is_MemCheck_on() CRYPTO_is_mem_check_on() + +#define OPENSSL_malloc(num) CRYPTO_malloc((int)num,__FILE__,__LINE__) +#define OPENSSL_strdup(str) CRYPTO_strdup((str),__FILE__,__LINE__) +#define OPENSSL_realloc(addr,num) \ + CRYPTO_realloc((char *)addr,(int)num,__FILE__,__LINE__) +#define OPENSSL_realloc_clean(addr,old_num,num) \ + CRYPTO_realloc_clean(addr,old_num,num,__FILE__,__LINE__) +#define OPENSSL_remalloc(addr,num) \ + CRYPTO_remalloc((char **)addr,(int)num,__FILE__,__LINE__) +#define OPENSSL_freeFunc CRYPTO_free +#define OPENSSL_free(addr) CRYPTO_free(addr) + +#define OPENSSL_malloc_locked(num) \ + CRYPTO_malloc_locked((int)num,__FILE__,__LINE__) +#define OPENSSL_free_locked(addr) CRYPTO_free_locked(addr) + + +const char *SSLeay_version(int type); +unsigned long SSLeay(void); + +int OPENSSL_issetugid(void); + +/* An opaque type representing an implementation of "ex_data" support */ +typedef struct st_CRYPTO_EX_DATA_IMPL CRYPTO_EX_DATA_IMPL; +/* Return an opaque pointer to the current "ex_data" implementation */ +const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void); +/* Sets the "ex_data" implementation to be used (if it's not too late) */ +int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i); +/* Get a new "ex_data" class, and return the corresponding "class_index" */ +int CRYPTO_ex_data_new_class(void); +/* Within a given class, get/register a new index */ +int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +/* Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a given + * class (invokes whatever per-class callbacks are applicable) */ +int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, + CRYPTO_EX_DATA *from); +void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +/* Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular index + * (relative to the class type involved) */ +int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val); +void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad,int idx); +/* This function cleans up all "ex_data" state. It mustn't be called under + * potential race-conditions. */ +void CRYPTO_cleanup_all_ex_data(void); + +int CRYPTO_get_new_lockid(char *name); + +int CRYPTO_num_locks(void); /* return CRYPTO_NUM_LOCKS (shared libs!) */ +void CRYPTO_lock(int mode, int type,const char *file,int line); +void CRYPTO_set_locking_callback(void (*func)(int mode,int type, + const char *file,int line)); +void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file, + int line); +void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type, + const char *file, int line)); +int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type, + const char *file,int line); + +/* Don't use this structure directly. */ +typedef struct crypto_threadid_st + { + void *ptr; + unsigned long val; + } CRYPTO_THREADID; +/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */ +void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val); +void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr); +int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *)); +void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *); +void CRYPTO_THREADID_current(CRYPTO_THREADID *id); +int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b); +void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src); +unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id); +#ifndef OPENSSL_NO_DEPRECATED +void CRYPTO_set_id_callback(unsigned long (*func)(void)); +unsigned long (*CRYPTO_get_id_callback(void))(void); +unsigned long CRYPTO_thread_id(void); +#endif + +const char *CRYPTO_get_lock_name(int type); +int CRYPTO_add_lock(int *pointer,int amount,int type, const char *file, + int line); + +int CRYPTO_get_new_dynlockid(void); +void CRYPTO_destroy_dynlockid(int i); +struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i); +void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*dyn_create_function)(const char *file, int line)); +void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)); +void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function)(struct CRYPTO_dynlock_value *l, const char *file, int line)); +struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))(const char *file,int line); +void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, struct CRYPTO_dynlock_value *l, const char *file,int line); +void (*CRYPTO_get_dynlock_destroy_callback(void))(struct CRYPTO_dynlock_value *l, const char *file,int line); + +/* CRYPTO_set_mem_functions includes CRYPTO_set_locked_mem_functions -- + * call the latter last if you need different functions */ +int CRYPTO_set_mem_functions(void *(*m)(size_t),void *(*r)(void *,size_t), void (*f)(void *)); +int CRYPTO_set_locked_mem_functions(void *(*m)(size_t), void (*free_func)(void *)); +int CRYPTO_set_mem_ex_functions(void *(*m)(size_t,const char *,int), + void *(*r)(void *,size_t,const char *,int), + void (*f)(void *)); +int CRYPTO_set_locked_mem_ex_functions(void *(*m)(size_t,const char *,int), + void (*free_func)(void *)); +int CRYPTO_set_mem_debug_functions(void (*m)(void *,int,const char *,int,int), + void (*r)(void *,void *,int,const char *,int,int), + void (*f)(void *,int), + void (*so)(long), + long (*go)(void)); +void CRYPTO_get_mem_functions(void *(**m)(size_t),void *(**r)(void *, size_t), void (**f)(void *)); +void CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *)); +void CRYPTO_get_mem_ex_functions(void *(**m)(size_t,const char *,int), + void *(**r)(void *, size_t,const char *,int), + void (**f)(void *)); +void CRYPTO_get_locked_mem_ex_functions(void *(**m)(size_t,const char *,int), + void (**f)(void *)); +void CRYPTO_get_mem_debug_functions(void (**m)(void *,int,const char *,int,int), + void (**r)(void *,void *,int,const char *,int,int), + void (**f)(void *,int), + void (**so)(long), + long (**go)(void)); + +void *CRYPTO_malloc_locked(int num, const char *file, int line); +void CRYPTO_free_locked(void *); +void *CRYPTO_malloc(int num, const char *file, int line); +char *CRYPTO_strdup(const char *str, const char *file, int line); +void CRYPTO_free(void *); +void *CRYPTO_realloc(void *addr,int num, const char *file, int line); +void *CRYPTO_realloc_clean(void *addr,int old_num,int num,const char *file, + int line); +void *CRYPTO_remalloc(void *addr,int num, const char *file, int line); + +void OPENSSL_cleanse(void *ptr, size_t len); + +void CRYPTO_set_mem_debug_options(long bits); +long CRYPTO_get_mem_debug_options(void); + +#define CRYPTO_push_info(info) \ + CRYPTO_push_info_(info, __FILE__, __LINE__); +int CRYPTO_push_info_(const char *info, const char *file, int line); +int CRYPTO_pop_info(void); +int CRYPTO_remove_all_info(void); + + +/* Default debugging functions (enabled by CRYPTO_malloc_debug_init() macro; + * used as default in CRYPTO_MDEBUG compilations): */ +/* The last argument has the following significance: + * + * 0: called before the actual memory allocation has taken place + * 1: called after the actual memory allocation has taken place + */ +void CRYPTO_dbg_malloc(void *addr,int num,const char *file,int line,int before_p); +void CRYPTO_dbg_realloc(void *addr1,void *addr2,int num,const char *file,int line,int before_p); +void CRYPTO_dbg_free(void *addr,int before_p); +/* Tell the debugging code about options. By default, the following values + * apply: + * + * 0: Clear all options. + * V_CRYPTO_MDEBUG_TIME (1): Set the "Show Time" option. + * V_CRYPTO_MDEBUG_THREAD (2): Set the "Show Thread Number" option. + * V_CRYPTO_MDEBUG_ALL (3): 1 + 2 + */ +void CRYPTO_dbg_set_options(long bits); +long CRYPTO_dbg_get_options(void); + + +#ifndef OPENSSL_NO_FP_API +void CRYPTO_mem_leaks_fp(FILE *); +#endif +void CRYPTO_mem_leaks(struct bio_st *bio); +/* unsigned long order, char *file, int line, int num_bytes, char *addr */ +typedef void *CRYPTO_MEM_LEAK_CB(unsigned long, const char *, int, int, void *); +void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb); + +/* die if we have to */ +void OpenSSLDie(const char *file,int line,const char *assertion); +#define OPENSSL_assert(e) (void)((e) ? 0 : (OpenSSLDie(__FILE__, __LINE__, #e),1)) + +unsigned long *OPENSSL_ia32cap_loc(void); +#define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc())) +int OPENSSL_isservice(void); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_CRYPTO_strings(void); + +/* Error codes for the CRYPTO functions. */ + +/* Function codes. */ +#define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX 100 +#define CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID 103 +#define CRYPTO_F_CRYPTO_GET_NEW_LOCKID 101 +#define CRYPTO_F_CRYPTO_SET_EX_DATA 102 +#define CRYPTO_F_DEF_ADD_INDEX 104 +#define CRYPTO_F_DEF_GET_CLASS 105 +#define CRYPTO_F_INT_DUP_EX_DATA 106 +#define CRYPTO_F_INT_FREE_EX_DATA 107 +#define CRYPTO_F_INT_NEW_EX_DATA 108 + +/* Reason codes. */ +#define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK 100 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/dh.h b/extra_lib/include/openssl/dh.h new file mode 100644 index 0000000..849309a --- /dev/null +++ b/extra_lib/include/openssl/dh.h @@ -0,0 +1,260 @@ +/* crypto/dh/dh.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_DH_H +#define HEADER_DH_H + +#include + +#ifdef OPENSSL_NO_DH +#error DH is disabled. +#endif + +#ifndef OPENSSL_NO_BIO +#include +#endif +#include +#ifndef OPENSSL_NO_DEPRECATED +#include +#endif + +#ifndef OPENSSL_DH_MAX_MODULUS_BITS +# define OPENSSL_DH_MAX_MODULUS_BITS 10000 +#endif + +#define DH_FLAG_CACHE_MONT_P 0x01 +#define DH_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DH + * implementation now uses constant time + * modular exponentiation for secret exponents + * by default. This flag causes the + * faster variable sliding window method to + * be used for all exponents. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Already defined in ossl_typ.h */ +/* typedef struct dh_st DH; */ +/* typedef struct dh_method DH_METHOD; */ + +struct dh_method + { + const char *name; + /* Methods here */ + int (*generate_key)(DH *dh); + int (*compute_key)(unsigned char *key,const BIGNUM *pub_key,DH *dh); + int (*bn_mod_exp)(const DH *dh, BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); /* Can be null */ + + int (*init)(DH *dh); + int (*finish)(DH *dh); + int flags; + char *app_data; + /* If this is non-NULL, it will be used to generate parameters */ + int (*generate_params)(DH *dh, int prime_len, int generator, BN_GENCB *cb); + }; + +struct dh_st + { + /* This first argument is used to pick up errors when + * a DH is passed instead of a EVP_PKEY */ + int pad; + int version; + BIGNUM *p; + BIGNUM *g; + long length; /* optional */ + BIGNUM *pub_key; /* g^x */ + BIGNUM *priv_key; /* x */ + + int flags; + BN_MONT_CTX *method_mont_p; + /* Place holders if we want to do X9.42 DH */ + BIGNUM *q; + BIGNUM *j; + unsigned char *seed; + int seedlen; + BIGNUM *counter; + + int references; + CRYPTO_EX_DATA ex_data; + const DH_METHOD *meth; + ENGINE *engine; + }; + +#define DH_GENERATOR_2 2 +/* #define DH_GENERATOR_3 3 */ +#define DH_GENERATOR_5 5 + +/* DH_check error codes */ +#define DH_CHECK_P_NOT_PRIME 0x01 +#define DH_CHECK_P_NOT_SAFE_PRIME 0x02 +#define DH_UNABLE_TO_CHECK_GENERATOR 0x04 +#define DH_NOT_SUITABLE_GENERATOR 0x08 + +/* DH_check_pub_key error codes */ +#define DH_CHECK_PUBKEY_TOO_SMALL 0x01 +#define DH_CHECK_PUBKEY_TOO_LARGE 0x02 + +/* primes p where (p-1)/2 is prime too are called "safe"; we define + this for backward compatibility: */ +#define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME + +#define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ + (char *(*)())d2i_DHparams,(fp),(unsigned char **)(x)) +#define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \ + (unsigned char *)(x)) +#define d2i_DHparams_bio(bp,x) ASN1_d2i_bio_of(DH,DH_new,d2i_DHparams,bp,x) +#define i2d_DHparams_bio(bp,x) ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x) + +DH *DHparams_dup(DH *); + +const DH_METHOD *DH_OpenSSL(void); + +void DH_set_default_method(const DH_METHOD *meth); +const DH_METHOD *DH_get_default_method(void); +int DH_set_method(DH *dh, const DH_METHOD *meth); +DH *DH_new_method(ENGINE *engine); + +DH * DH_new(void); +void DH_free(DH *dh); +int DH_up_ref(DH *dh); +int DH_size(const DH *dh); +int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int DH_set_ex_data(DH *d, int idx, void *arg); +void *DH_get_ex_data(DH *d, int idx); + +/* Deprecated version */ +#ifndef OPENSSL_NO_DEPRECATED +DH * DH_generate_parameters(int prime_len,int generator, + void (*callback)(int,int,void *),void *cb_arg); +#endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* New version */ +int DH_generate_parameters_ex(DH *dh, int prime_len,int generator, BN_GENCB *cb); + +int DH_check(const DH *dh,int *codes); +int DH_check_pub_key(const DH *dh,const BIGNUM *pub_key, int *codes); +int DH_generate_key(DH *dh); +int DH_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh); +DH * d2i_DHparams(DH **a,const unsigned char **pp, long length); +int i2d_DHparams(const DH *a,unsigned char **pp); +#ifndef OPENSSL_NO_FP_API +int DHparams_print_fp(FILE *fp, const DH *x); +#endif +#ifndef OPENSSL_NO_BIO +int DHparams_print(BIO *bp, const DH *x); +#else +int DHparams_print(char *bp, const DH *x); +#endif + +#define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL) + +#define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL) + +#define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN (EVP_PKEY_ALG_CTRL + 1) +#define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR (EVP_PKEY_ALG_CTRL + 2) + + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_DH_strings(void); + +/* Error codes for the DH functions. */ + +/* Function codes. */ +#define DH_F_COMPUTE_KEY 102 +#define DH_F_DHPARAMS_PRINT_FP 101 +#define DH_F_DH_BUILTIN_GENPARAMS 106 +#define DH_F_DH_NEW_METHOD 105 +#define DH_F_DH_PARAM_DECODE 107 +#define DH_F_DH_PRIV_DECODE 110 +#define DH_F_DH_PRIV_ENCODE 111 +#define DH_F_DH_PUB_DECODE 108 +#define DH_F_DH_PUB_ENCODE 109 +#define DH_F_DO_DH_PRINT 100 +#define DH_F_GENERATE_KEY 103 +#define DH_F_GENERATE_PARAMETERS 104 +#define DH_F_PKEY_DH_DERIVE 112 +#define DH_F_PKEY_DH_KEYGEN 113 + +/* Reason codes. */ +#define DH_R_BAD_GENERATOR 101 +#define DH_R_BN_DECODE_ERROR 109 +#define DH_R_BN_ERROR 106 +#define DH_R_DECODE_ERROR 104 +#define DH_R_INVALID_PUBKEY 102 +#define DH_R_KEYS_NOT_SET 108 +#define DH_R_MODULUS_TOO_LARGE 103 +#define DH_R_NO_PARAMETERS_SET 107 +#define DH_R_NO_PRIVATE_VALUE 100 +#define DH_R_PARAMETER_ENCODING_ERROR 105 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/dsa.h b/extra_lib/include/openssl/dsa.h new file mode 100644 index 0000000..ac50a5c --- /dev/null +++ b/extra_lib/include/openssl/dsa.h @@ -0,0 +1,307 @@ +/* crypto/dsa/dsa.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * The DSS routines are based on patches supplied by + * Steven Schoch . He basically did the + * work and I have just tweaked them a little to fit into my + * stylistic vision for SSLeay :-) */ + +#ifndef HEADER_DSA_H +#define HEADER_DSA_H + +#include + +#ifdef OPENSSL_NO_DSA +#error DSA is disabled. +#endif + +#ifndef OPENSSL_NO_BIO +#include +#endif +#include +#include + +#ifndef OPENSSL_NO_DEPRECATED +#include +#ifndef OPENSSL_NO_DH +# include +#endif +#endif + +#ifndef OPENSSL_DSA_MAX_MODULUS_BITS +# define OPENSSL_DSA_MAX_MODULUS_BITS 10000 +#endif + +#define DSA_FLAG_CACHE_MONT_P 0x01 +#define DSA_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DSA + * implementation now uses constant time + * modular exponentiation for secret exponents + * by default. This flag causes the + * faster variable sliding window method to + * be used for all exponents. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Already defined in ossl_typ.h */ +/* typedef struct dsa_st DSA; */ +/* typedef struct dsa_method DSA_METHOD; */ + +typedef struct DSA_SIG_st + { + BIGNUM *r; + BIGNUM *s; + } DSA_SIG; + +struct dsa_method + { + const char *name; + DSA_SIG * (*dsa_do_sign)(const unsigned char *dgst, int dlen, DSA *dsa); + int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp); + int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); + int (*dsa_mod_exp)(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, + BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont); + int (*bn_mod_exp)(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); /* Can be null */ + int (*init)(DSA *dsa); + int (*finish)(DSA *dsa); + int flags; + char *app_data; + /* If this is non-NULL, it is used to generate DSA parameters */ + int (*dsa_paramgen)(DSA *dsa, int bits, + const unsigned char *seed, int seed_len, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb); + /* If this is non-NULL, it is used to generate DSA keys */ + int (*dsa_keygen)(DSA *dsa); + }; + +struct dsa_st + { + /* This first variable is used to pick up errors where + * a DSA is passed instead of of a EVP_PKEY */ + int pad; + long version; + int write_params; + BIGNUM *p; + BIGNUM *q; /* == 20 */ + BIGNUM *g; + + BIGNUM *pub_key; /* y public key */ + BIGNUM *priv_key; /* x private key */ + + BIGNUM *kinv; /* Signing pre-calc */ + BIGNUM *r; /* Signing pre-calc */ + + int flags; + /* Normally used to cache montgomery values */ + BN_MONT_CTX *method_mont_p; + int references; + CRYPTO_EX_DATA ex_data; + const DSA_METHOD *meth; + /* functional reference if 'meth' is ENGINE-provided */ + ENGINE *engine; + }; + +#define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \ + (char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x)) +#define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \ + (unsigned char *)(x)) +#define d2i_DSAparams_bio(bp,x) ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAparams,bp,x) +#define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x) + + +DSA *DSAparams_dup(DSA *x); +DSA_SIG * DSA_SIG_new(void); +void DSA_SIG_free(DSA_SIG *a); +int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp); +DSA_SIG * d2i_DSA_SIG(DSA_SIG **v, const unsigned char **pp, long length); + +DSA_SIG * DSA_do_sign(const unsigned char *dgst,int dlen,DSA *dsa); +int DSA_do_verify(const unsigned char *dgst,int dgst_len, + DSA_SIG *sig,DSA *dsa); + +const DSA_METHOD *DSA_OpenSSL(void); + +void DSA_set_default_method(const DSA_METHOD *); +const DSA_METHOD *DSA_get_default_method(void); +int DSA_set_method(DSA *dsa, const DSA_METHOD *); + +DSA * DSA_new(void); +DSA * DSA_new_method(ENGINE *engine); +void DSA_free (DSA *r); +/* "up" the DSA object's reference count */ +int DSA_up_ref(DSA *r); +int DSA_size(const DSA *); + /* next 4 return -1 on error */ +int DSA_sign_setup( DSA *dsa,BN_CTX *ctx_in,BIGNUM **kinvp,BIGNUM **rp); +int DSA_sign(int type,const unsigned char *dgst,int dlen, + unsigned char *sig, unsigned int *siglen, DSA *dsa); +int DSA_verify(int type,const unsigned char *dgst,int dgst_len, + const unsigned char *sigbuf, int siglen, DSA *dsa); +int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int DSA_set_ex_data(DSA *d, int idx, void *arg); +void *DSA_get_ex_data(DSA *d, int idx); + +DSA * d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length); +DSA * d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length); +DSA * d2i_DSAparams(DSA **a, const unsigned char **pp, long length); + +/* Deprecated version */ +#ifndef OPENSSL_NO_DEPRECATED +DSA * DSA_generate_parameters(int bits, + unsigned char *seed,int seed_len, + int *counter_ret, unsigned long *h_ret,void + (*callback)(int, int, void *),void *cb_arg); +#endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* New version */ +int DSA_generate_parameters_ex(DSA *dsa, int bits, + const unsigned char *seed,int seed_len, + int *counter_ret, unsigned long *h_ret, BN_GENCB *cb); + +int DSA_generate_key(DSA *a); +int i2d_DSAPublicKey(const DSA *a, unsigned char **pp); +int i2d_DSAPrivateKey(const DSA *a, unsigned char **pp); +int i2d_DSAparams(const DSA *a,unsigned char **pp); + +#ifndef OPENSSL_NO_BIO +int DSAparams_print(BIO *bp, const DSA *x); +int DSA_print(BIO *bp, const DSA *x, int off); +#endif +#ifndef OPENSSL_NO_FP_API +int DSAparams_print_fp(FILE *fp, const DSA *x); +int DSA_print_fp(FILE *bp, const DSA *x, int off); +#endif + +#define DSS_prime_checks 50 +/* Primality test according to FIPS PUB 186[-1], Appendix 2.1: + * 50 rounds of Rabin-Miller */ +#define DSA_is_prime(n, callback, cb_arg) \ + BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg) + +#ifndef OPENSSL_NO_DH +/* Convert DSA structure (key or just parameters) into DH structure + * (be careful to avoid small subgroup attacks when using this!) */ +DH *DSA_dup_DH(const DSA *r); +#endif + +#define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL) + +#define EVP_PKEY_CTRL_DSA_PARAMGEN_BITS (EVP_PKEY_ALG_CTRL + 1) +#define EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS (EVP_PKEY_ALG_CTRL + 2) +#define EVP_PKEY_CTRL_DSA_PARAMGEN_MD (EVP_PKEY_ALG_CTRL + 3) + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_DSA_strings(void); + +/* Error codes for the DSA functions. */ + +/* Function codes. */ +#define DSA_F_D2I_DSA_SIG 110 +#define DSA_F_DO_DSA_PRINT 104 +#define DSA_F_DSAPARAMS_PRINT 100 +#define DSA_F_DSAPARAMS_PRINT_FP 101 +#define DSA_F_DSA_DO_SIGN 112 +#define DSA_F_DSA_DO_VERIFY 113 +#define DSA_F_DSA_NEW_METHOD 103 +#define DSA_F_DSA_PARAM_DECODE 119 +#define DSA_F_DSA_PRINT_FP 105 +#define DSA_F_DSA_PRIV_DECODE 115 +#define DSA_F_DSA_PRIV_ENCODE 116 +#define DSA_F_DSA_PUB_DECODE 117 +#define DSA_F_DSA_PUB_ENCODE 118 +#define DSA_F_DSA_SIGN 106 +#define DSA_F_DSA_SIGN_SETUP 107 +#define DSA_F_DSA_SIG_NEW 109 +#define DSA_F_DSA_VERIFY 108 +#define DSA_F_I2D_DSA_SIG 111 +#define DSA_F_OLD_DSA_PRIV_DECODE 122 +#define DSA_F_PKEY_DSA_CTRL 120 +#define DSA_F_PKEY_DSA_KEYGEN 121 +#define DSA_F_SIG_CB 114 + +/* Reason codes. */ +#define DSA_R_BAD_Q_VALUE 102 +#define DSA_R_BN_DECODE_ERROR 108 +#define DSA_R_BN_ERROR 109 +#define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100 +#define DSA_R_DECODE_ERROR 104 +#define DSA_R_INVALID_DIGEST_TYPE 106 +#define DSA_R_MISSING_PARAMETERS 101 +#define DSA_R_MODULUS_TOO_LARGE 103 +#define DSA_R_NO_PARAMETERS_SET 107 +#define DSA_R_PARAMETER_ENCODING_ERROR 105 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/dtls1.h b/extra_lib/include/openssl/dtls1.h new file mode 100644 index 0000000..2900d1d --- /dev/null +++ b/extra_lib/include/openssl/dtls1.h @@ -0,0 +1,267 @@ +/* ssl/dtls1.h */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_DTLS1_H +#define HEADER_DTLS1_H + +#include +#include +#ifdef OPENSSL_SYS_VMS +#include +#include +#endif +#ifdef OPENSSL_SYS_WIN32 +/* Needed for struct timeval */ +#include +#elif defined(OPENSSL_SYS_NETWARE) && !defined(_WINSOCK2API_) +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define DTLS1_VERSION 0xFEFF +#define DTLS1_BAD_VER 0x0100 + +#if 0 +/* this alert description is not specified anywhere... */ +#define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE 110 +#endif + +/* lengths of messages */ +#define DTLS1_COOKIE_LENGTH 256 + +#define DTLS1_RT_HEADER_LENGTH 13 + +#define DTLS1_HM_HEADER_LENGTH 12 + +#define DTLS1_HM_BAD_FRAGMENT -2 +#define DTLS1_HM_FRAGMENT_RETRY -3 + +#define DTLS1_CCS_HEADER_LENGTH 1 + +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE +#define DTLS1_AL_HEADER_LENGTH 7 +#else +#define DTLS1_AL_HEADER_LENGTH 2 +#endif + + +typedef struct dtls1_bitmap_st + { + unsigned long map; /* track 32 packets on 32-bit systems + and 64 - on 64-bit systems */ + unsigned char max_seq_num[8]; /* max record number seen so far, + 64-bit value in big-endian + encoding */ + } DTLS1_BITMAP; + +struct dtls1_retransmit_state + { + EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ + EVP_MD_CTX *write_hash; /* used for mac generation */ +#ifndef OPENSSL_NO_COMP + COMP_CTX *compress; /* compression */ +#else + char *compress; +#endif + SSL_SESSION *session; + unsigned short epoch; + }; + +struct hm_header_st + { + unsigned char type; + unsigned long msg_len; + unsigned short seq; + unsigned long frag_off; + unsigned long frag_len; + unsigned int is_ccs; + struct dtls1_retransmit_state saved_retransmit_state; + }; + +struct ccs_header_st + { + unsigned char type; + unsigned short seq; + }; + +struct dtls1_timeout_st + { + /* Number of read timeouts so far */ + unsigned int read_timeouts; + + /* Number of write timeouts so far */ + unsigned int write_timeouts; + + /* Number of alerts received so far */ + unsigned int num_alerts; + }; + +typedef struct record_pqueue_st + { + unsigned short epoch; + pqueue q; + } record_pqueue; + +typedef struct hm_fragment_st + { + struct hm_header_st msg_header; + unsigned char *fragment; + unsigned char *reassembly; + } hm_fragment; + +typedef struct dtls1_state_st + { + unsigned int send_cookie; + unsigned char cookie[DTLS1_COOKIE_LENGTH]; + unsigned char rcvd_cookie[DTLS1_COOKIE_LENGTH]; + unsigned int cookie_len; + + /* + * The current data and handshake epoch. This is initially + * undefined, and starts at zero once the initial handshake is + * completed + */ + unsigned short r_epoch; + unsigned short w_epoch; + + /* records being received in the current epoch */ + DTLS1_BITMAP bitmap; + + /* renegotiation starts a new set of sequence numbers */ + DTLS1_BITMAP next_bitmap; + + /* handshake message numbers */ + unsigned short handshake_write_seq; + unsigned short next_handshake_write_seq; + + unsigned short handshake_read_seq; + + /* save last sequence number for retransmissions */ + unsigned char last_write_sequence[8]; + + /* Received handshake records (processed and unprocessed) */ + record_pqueue unprocessed_rcds; + record_pqueue processed_rcds; + + /* Buffered handshake messages */ + pqueue buffered_messages; + + /* Buffered (sent) handshake records */ + pqueue sent_messages; + + /* Buffered application records. + * Only for records between CCS and Finished + * to prevent either protocol violation or + * unnecessary message loss. + */ + record_pqueue buffered_app_data; + + /* Is set when listening for new connections with dtls1_listen() */ + unsigned int listen; + + unsigned int mtu; /* max DTLS packet size */ + + struct hm_header_st w_msg_hdr; + struct hm_header_st r_msg_hdr; + + struct dtls1_timeout_st timeout; + + /* Indicates when the last handshake msg sent will timeout */ + struct timeval next_timeout; + + /* Timeout duration */ + unsigned short timeout_duration; + + /* storage for Alert/Handshake protocol data received but not + * yet processed by ssl3_read_bytes: */ + unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH]; + unsigned int alert_fragment_len; + unsigned char handshake_fragment[DTLS1_HM_HEADER_LENGTH]; + unsigned int handshake_fragment_len; + + unsigned int retransmitting; + unsigned int change_cipher_spec_ok; + + } DTLS1_STATE; + +typedef struct dtls1_record_data_st + { + unsigned char *packet; + unsigned int packet_length; + SSL3_BUFFER rbuf; + SSL3_RECORD rrec; + } DTLS1_RECORD_DATA; + + +/* Timeout multipliers (timeout slice is defined in apps/timeouts.h */ +#define DTLS1_TMO_READ_COUNT 2 +#define DTLS1_TMO_WRITE_COUNT 2 + +#define DTLS1_TMO_ALERT_COUNT 12 + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/extra_lib/include/openssl/e_os2.h b/extra_lib/include/openssl/e_os2.h new file mode 100644 index 0000000..4c785c6 --- /dev/null +++ b/extra_lib/include/openssl/e_os2.h @@ -0,0 +1,289 @@ +/* e_os2.h */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#ifndef HEADER_E_OS2_H +#define HEADER_E_OS2_H + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * Detect operating systems. This probably needs completing. + * The result is that at least one OPENSSL_SYS_os macro should be defined. + * However, if none is defined, Unix is assumed. + **/ + +#define OPENSSL_SYS_UNIX + +/* ----------------------- Macintosh, before MacOS X ----------------------- */ +#if defined(__MWERKS__) && defined(macintosh) || defined(OPENSSL_SYSNAME_MAC) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_MACINTOSH_CLASSIC +#endif + +/* ----------------------- NetWare ----------------------------------------- */ +#if defined(NETWARE) || defined(OPENSSL_SYSNAME_NETWARE) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_NETWARE +#endif + +/* ---------------------- Microsoft operating systems ---------------------- */ + +/* Note that MSDOS actually denotes 32-bit environments running on top of + MS-DOS, such as DJGPP one. */ +#if defined(OPENSSL_SYSNAME_MSDOS) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_MSDOS +#endif + +/* For 32 bit environment, there seems to be the CygWin environment and then + all the others that try to do the same thing Microsoft does... */ +#if defined(OPENSSL_SYSNAME_UWIN) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WIN32_UWIN +#else +# if defined(__CYGWIN32__) || defined(OPENSSL_SYSNAME_CYGWIN32) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WIN32_CYGWIN +# else +# if defined(_WIN32) || defined(OPENSSL_SYSNAME_WIN32) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WIN32 +# endif +# if defined(OPENSSL_SYSNAME_WINNT) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WINNT +# endif +# if defined(OPENSSL_SYSNAME_WINCE) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WINCE +# endif +# endif +#endif + +/* Anything that tries to look like Microsoft is "Windows" */ +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WINNT) || defined(OPENSSL_SYS_WINCE) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WINDOWS +# ifndef OPENSSL_SYS_MSDOS +# define OPENSSL_SYS_MSDOS +# endif +#endif + +/* DLL settings. This part is a bit tough, because it's up to the application + implementor how he or she will link the application, so it requires some + macro to be used. */ +#ifdef OPENSSL_SYS_WINDOWS +# ifndef OPENSSL_OPT_WINDLL +# if defined(_WINDLL) /* This is used when building OpenSSL to indicate that + DLL linkage should be used */ +# define OPENSSL_OPT_WINDLL +# endif +# endif +#endif + +/* -------------------------------- OpenVMS -------------------------------- */ +#if defined(__VMS) || defined(VMS) || defined(OPENSSL_SYSNAME_VMS) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_VMS +# if defined(__DECC) +# define OPENSSL_SYS_VMS_DECC +# elif defined(__DECCXX) +# define OPENSSL_SYS_VMS_DECC +# define OPENSSL_SYS_VMS_DECCXX +# else +# define OPENSSL_SYS_VMS_NODECC +# endif +#endif + +/* --------------------------------- OS/2 ---------------------------------- */ +#if defined(__EMX__) || defined(__OS2__) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_OS2 +#endif + +/* --------------------------------- Unix ---------------------------------- */ +#ifdef OPENSSL_SYS_UNIX +# if defined(linux) || defined(__linux__) || defined(OPENSSL_SYSNAME_LINUX) +# define OPENSSL_SYS_LINUX +# endif +# ifdef OPENSSL_SYSNAME_MPE +# define OPENSSL_SYS_MPE +# endif +# ifdef OPENSSL_SYSNAME_SNI +# define OPENSSL_SYS_SNI +# endif +# ifdef OPENSSL_SYSNAME_ULTRASPARC +# define OPENSSL_SYS_ULTRASPARC +# endif +# ifdef OPENSSL_SYSNAME_NEWS4 +# define OPENSSL_SYS_NEWS4 +# endif +# ifdef OPENSSL_SYSNAME_MACOSX +# define OPENSSL_SYS_MACOSX +# endif +# ifdef OPENSSL_SYSNAME_MACOSX_RHAPSODY +# define OPENSSL_SYS_MACOSX_RHAPSODY +# define OPENSSL_SYS_MACOSX +# endif +# ifdef OPENSSL_SYSNAME_SUNOS +# define OPENSSL_SYS_SUNOS +#endif +# if defined(_CRAY) || defined(OPENSSL_SYSNAME_CRAY) +# define OPENSSL_SYS_CRAY +# endif +# if defined(_AIX) || defined(OPENSSL_SYSNAME_AIX) +# define OPENSSL_SYS_AIX +# endif +#endif + +/* --------------------------------- VOS ----------------------------------- */ +#ifdef OPENSSL_SYSNAME_VOS +# define OPENSSL_SYS_VOS +#endif + +/* ------------------------------- VxWorks --------------------------------- */ +#ifdef OPENSSL_SYSNAME_VXWORKS +# define OPENSSL_SYS_VXWORKS +#endif + +/* --------------------------------- BeOS ---------------------------------- */ +#if defined(__BEOS__) +# define OPENSSL_SYS_BEOS +# include +# if defined(BONE_VERSION) +# define OPENSSL_SYS_BEOS_BONE +# else +# define OPENSSL_SYS_BEOS_R5 +# endif +#endif + +/** + * That's it for OS-specific stuff + *****************************************************************************/ + + +/* Specials for I/O an exit */ +#ifdef OPENSSL_SYS_MSDOS +# define OPENSSL_UNISTD_IO +# define OPENSSL_DECLARE_EXIT extern void exit(int); +#else +# define OPENSSL_UNISTD_IO OPENSSL_UNISTD +# define OPENSSL_DECLARE_EXIT /* declared in unistd.h */ +#endif + +/* Definitions of OPENSSL_GLOBAL and OPENSSL_EXTERN, to define and declare + certain global symbols that, with some compilers under VMS, have to be + defined and declared explicitely with globaldef and globalref. + Definitions of OPENSSL_EXPORT and OPENSSL_IMPORT, to define and declare + DLL exports and imports for compilers under Win32. These are a little + more complicated to use. Basically, for any library that exports some + global variables, the following code must be present in the header file + that declares them, before OPENSSL_EXTERN is used: + + #ifdef SOME_BUILD_FLAG_MACRO + # undef OPENSSL_EXTERN + # define OPENSSL_EXTERN OPENSSL_EXPORT + #endif + + The default is to have OPENSSL_EXPORT, OPENSSL_IMPORT and OPENSSL_GLOBAL + have some generally sensible values, and for OPENSSL_EXTERN to have the + value OPENSSL_IMPORT. +*/ + +#if defined(OPENSSL_SYS_VMS_NODECC) +# define OPENSSL_EXPORT globalref +# define OPENSSL_IMPORT globalref +# define OPENSSL_GLOBAL globaldef +#elif defined(OPENSSL_SYS_WINDOWS) && defined(OPENSSL_OPT_WINDLL) +# define OPENSSL_EXPORT extern __declspec(dllexport) +# define OPENSSL_IMPORT extern __declspec(dllimport) +# define OPENSSL_GLOBAL +#else +# define OPENSSL_EXPORT extern +# define OPENSSL_IMPORT extern +# define OPENSSL_GLOBAL +#endif +#define OPENSSL_EXTERN OPENSSL_IMPORT + +/* Macros to allow global variables to be reached through function calls when + required (if a shared library version requires it, for example. + The way it's done allows definitions like this: + + // in foobar.c + OPENSSL_IMPLEMENT_GLOBAL(int,foobar,0) + // in foobar.h + OPENSSL_DECLARE_GLOBAL(int,foobar); + #define foobar OPENSSL_GLOBAL_REF(foobar) +*/ +#ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION +# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) \ + type *_shadow_##name(void) \ + { static type _hide_##name=value; return &_hide_##name; } +# define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void) +# define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name())) +#else +# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) OPENSSL_GLOBAL type _shadow_##name=value; +# define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name +# define OPENSSL_GLOBAL_REF(name) _shadow_##name +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/ec.h b/extra_lib/include/openssl/ec.h new file mode 100644 index 0000000..ee70781 --- /dev/null +++ b/extra_lib/include/openssl/ec.h @@ -0,0 +1,1100 @@ +/* crypto/ec/ec.h */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/** + * \file crypto/ec/ec.h Include file for the OpenSSL EC functions + * \author Originally written by Bodo Moeller for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#ifndef HEADER_EC_H +#define HEADER_EC_H + +#include + +#ifdef OPENSSL_NO_EC +#error EC is disabled. +#endif + +#include +#include +#ifndef OPENSSL_NO_DEPRECATED +#include +#endif + +#ifdef __cplusplus +extern "C" { +#elif defined(__SUNPRO_C) +# if __SUNPRO_C >= 0x520 +# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) +# endif +#endif + + +#ifndef OPENSSL_ECC_MAX_FIELD_BITS +# define OPENSSL_ECC_MAX_FIELD_BITS 661 +#endif + +/** Enum for the point conversion form as defined in X9.62 (ECDSA) + * for the encoding of a elliptic curve point (x,y) */ +typedef enum { + /** the point is encoded as z||x, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_COMPRESSED = 2, + /** the point is encoded as z||x||y, where z is the octet 0x02 */ + POINT_CONVERSION_UNCOMPRESSED = 4, + /** the point is encoded as z||x||y, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_HYBRID = 6 +} point_conversion_form_t; + + +typedef struct ec_method_st EC_METHOD; + +typedef struct ec_group_st + /* + EC_METHOD *meth; + -- field definition + -- curve coefficients + -- optional generator with associated information (order, cofactor) + -- optional extra data (precomputed table for fast computation of multiples of generator) + -- ASN1 stuff + */ + EC_GROUP; + +typedef struct ec_point_st EC_POINT; + + +/********************************************************************/ +/* EC_METHODs for curves over GF(p) */ +/********************************************************************/ + +/** Returns the basic GFp ec methods which provides the basis for the + * optimized methods. + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_simple_method(void); + +/** Returns GFp methods using montgomery multiplication. + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_mont_method(void); + +/** Returns GFp methods using optimized methods for NIST recommended curves + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nist_method(void); + + +/********************************************************************/ +/* EC_METHOD for curves over GF(2^m) */ +/********************************************************************/ + +/** Returns the basic GF2m ec method + * \return EC_METHOD object + */ +const EC_METHOD *EC_GF2m_simple_method(void); + + +/********************************************************************/ +/* EC_GROUP functions */ +/********************************************************************/ + +/** Creates a new EC_GROUP object + * \param meth EC_METHOD to use + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *EC_GROUP_new(const EC_METHOD *meth); + +/** Frees a EC_GROUP object + * \param group EC_GROUP object to be freed. + */ +void EC_GROUP_free(EC_GROUP *group); + +/** Clears and frees a EC_GROUP object + * \param group EC_GROUP object to be cleared and freed. + */ +void EC_GROUP_clear_free(EC_GROUP *group); + +/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD. + * \param dst destination EC_GROUP object + * \param src source EC_GROUP object + * \return 1 on success and 0 if an error occurred. + */ +int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src); + +/** Creates a new EC_GROUP object and copies the copies the content + * form src to the newly created EC_KEY object + * \param src source EC_GROUP object + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *EC_GROUP_dup(const EC_GROUP *src); + +/** Returns the EC_METHOD of the EC_GROUP object. + * \param group EC_GROUP object + * \return EC_METHOD used in this EC_GROUP object. + */ +const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group); + +/** Returns the field type of the EC_METHOD. + * \param meth EC_METHOD object + * \return NID of the underlying field type OID. + */ +int EC_METHOD_get_field_type(const EC_METHOD *meth); + +/** Sets the generator and it's order/cofactor of a EC_GROUP object. + * \param group EC_GROUP object + * \param generator EC_POINT object with the generator. + * \param order the order of the group generated by the generator. + * \param cofactor the index of the sub-group generated by the generator + * in the group of all points on the elliptic curve. + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor); + +/** Returns the generator of a EC_GROUP object. + * \param group EC_GROUP object + * \return the currently used generator (possibly NULL). + */ +const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); + +/** Gets the order of a EC_GROUP + * \param group EC_GROUP object + * \param order BIGNUM to which the order is copied + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); + +/** Gets the cofactor of a EC_GROUP + * \param group EC_GROUP object + * \param cofactor BIGNUM to which the cofactor is copied + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx); + +/** Sets the name of a EC_GROUP object + * \param group EC_GROUP object + * \param nid NID of the curve name OID + */ +void EC_GROUP_set_curve_name(EC_GROUP *group, int nid); + +/** Returns the curve name of a EC_GROUP object + * \param group EC_GROUP object + * \return NID of the curve name OID or 0 if not set. + */ +int EC_GROUP_get_curve_name(const EC_GROUP *group); + +void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); +int EC_GROUP_get_asn1_flag(const EC_GROUP *group); + +void EC_GROUP_set_point_conversion_form(EC_GROUP *, point_conversion_form_t); +point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *); + +unsigned char *EC_GROUP_get0_seed(const EC_GROUP *); +size_t EC_GROUP_get_seed_len(const EC_GROUP *); +size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len); + +/** Sets the parameter of a ec over GFp defined by y^2 = x^3 + a*x + b + * \param group EC_GROUP object + * \param p BIGNUM with the prime number + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + +/** Gets the parameter of the ec over GFp defined by y^2 = x^3 + a*x + b + * \param group EC_GROUP object + * \param p BIGNUM for the prime number + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx); + +/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b + * \param group EC_GROUP object + * \param p BIGNUM with the polynomial defining the underlying field + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + +/** Gets the parameter of the ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b + * \param group EC_GROUP object + * \param p BIGNUM for the polynomial defining the underlying field + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx); + +/** Returns the number of bits needed to represent a field element + * \param group EC_GROUP object + * \return number of bits needed to represent a field element + */ +int EC_GROUP_get_degree(const EC_GROUP *group); + +/** Checks whether the parameter in the EC_GROUP define a valid ec group + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if group is a valid ec group and 0 otherwise + */ +int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx); + +/** Checks whether the discriminant of the elliptic curve is zero or not + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if the discriminant is not zero and 0 otherwise + */ +int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx); + +/** Compares two EC_GROUP objects + * \param a first EC_GROUP object + * \param b second EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 0 if both groups are equal and 1 otherwise + */ +int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx); + +/* EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*() + * after choosing an appropriate EC_METHOD */ + +/** Creates a new EC_GROUP object with the specified parameters defined + * over GFp (defined by the equation y^2 = x^3 + a*x + b) + * \param p BIGNUM with the prime number + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + */ +EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + +/** Creates a new EC_GROUP object with the specified parameters defined + * over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b) + * \param p BIGNUM with the polynomial defining the underlying field + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + */ +EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + +/** Creates a EC_GROUP object with a curve specified by a NID + * \param nid NID of the OID of the curve name + * \return newly created EC_GROUP object with specified curve or NULL + * if an error occurred + */ +EC_GROUP *EC_GROUP_new_by_curve_name(int nid); + + +/********************************************************************/ +/* handling of internal curves */ +/********************************************************************/ + +typedef struct { + int nid; + const char *comment; + } EC_builtin_curve; + +/* EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number + * of all available curves or zero if a error occurred. + * In case r ist not zero nitems EC_builtin_curve structures + * are filled with the data of the first nitems internal groups */ +size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems); + + +/********************************************************************/ +/* EC_POINT functions */ +/********************************************************************/ + +/** Creates a new EC_POINT object for the specified EC_GROUP + * \param group EC_GROUP the underlying EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + */ +EC_POINT *EC_POINT_new(const EC_GROUP *group); + +/** Frees a EC_POINT object + * \param point EC_POINT object to be freed + */ +void EC_POINT_free(EC_POINT *point); + +/** Clears and frees a EC_POINT object + * \param point EC_POINT object to be cleared and freed + */ +void EC_POINT_clear_free(EC_POINT *point); + +/** Copies EC_POINT object + * \param dst destination EC_POINT object + * \param src source EC_POINT object + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src); + +/** Creates a new EC_POINT object and copies the content of the supplied + * EC_POINT + * \param src source EC_POINT object + * \param group underlying the EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + */ +EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group); + +/** Returns the EC_METHOD used in EC_POINT object + * \param point EC_POINT object + * \return the EC_METHOD used + */ +const EC_METHOD *EC_POINT_method_of(const EC_POINT *point); + +/** Sets a point to infinity (neutral element) + * \param group underlying EC_GROUP object + * \param point EC_POINT to set to infinity + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point); + +/** Sets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param z BIGNUM with the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *ctx); + +/** Gets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param z BIGNUM for the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *ctx); + +/** Sets the affine coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx); + +/** Gets the affine coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx); + +/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, int y_bit, BN_CTX *ctx); + +/** Sets the affine coordinates of a EC_POINT over GF2m + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx); + +/** Gets the affine coordinates of a EC_POINT over GF2m + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, BIGNUM *y, BN_CTX *ctx); + +/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, int y_bit, BN_CTX *ctx); + +/** Encodes a EC_POINT object to a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param form point conversion form + * \param buf memory buffer for the result. If NULL the function returns + * required buffer size. + * \param len length of the memory buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + */ +size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *ctx); + +/** Decodes a EC_POINT from a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param buf memory buffer with the encoded ec point + * \param len length of the encoded ec point + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p, + const unsigned char *buf, size_t len, BN_CTX *ctx); + +/* other interfaces to point2oct/oct2point: */ +BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BIGNUM *, BN_CTX *); +EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *, + EC_POINT *, BN_CTX *); +char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BN_CTX *); +EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *, + EC_POINT *, BN_CTX *); + + +/********************************************************************/ +/* functions for doing EC_POINT arithmetic */ +/********************************************************************/ + +/** Computes the sum of two EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = a + b) + * \param a EC_POINT object with the first summand + * \param b EC_POINT object with the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx); + +/** Computes the double of a EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = 2 * a) + * \param a EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx); + +/** Computes the inverse of a EC_POINT + * \param group underlying EC_GROUP object + * \param a EC_POINT object to be inverted (it's used for the result as well) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx); + +/** Checks whether the point is the neutral element of the group + * \param group the underlying EC_GROUP object + * \param p EC_POINT object + * \return 1 if the point is the neutral element and 0 otherwise + */ +int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p); + +/** Checks whether the point is on the curve + * \param group underlying EC_GROUP object + * \param point EC_POINT object to check + * \param ctx BN_CTX object (optional) + * \return 1 if point if on the curve and 0 otherwise + */ +int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx); + +/** Compares two EC_POINTs + * \param group underlying EC_GROUP object + * \param a first EC_POINT object + * \param b second EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 0 if both points are equal and a value != 0 otherwise + */ +int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx); + +int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); +int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *); + +/** Computes r = generator * n sum_{i=0}^num p[i] * m[i] + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param num number futher summands + * \param p array of size num of EC_POINT objects + * \param m array of size num of BIGNUM objects + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, size_t num, const EC_POINT *p[], const BIGNUM *m[], BN_CTX *ctx); + +/** Computes r = generator * n + q * m + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param q EC_POINT object with the first factor of the second summand + * \param m BIGNUM with the second factor of the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx); + +/** Stores multiples of generator for faster point multiplication + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx); + +/** Reports whether a precomputation has been done + * \param group EC_GROUP object + * \return 1 if a pre-computation has been done and 0 otherwise + */ +int EC_GROUP_have_precompute_mult(const EC_GROUP *group); + + +/********************************************************************/ +/* ASN1 stuff */ +/********************************************************************/ + +/* EC_GROUP_get_basis_type() returns the NID of the basis type + * used to represent the field elements */ +int EC_GROUP_get_basis_type(const EC_GROUP *); +int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k); +int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1, + unsigned int *k2, unsigned int *k3); + +#define OPENSSL_EC_NAMED_CURVE 0x001 + +typedef struct ecpk_parameters_st ECPKPARAMETERS; + +EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len); +int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out); + +#define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x) +#define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x) +#define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \ + (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x)) +#define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \ + (unsigned char *)(x)) + +#ifndef OPENSSL_NO_BIO +int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off); +#endif +#ifndef OPENSSL_NO_FP_API +int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off); +#endif + + +/********************************************************************/ +/* EC_KEY functions */ +/********************************************************************/ + +typedef struct ec_key_st EC_KEY; + +/* some values for the encoding_flag */ +#define EC_PKEY_NO_PARAMETERS 0x001 +#define EC_PKEY_NO_PUBKEY 0x002 + +/** Creates a new EC_KEY object. + * \return EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_new(void); + +/** Creates a new EC_KEY object using a named curve as underlying + * EC_GROUP object. + * \param nid NID of the named curve. + * \return EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_new_by_curve_name(int nid); + +/** Frees a EC_KEY object. + * \param key EC_KEY object to be freed. + */ +void EC_KEY_free(EC_KEY *key); + +/** Copies a EC_KEY object. + * \param dst destination EC_KEY object + * \param src src EC_KEY object + * \return dst or NULL if an error occurred. + */ +EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src); + +/** Creates a new EC_KEY object and copies the content from src to it. + * \param src the source EC_KEY object + * \return newly created EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_dup(const EC_KEY *src); + +/** Increases the internal reference count of a EC_KEY object. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_up_ref(EC_KEY *key); + +/** Returns the EC_GROUP object of a EC_KEY object + * \param key EC_KEY object + * \return the EC_GROUP object (possibly NULL). + */ +const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key); + +/** Sets the EC_GROUP of a EC_KEY object. + * \param key EC_KEY object + * \param group EC_GROUP to use in the EC_KEY object (note: the EC_KEY + * object will use an own copy of the EC_GROUP). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); + +/** Returns the private key of a EC_KEY object. + * \param key EC_KEY object + * \return a BIGNUM with the private key (possibly NULL). + */ +const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key); + +/** Sets the private key of a EC_KEY object. + * \param key EC_KEY object + * \param prv BIGNUM with the private key (note: the EC_KEY object + * will use an own copy of the BIGNUM). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv); + +/** Returns the public key of a EC_KEY object. + * \param key the EC_KEY object + * \return a EC_POINT object with the public key (possibly NULL) + */ +const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key); + +/** Sets the public key of a EC_KEY object. + * \param key EC_KEY object + * \param pub EC_POINT object with the public key (note: the EC_KEY object + * will use an own copy of the EC_POINT object). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); + +unsigned EC_KEY_get_enc_flags(const EC_KEY *key); +void EC_KEY_set_enc_flags(EC_KEY *, unsigned int); +point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *); +void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t); +/* functions to set/get method specific data */ +void *EC_KEY_get_key_method_data(EC_KEY *, + void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)); +void EC_KEY_insert_key_method_data(EC_KEY *, void *data, + void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *)); +/* wrapper functions for the underlying EC_GROUP object */ +void EC_KEY_set_asn1_flag(EC_KEY *, int); + +/** Creates a table of pre-computed multiples of the generator to + * accelerate further EC_KEY operations. + * \param key EC_KEY object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx); + +/** Creates a new ec private (and optional a new public) key. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_generate_key(EC_KEY *key); + +/** Verifies that a private and/or public key is valid. + * \param key the EC_KEY object + * \return 1 on success and 0 otherwise. + */ +int EC_KEY_check_key(const EC_KEY *key); + + +/********************************************************************/ +/* de- and encoding functions for SEC1 ECPrivateKey */ +/********************************************************************/ + +/** Decodes a private key from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded private key + * \param len length of the DER encoded private key + * \return the decoded private key or NULL if an error occurred. + */ +EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes a private key object and stores the result in a buffer. + * \param key the EC_KEY object to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + */ +int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out); + + +/********************************************************************/ +/* de- and encoding functions for EC parameters */ +/********************************************************************/ + +/** Decodes ec parameter from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded ec parameters + * \param len length of the DER encoded ec parameters + * \return a EC_KEY object with the decoded parameters or NULL if an error + * occurred. + */ +EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes ec parameter and stores the result in a buffer. + * \param key the EC_KEY object with ec paramters to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + */ +int i2d_ECParameters(EC_KEY *key, unsigned char **out); + + +/********************************************************************/ +/* de- and encoding functions for EC public key */ +/* (octet string, not DER -- hence 'o2i' and 'i2o') */ +/********************************************************************/ + +/** Decodes a ec public key from a octet string. + * \param key a pointer to a EC_KEY object which should be used + * \param in memory buffer with the encoded public key + * \param len length of the encoded public key + * \return EC_KEY object with decoded public key or NULL if an error + * occurred. + */ +EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes a ec public key in an octet string. + * \param key the EC_KEY object with the public key + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred + */ +int i2o_ECPublicKey(EC_KEY *key, unsigned char **out); + +#ifndef OPENSSL_NO_BIO +/** Prints out the ec parameters on human readable form. + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + */ +int ECParameters_print(BIO *bp, const EC_KEY *key); + +/** Prints out the contents of a EC_KEY object + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + */ +int EC_KEY_print(BIO *bp, const EC_KEY *key, int off); + +#endif +#ifndef OPENSSL_NO_FP_API +/** Prints out the ec parameters on human readable form. + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + */ +int ECParameters_print_fp(FILE *fp, const EC_KEY *key); + +/** Prints out the contents of a EC_KEY object + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + */ +int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off); + +#endif + +#define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x) + +#ifndef __cplusplus +#if defined(__SUNPRO_C) +# if __SUNPRO_C >= 0x520 +# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) +# endif +# endif +#endif + +#define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL) + + +#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1) + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_EC_strings(void); + +/* Error codes for the EC functions. */ + +/* Function codes. */ +#define EC_F_COMPUTE_WNAF 143 +#define EC_F_D2I_ECPARAMETERS 144 +#define EC_F_D2I_ECPKPARAMETERS 145 +#define EC_F_D2I_ECPRIVATEKEY 146 +#define EC_F_DO_EC_KEY_PRINT 221 +#define EC_F_ECKEY_PARAM2TYPE 223 +#define EC_F_ECKEY_PARAM_DECODE 212 +#define EC_F_ECKEY_PRIV_DECODE 213 +#define EC_F_ECKEY_PRIV_ENCODE 214 +#define EC_F_ECKEY_PUB_DECODE 215 +#define EC_F_ECKEY_PUB_ENCODE 216 +#define EC_F_ECKEY_TYPE2PARAM 220 +#define EC_F_ECPARAMETERS_PRINT 147 +#define EC_F_ECPARAMETERS_PRINT_FP 148 +#define EC_F_ECPKPARAMETERS_PRINT 149 +#define EC_F_ECPKPARAMETERS_PRINT_FP 150 +#define EC_F_ECP_NIST_MOD_192 203 +#define EC_F_ECP_NIST_MOD_224 204 +#define EC_F_ECP_NIST_MOD_256 205 +#define EC_F_ECP_NIST_MOD_521 206 +#define EC_F_EC_ASN1_GROUP2CURVE 153 +#define EC_F_EC_ASN1_GROUP2FIELDID 154 +#define EC_F_EC_ASN1_GROUP2PARAMETERS 155 +#define EC_F_EC_ASN1_GROUP2PKPARAMETERS 156 +#define EC_F_EC_ASN1_PARAMETERS2GROUP 157 +#define EC_F_EC_ASN1_PKPARAMETERS2GROUP 158 +#define EC_F_EC_EX_DATA_SET_DATA 211 +#define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY 208 +#define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT 159 +#define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE 195 +#define EC_F_EC_GF2M_SIMPLE_OCT2POINT 160 +#define EC_F_EC_GF2M_SIMPLE_POINT2OCT 161 +#define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162 +#define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163 +#define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES 164 +#define EC_F_EC_GFP_MONT_FIELD_DECODE 133 +#define EC_F_EC_GFP_MONT_FIELD_ENCODE 134 +#define EC_F_EC_GFP_MONT_FIELD_MUL 131 +#define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE 209 +#define EC_F_EC_GFP_MONT_FIELD_SQR 132 +#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189 +#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP 135 +#define EC_F_EC_GFP_NIST_FIELD_MUL 200 +#define EC_F_EC_GFP_NIST_FIELD_SQR 201 +#define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202 +#define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165 +#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166 +#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 100 +#define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR 101 +#define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102 +#define EC_F_EC_GFP_SIMPLE_OCT2POINT 103 +#define EC_F_EC_GFP_SIMPLE_POINT2OCT 104 +#define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137 +#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 167 +#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105 +#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 168 +#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128 +#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 169 +#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129 +#define EC_F_EC_GROUP_CHECK 170 +#define EC_F_EC_GROUP_CHECK_DISCRIMINANT 171 +#define EC_F_EC_GROUP_COPY 106 +#define EC_F_EC_GROUP_GET0_GENERATOR 139 +#define EC_F_EC_GROUP_GET_COFACTOR 140 +#define EC_F_EC_GROUP_GET_CURVE_GF2M 172 +#define EC_F_EC_GROUP_GET_CURVE_GFP 130 +#define EC_F_EC_GROUP_GET_DEGREE 173 +#define EC_F_EC_GROUP_GET_ORDER 141 +#define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS 193 +#define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS 194 +#define EC_F_EC_GROUP_NEW 108 +#define EC_F_EC_GROUP_NEW_BY_CURVE_NAME 174 +#define EC_F_EC_GROUP_NEW_FROM_DATA 175 +#define EC_F_EC_GROUP_PRECOMPUTE_MULT 142 +#define EC_F_EC_GROUP_SET_CURVE_GF2M 176 +#define EC_F_EC_GROUP_SET_CURVE_GFP 109 +#define EC_F_EC_GROUP_SET_EXTRA_DATA 110 +#define EC_F_EC_GROUP_SET_GENERATOR 111 +#define EC_F_EC_KEY_CHECK_KEY 177 +#define EC_F_EC_KEY_COPY 178 +#define EC_F_EC_KEY_GENERATE_KEY 179 +#define EC_F_EC_KEY_NEW 182 +#define EC_F_EC_KEY_PRINT 180 +#define EC_F_EC_KEY_PRINT_FP 181 +#define EC_F_EC_POINTS_MAKE_AFFINE 136 +#define EC_F_EC_POINT_ADD 112 +#define EC_F_EC_POINT_CMP 113 +#define EC_F_EC_POINT_COPY 114 +#define EC_F_EC_POINT_DBL 115 +#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M 183 +#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116 +#define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117 +#define EC_F_EC_POINT_INVERT 210 +#define EC_F_EC_POINT_IS_AT_INFINITY 118 +#define EC_F_EC_POINT_IS_ON_CURVE 119 +#define EC_F_EC_POINT_MAKE_AFFINE 120 +#define EC_F_EC_POINT_MUL 184 +#define EC_F_EC_POINT_NEW 121 +#define EC_F_EC_POINT_OCT2POINT 122 +#define EC_F_EC_POINT_POINT2OCT 123 +#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M 185 +#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 124 +#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M 186 +#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125 +#define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126 +#define EC_F_EC_POINT_SET_TO_INFINITY 127 +#define EC_F_EC_PRE_COMP_DUP 207 +#define EC_F_EC_PRE_COMP_NEW 196 +#define EC_F_EC_WNAF_MUL 187 +#define EC_F_EC_WNAF_PRECOMPUTE_MULT 188 +#define EC_F_I2D_ECPARAMETERS 190 +#define EC_F_I2D_ECPKPARAMETERS 191 +#define EC_F_I2D_ECPRIVATEKEY 192 +#define EC_F_I2O_ECPUBLICKEY 151 +#define EC_F_O2I_ECPUBLICKEY 152 +#define EC_F_OLD_EC_PRIV_DECODE 222 +#define EC_F_PKEY_EC_CTRL 197 +#define EC_F_PKEY_EC_CTRL_STR 198 +#define EC_F_PKEY_EC_DERIVE 217 +#define EC_F_PKEY_EC_KEYGEN 199 +#define EC_F_PKEY_EC_PARAMGEN 219 +#define EC_F_PKEY_EC_SIGN 218 + +/* Reason codes. */ +#define EC_R_ASN1_ERROR 115 +#define EC_R_ASN1_UNKNOWN_FIELD 116 +#define EC_R_BUFFER_TOO_SMALL 100 +#define EC_R_D2I_ECPKPARAMETERS_FAILURE 117 +#define EC_R_DECODE_ERROR 142 +#define EC_R_DISCRIMINANT_IS_ZERO 118 +#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119 +#define EC_R_FIELD_TOO_LARGE 143 +#define EC_R_GROUP2PKPARAMETERS_FAILURE 120 +#define EC_R_I2D_ECPKPARAMETERS_FAILURE 121 +#define EC_R_INCOMPATIBLE_OBJECTS 101 +#define EC_R_INVALID_ARGUMENT 112 +#define EC_R_INVALID_COMPRESSED_POINT 110 +#define EC_R_INVALID_COMPRESSION_BIT 109 +#define EC_R_INVALID_CURVE 141 +#define EC_R_INVALID_DIGEST_TYPE 138 +#define EC_R_INVALID_ENCODING 102 +#define EC_R_INVALID_FIELD 103 +#define EC_R_INVALID_FORM 104 +#define EC_R_INVALID_GROUP_ORDER 122 +#define EC_R_INVALID_PENTANOMIAL_BASIS 132 +#define EC_R_INVALID_PRIVATE_KEY 123 +#define EC_R_INVALID_TRINOMIAL_BASIS 137 +#define EC_R_KEYS_NOT_SET 140 +#define EC_R_MISSING_PARAMETERS 124 +#define EC_R_MISSING_PRIVATE_KEY 125 +#define EC_R_NOT_A_NIST_PRIME 135 +#define EC_R_NOT_A_SUPPORTED_NIST_PRIME 136 +#define EC_R_NOT_IMPLEMENTED 126 +#define EC_R_NOT_INITIALIZED 111 +#define EC_R_NO_FIELD_MOD 133 +#define EC_R_NO_PARAMETERS_SET 139 +#define EC_R_PASSED_NULL_PARAMETER 134 +#define EC_R_PKPARAMETERS2GROUP_FAILURE 127 +#define EC_R_POINT_AT_INFINITY 106 +#define EC_R_POINT_IS_NOT_ON_CURVE 107 +#define EC_R_SLOT_FULL 108 +#define EC_R_UNDEFINED_GENERATOR 113 +#define EC_R_UNDEFINED_ORDER 128 +#define EC_R_UNKNOWN_GROUP 129 +#define EC_R_UNKNOWN_ORDER 114 +#define EC_R_UNSUPPORTED_FIELD 131 +#define EC_R_WRONG_ORDER 130 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/ecdh.h b/extra_lib/include/openssl/ecdh.h new file mode 100644 index 0000000..b4b58ee --- /dev/null +++ b/extra_lib/include/openssl/ecdh.h @@ -0,0 +1,123 @@ +/* crypto/ecdh/ecdh.h */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH software is originally written by Douglas Stebila of + * Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_ECDH_H +#define HEADER_ECDH_H + +#include + +#ifdef OPENSSL_NO_ECDH +#error ECDH is disabled. +#endif + +#include +#include +#ifndef OPENSSL_NO_DEPRECATED +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +const ECDH_METHOD *ECDH_OpenSSL(void); + +void ECDH_set_default_method(const ECDH_METHOD *); +const ECDH_METHOD *ECDH_get_default_method(void); +int ECDH_set_method(EC_KEY *, const ECDH_METHOD *); + +int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh, + void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen)); + +int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new + *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg); +void *ECDH_get_ex_data(EC_KEY *d, int idx); + + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_ECDH_strings(void); + +/* Error codes for the ECDH functions. */ + +/* Function codes. */ +#define ECDH_F_ECDH_COMPUTE_KEY 100 +#define ECDH_F_ECDH_DATA_NEW_METHOD 101 + +/* Reason codes. */ +#define ECDH_R_KDF_FAILED 102 +#define ECDH_R_NO_PRIVATE_VALUE 100 +#define ECDH_R_POINT_ARITHMETIC_FAILURE 101 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/ecdsa.h b/extra_lib/include/openssl/ecdsa.h new file mode 100644 index 0000000..e61c539 --- /dev/null +++ b/extra_lib/include/openssl/ecdsa.h @@ -0,0 +1,258 @@ +/* crypto/ecdsa/ecdsa.h */ +/** + * \file crypto/ecdsa/ecdsa.h Include file for the OpenSSL ECDSA functions + * \author Written by Nils Larsch for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_ECDSA_H +#define HEADER_ECDSA_H + +#include + +#ifdef OPENSSL_NO_ECDSA +#error ECDSA is disabled. +#endif + +#include +#include +#ifndef OPENSSL_NO_DEPRECATED +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ECDSA_SIG_st + { + BIGNUM *r; + BIGNUM *s; + } ECDSA_SIG; + +/** Allocates and initialize a ECDSA_SIG structure + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_SIG_new(void); + +/** frees a ECDSA_SIG structure + * \param sig pointer to the ECDSA_SIG structure + */ +void ECDSA_SIG_free(ECDSA_SIG *sig); + +/** DER encode content of ECDSA_SIG object (note: this function modifies *pp + * (*pp += length of the DER encoded signature)). + * \param sig pointer to the ECDSA_SIG object + * \param pp pointer to a unsigned char pointer for the output or NULL + * \return the length of the DER encoded ECDSA_SIG object or 0 + */ +int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp); + +/** Decodes a DER encoded ECDSA signature (note: this function changes *pp + * (*pp += len)). + * \param sig pointer to ECDSA_SIG pointer (may be NULL) + * \param pp memory buffer with the DER encoded signature + * \param len length of the buffer + * \return pointer to the decoded ECDSA_SIG structure (or NULL) + */ +ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len); + +/** Computes the ECDSA signature of the given hash value using + * the supplied private key and returns the created signature. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param eckey EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst,int dgst_len,EC_KEY *eckey); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param kinv BIGNUM with a pre-computed inverse k (optional) + * \param rp BIGNUM with a pre-computed rp value (optioanl), + * see ECDSA_sign_setup + * \param eckey EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, + const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey); + +/** Verifies that the supplied signature is a valid ECDSA + * signature of the supplied hash value using the supplied public key. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param sig ECDSA_SIG structure + * \param eckey EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid + * and -1 on error + */ +int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY* eckey); + +const ECDSA_METHOD *ECDSA_OpenSSL(void); + +/** Sets the default ECDSA method + * \param meth new default ECDSA_METHOD + */ +void ECDSA_set_default_method(const ECDSA_METHOD *meth); + +/** Returns the default ECDSA method + * \return pointer to ECDSA_METHOD structure containing the default method + */ +const ECDSA_METHOD *ECDSA_get_default_method(void); + +/** Sets method to be used for the ECDSA operations + * \param eckey EC_KEY object + * \param meth new method + * \return 1 on success and 0 otherwise + */ +int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth); + +/** Returns the maximum length of the DER encoded signature + * \param eckey EC_KEY object + * \return numbers of bytes required for the DER encoded signature + */ +int ECDSA_size(const EC_KEY *eckey); + +/** Precompute parts of the signing operation + * \param eckey EC_KEY object containing a private EC key + * \param ctx BN_CTX object (optional) + * \param kinv BIGNUM pointer for the inverse of k + * \param rp BIGNUM pointer for x coordinate of k * generator + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, + BIGNUM **rp); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig memory for the DER encoded created signature + * \param siglen pointer to the length of the returned signature + * \param eckey EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, EC_KEY *eckey); + + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig buffer to hold the DER encoded signature + * \param siglen pointer to the length of the returned signature + * \param kinv BIGNUM with a pre-computed inverse k (optional) + * \param rp BIGNUM with a pre-computed rp value (optioanl), + * see ECDSA_sign_setup + * \param eckey EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, + const BIGNUM *rp, EC_KEY *eckey); + +/** Verifies that the given signature is valid ECDSA signature + * of the supplied hash value using the specified public key. + * \param type this parameter is ignored + * \param dgst pointer to the hash value + * \param dgstlen length of the hash value + * \param sig pointer to the DER encoded signature + * \param siglen length of the DER encoded signature + * \param eckey EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid + * and -1 on error + */ +int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, + const unsigned char *sig, int siglen, EC_KEY *eckey); + +/* the standard ex_data functions */ +int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new + *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg); +void *ECDSA_get_ex_data(EC_KEY *d, int idx); + + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_ECDSA_strings(void); + +/* Error codes for the ECDSA functions. */ + +/* Function codes. */ +#define ECDSA_F_ECDSA_DATA_NEW_METHOD 100 +#define ECDSA_F_ECDSA_DO_SIGN 101 +#define ECDSA_F_ECDSA_DO_VERIFY 102 +#define ECDSA_F_ECDSA_SIGN_SETUP 103 + +/* Reason codes. */ +#define ECDSA_R_BAD_SIGNATURE 100 +#define ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 101 +#define ECDSA_R_ERR_EC_LIB 102 +#define ECDSA_R_MISSING_PARAMETERS 103 +#define ECDSA_R_NEED_NEW_SETUP_VALUES 106 +#define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED 104 +#define ECDSA_R_SIGNATURE_MALLOC_FAILED 105 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/err.h b/extra_lib/include/openssl/err.h new file mode 100644 index 0000000..b9f8c16 --- /dev/null +++ b/extra_lib/include/openssl/err.h @@ -0,0 +1,385 @@ +/* crypto/err/err.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_ERR_H +#define HEADER_ERR_H + +#include + +#ifndef OPENSSL_NO_FP_API +#include +#include +#endif + +#include +#ifndef OPENSSL_NO_BIO +#include +#endif +#ifndef OPENSSL_NO_LHASH +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef OPENSSL_NO_ERR +#define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,d,e) +#else +#define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,NULL,0) +#endif + +#include + +#define ERR_TXT_MALLOCED 0x01 +#define ERR_TXT_STRING 0x02 + +#define ERR_FLAG_MARK 0x01 + +#define ERR_NUM_ERRORS 16 +typedef struct err_state_st + { + CRYPTO_THREADID tid; + int err_flags[ERR_NUM_ERRORS]; + unsigned long err_buffer[ERR_NUM_ERRORS]; + char *err_data[ERR_NUM_ERRORS]; + int err_data_flags[ERR_NUM_ERRORS]; + const char *err_file[ERR_NUM_ERRORS]; + int err_line[ERR_NUM_ERRORS]; + int top,bottom; + } ERR_STATE; + +/* library */ +#define ERR_LIB_NONE 1 +#define ERR_LIB_SYS 2 +#define ERR_LIB_BN 3 +#define ERR_LIB_RSA 4 +#define ERR_LIB_DH 5 +#define ERR_LIB_EVP 6 +#define ERR_LIB_BUF 7 +#define ERR_LIB_OBJ 8 +#define ERR_LIB_PEM 9 +#define ERR_LIB_DSA 10 +#define ERR_LIB_X509 11 +/* #define ERR_LIB_METH 12 */ +#define ERR_LIB_ASN1 13 +#define ERR_LIB_CONF 14 +#define ERR_LIB_CRYPTO 15 +#define ERR_LIB_EC 16 +#define ERR_LIB_SSL 20 +/* #define ERR_LIB_SSL23 21 */ +/* #define ERR_LIB_SSL2 22 */ +/* #define ERR_LIB_SSL3 23 */ +/* #define ERR_LIB_RSAREF 30 */ +/* #define ERR_LIB_PROXY 31 */ +#define ERR_LIB_BIO 32 +#define ERR_LIB_PKCS7 33 +#define ERR_LIB_X509V3 34 +#define ERR_LIB_PKCS12 35 +#define ERR_LIB_RAND 36 +#define ERR_LIB_DSO 37 +#define ERR_LIB_ENGINE 38 +#define ERR_LIB_OCSP 39 +#define ERR_LIB_UI 40 +#define ERR_LIB_COMP 41 +#define ERR_LIB_ECDSA 42 +#define ERR_LIB_ECDH 43 +#define ERR_LIB_STORE 44 +#define ERR_LIB_FIPS 45 +#define ERR_LIB_CMS 46 +#define ERR_LIB_TS 47 +#define ERR_LIB_HMAC 48 +#define ERR_LIB_JPAKE 49 + +#define ERR_LIB_USER 128 + +#define SYSerr(f,r) ERR_PUT_error(ERR_LIB_SYS,(f),(r),__FILE__,__LINE__) +#define BNerr(f,r) ERR_PUT_error(ERR_LIB_BN,(f),(r),__FILE__,__LINE__) +#define RSAerr(f,r) ERR_PUT_error(ERR_LIB_RSA,(f),(r),__FILE__,__LINE__) +#define DHerr(f,r) ERR_PUT_error(ERR_LIB_DH,(f),(r),__FILE__,__LINE__) +#define EVPerr(f,r) ERR_PUT_error(ERR_LIB_EVP,(f),(r),__FILE__,__LINE__) +#define BUFerr(f,r) ERR_PUT_error(ERR_LIB_BUF,(f),(r),__FILE__,__LINE__) +#define OBJerr(f,r) ERR_PUT_error(ERR_LIB_OBJ,(f),(r),__FILE__,__LINE__) +#define PEMerr(f,r) ERR_PUT_error(ERR_LIB_PEM,(f),(r),__FILE__,__LINE__) +#define DSAerr(f,r) ERR_PUT_error(ERR_LIB_DSA,(f),(r),__FILE__,__LINE__) +#define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),__FILE__,__LINE__) +#define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),__FILE__,__LINE__) +#define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),__FILE__,__LINE__) +#define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),__FILE__,__LINE__) +#define ECerr(f,r) ERR_PUT_error(ERR_LIB_EC,(f),(r),__FILE__,__LINE__) +#define SSLerr(f,r) ERR_PUT_error(ERR_LIB_SSL,(f),(r),__FILE__,__LINE__) +#define BIOerr(f,r) ERR_PUT_error(ERR_LIB_BIO,(f),(r),__FILE__,__LINE__) +#define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),__FILE__,__LINE__) +#define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),__FILE__,__LINE__) +#define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),__FILE__,__LINE__) +#define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),__FILE__,__LINE__) +#define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),__FILE__,__LINE__) +#define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),__FILE__,__LINE__) +#define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),__FILE__,__LINE__) +#define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),__FILE__,__LINE__) +#define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),__FILE__,__LINE__) +#define ECDSAerr(f,r) ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),__FILE__,__LINE__) +#define ECDHerr(f,r) ERR_PUT_error(ERR_LIB_ECDH,(f),(r),__FILE__,__LINE__) +#define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__) +#define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),__FILE__,__LINE__) +#define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),__FILE__,__LINE__) +#define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),__FILE__,__LINE__) +#define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),__FILE__,__LINE__) +#define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),__FILE__,__LINE__) + +/* Borland C seems too stupid to be able to shift and do longs in + * the pre-processor :-( */ +#define ERR_PACK(l,f,r) (((((unsigned long)l)&0xffL)*0x1000000)| \ + ((((unsigned long)f)&0xfffL)*0x1000)| \ + ((((unsigned long)r)&0xfffL))) +#define ERR_GET_LIB(l) (int)((((unsigned long)l)>>24L)&0xffL) +#define ERR_GET_FUNC(l) (int)((((unsigned long)l)>>12L)&0xfffL) +#define ERR_GET_REASON(l) (int)((l)&0xfffL) +#define ERR_FATAL_ERROR(l) (int)((l)&ERR_R_FATAL) + + +/* OS functions */ +#define SYS_F_FOPEN 1 +#define SYS_F_CONNECT 2 +#define SYS_F_GETSERVBYNAME 3 +#define SYS_F_SOCKET 4 +#define SYS_F_IOCTLSOCKET 5 +#define SYS_F_BIND 6 +#define SYS_F_LISTEN 7 +#define SYS_F_ACCEPT 8 +#define SYS_F_WSASTARTUP 9 /* Winsock stuff */ +#define SYS_F_OPENDIR 10 +#define SYS_F_FREAD 11 + + +/* reasons */ +#define ERR_R_SYS_LIB ERR_LIB_SYS /* 2 */ +#define ERR_R_BN_LIB ERR_LIB_BN /* 3 */ +#define ERR_R_RSA_LIB ERR_LIB_RSA /* 4 */ +#define ERR_R_DH_LIB ERR_LIB_DH /* 5 */ +#define ERR_R_EVP_LIB ERR_LIB_EVP /* 6 */ +#define ERR_R_BUF_LIB ERR_LIB_BUF /* 7 */ +#define ERR_R_OBJ_LIB ERR_LIB_OBJ /* 8 */ +#define ERR_R_PEM_LIB ERR_LIB_PEM /* 9 */ +#define ERR_R_DSA_LIB ERR_LIB_DSA /* 10 */ +#define ERR_R_X509_LIB ERR_LIB_X509 /* 11 */ +#define ERR_R_ASN1_LIB ERR_LIB_ASN1 /* 13 */ +#define ERR_R_CONF_LIB ERR_LIB_CONF /* 14 */ +#define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO /* 15 */ +#define ERR_R_EC_LIB ERR_LIB_EC /* 16 */ +#define ERR_R_SSL_LIB ERR_LIB_SSL /* 20 */ +#define ERR_R_BIO_LIB ERR_LIB_BIO /* 32 */ +#define ERR_R_PKCS7_LIB ERR_LIB_PKCS7 /* 33 */ +#define ERR_R_X509V3_LIB ERR_LIB_X509V3 /* 34 */ +#define ERR_R_PKCS12_LIB ERR_LIB_PKCS12 /* 35 */ +#define ERR_R_RAND_LIB ERR_LIB_RAND /* 36 */ +#define ERR_R_DSO_LIB ERR_LIB_DSO /* 37 */ +#define ERR_R_ENGINE_LIB ERR_LIB_ENGINE /* 38 */ +#define ERR_R_OCSP_LIB ERR_LIB_OCSP /* 39 */ +#define ERR_R_UI_LIB ERR_LIB_UI /* 40 */ +#define ERR_R_COMP_LIB ERR_LIB_COMP /* 41 */ +#define ERR_R_ECDSA_LIB ERR_LIB_ECDSA /* 42 */ +#define ERR_R_ECDH_LIB ERR_LIB_ECDH /* 43 */ +#define ERR_R_STORE_LIB ERR_LIB_STORE /* 44 */ +#define ERR_R_TS_LIB ERR_LIB_TS /* 45 */ + +#define ERR_R_NESTED_ASN1_ERROR 58 +#define ERR_R_BAD_ASN1_OBJECT_HEADER 59 +#define ERR_R_BAD_GET_ASN1_OBJECT_CALL 60 +#define ERR_R_EXPECTING_AN_ASN1_SEQUENCE 61 +#define ERR_R_ASN1_LENGTH_MISMATCH 62 +#define ERR_R_MISSING_ASN1_EOS 63 + +/* fatal error */ +#define ERR_R_FATAL 64 +#define ERR_R_MALLOC_FAILURE (1|ERR_R_FATAL) +#define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED (2|ERR_R_FATAL) +#define ERR_R_PASSED_NULL_PARAMETER (3|ERR_R_FATAL) +#define ERR_R_INTERNAL_ERROR (4|ERR_R_FATAL) +#define ERR_R_DISABLED (5|ERR_R_FATAL) + +/* 99 is the maximum possible ERR_R_... code, higher values + * are reserved for the individual libraries */ + + +typedef struct ERR_string_data_st + { + unsigned long error; + const char *string; + } ERR_STRING_DATA; + +void ERR_put_error(int lib, int func,int reason,const char *file,int line); +void ERR_set_error_data(char *data,int flags); + +unsigned long ERR_get_error(void); +unsigned long ERR_get_error_line(const char **file,int *line); +unsigned long ERR_get_error_line_data(const char **file,int *line, + const char **data, int *flags); +unsigned long ERR_peek_error(void); +unsigned long ERR_peek_error_line(const char **file,int *line); +unsigned long ERR_peek_error_line_data(const char **file,int *line, + const char **data,int *flags); +unsigned long ERR_peek_last_error(void); +unsigned long ERR_peek_last_error_line(const char **file,int *line); +unsigned long ERR_peek_last_error_line_data(const char **file,int *line, + const char **data,int *flags); +void ERR_clear_error(void ); +char *ERR_error_string(unsigned long e,char *buf); +void ERR_error_string_n(unsigned long e, char *buf, size_t len); +const char *ERR_lib_error_string(unsigned long e); +const char *ERR_func_error_string(unsigned long e); +const char *ERR_reason_error_string(unsigned long e); +void ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u), + void *u); +#ifndef OPENSSL_NO_FP_API +void ERR_print_errors_fp(FILE *fp); +#endif +#ifndef OPENSSL_NO_BIO +void ERR_print_errors(BIO *bp); +void ERR_add_error_data(int num, ...); +#endif +void ERR_load_strings(int lib,ERR_STRING_DATA str[]); +void ERR_unload_strings(int lib,ERR_STRING_DATA str[]); +void ERR_load_ERR_strings(void); +void ERR_load_crypto_strings(void); +void ERR_free_strings(void); + +void ERR_remove_thread_state(const CRYPTO_THREADID *tid); +#ifndef OPENSSL_NO_DEPRECATED +void ERR_remove_state(unsigned long pid); /* if zero we look it up */ +#endif +ERR_STATE *ERR_get_state(void); + +#ifndef OPENSSL_NO_LHASH +LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void); +LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void); +void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash); +#endif + +int ERR_get_next_error_library(void); + +int ERR_set_mark(void); +int ERR_pop_to_mark(void); + +/* Already defined in ossl_typ.h */ +/* typedef struct st_ERR_FNS ERR_FNS; */ +/* An application can use this function and provide the return value to loaded + * modules that should use the application's ERR state/functionality */ +const ERR_FNS *ERR_get_implementation(void); +/* A loaded module should call this function prior to any ERR operations using + * the application's "ERR_FNS". */ +int ERR_set_implementation(const ERR_FNS *fns); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/extra_lib/include/openssl/evp.h b/extra_lib/include/openssl/evp.h new file mode 100644 index 0000000..9f9795e --- /dev/null +++ b/extra_lib/include/openssl/evp.h @@ -0,0 +1,1324 @@ +/* crypto/evp/evp.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_ENVELOPE_H +#define HEADER_ENVELOPE_H + +#ifdef OPENSSL_ALGORITHM_DEFINES +# include +#else +# define OPENSSL_ALGORITHM_DEFINES +# include +# undef OPENSSL_ALGORITHM_DEFINES +#endif + +#include + +#include + +#ifndef OPENSSL_NO_BIO +#include +#endif + +/* +#define EVP_RC2_KEY_SIZE 16 +#define EVP_RC4_KEY_SIZE 16 +#define EVP_BLOWFISH_KEY_SIZE 16 +#define EVP_CAST5_KEY_SIZE 16 +#define EVP_RC5_32_12_16_KEY_SIZE 16 +*/ +#define EVP_MAX_MD_SIZE 64 /* longest known is SHA512 */ +#define EVP_MAX_KEY_LENGTH 32 +#define EVP_MAX_IV_LENGTH 16 +#define EVP_MAX_BLOCK_LENGTH 32 + +#define PKCS5_SALT_LEN 8 +/* Default PKCS#5 iteration count */ +#define PKCS5_DEFAULT_ITER 2048 + +#include + +#define EVP_PK_RSA 0x0001 +#define EVP_PK_DSA 0x0002 +#define EVP_PK_DH 0x0004 +#define EVP_PK_EC 0x0008 +#define EVP_PKT_SIGN 0x0010 +#define EVP_PKT_ENC 0x0020 +#define EVP_PKT_EXCH 0x0040 +#define EVP_PKS_RSA 0x0100 +#define EVP_PKS_DSA 0x0200 +#define EVP_PKS_EC 0x0400 +#define EVP_PKT_EXP 0x1000 /* <= 512 bit key */ + +#define EVP_PKEY_NONE NID_undef +#define EVP_PKEY_RSA NID_rsaEncryption +#define EVP_PKEY_RSA2 NID_rsa +#define EVP_PKEY_DSA NID_dsa +#define EVP_PKEY_DSA1 NID_dsa_2 +#define EVP_PKEY_DSA2 NID_dsaWithSHA +#define EVP_PKEY_DSA3 NID_dsaWithSHA1 +#define EVP_PKEY_DSA4 NID_dsaWithSHA1_2 +#define EVP_PKEY_DH NID_dhKeyAgreement +#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey +#define EVP_PKEY_HMAC NID_hmac + +#ifdef __cplusplus +extern "C" { +#endif + +/* Type needs to be a bit field + * Sub-type needs to be for variations on the method, as in, can it do + * arbitrary encryption.... */ +struct evp_pkey_st + { + int type; + int save_type; + int references; + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *engine; + union { + char *ptr; +#ifndef OPENSSL_NO_RSA + struct rsa_st *rsa; /* RSA */ +#endif +#ifndef OPENSSL_NO_DSA + struct dsa_st *dsa; /* DSA */ +#endif +#ifndef OPENSSL_NO_DH + struct dh_st *dh; /* DH */ +#endif +#ifndef OPENSSL_NO_EC + struct ec_key_st *ec; /* ECC */ +#endif + } pkey; + int save_parameters; + STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ + } /* EVP_PKEY */; + +#define EVP_PKEY_MO_SIGN 0x0001 +#define EVP_PKEY_MO_VERIFY 0x0002 +#define EVP_PKEY_MO_ENCRYPT 0x0004 +#define EVP_PKEY_MO_DECRYPT 0x0008 + +#ifndef EVP_MD +struct env_md_st + { + int type; + int pkey_type; + int md_size; + unsigned long flags; + int (*init)(EVP_MD_CTX *ctx); + int (*update)(EVP_MD_CTX *ctx,const void *data,size_t count); + int (*final)(EVP_MD_CTX *ctx,unsigned char *md); + int (*copy)(EVP_MD_CTX *to,const EVP_MD_CTX *from); + int (*cleanup)(EVP_MD_CTX *ctx); + + /* FIXME: prototype these some day */ + int (*sign)(int type, const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, void *key); + int (*verify)(int type, const unsigned char *m, unsigned int m_length, + const unsigned char *sigbuf, unsigned int siglen, + void *key); + int required_pkey_type[5]; /*EVP_PKEY_xxx */ + int block_size; + int ctx_size; /* how big does the ctx->md_data need to be */ + /* control function */ + int (*md_ctrl)(EVP_MD_CTX *ctx, int cmd, int p1, void *p2); + } /* EVP_MD */; + +typedef int evp_sign_method(int type,const unsigned char *m, + unsigned int m_length,unsigned char *sigret, + unsigned int *siglen, void *key); +typedef int evp_verify_method(int type,const unsigned char *m, + unsigned int m_length,const unsigned char *sigbuf, + unsigned int siglen, void *key); + +#define EVP_MD_FLAG_ONESHOT 0x0001 /* digest can only handle a single + * block */ + +#define EVP_MD_FLAG_PKEY_DIGEST 0x0002 /* digest is a "clone" digest used + * which is a copy of an existing + * one for a specific public key type. + * EVP_dss1() etc */ + +/* Digest uses EVP_PKEY_METHOD for signing instead of MD specific signing */ + +#define EVP_MD_FLAG_PKEY_METHOD_SIGNATURE 0x0004 + +/* DigestAlgorithmIdentifier flags... */ + +#define EVP_MD_FLAG_DIGALGID_MASK 0x0018 + +/* NULL or absent parameter accepted. Use NULL */ + +#define EVP_MD_FLAG_DIGALGID_NULL 0x0000 + +/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */ + +#define EVP_MD_FLAG_DIGALGID_ABSENT 0x0008 + +/* Custom handling via ctrl */ + +#define EVP_MD_FLAG_DIGALGID_CUSTOM 0x0018 + +/* Digest ctrls */ + +#define EVP_MD_CTRL_DIGALGID 0x1 +#define EVP_MD_CTRL_MICALG 0x2 + +/* Minimum Algorithm specific ctrl value */ + +#define EVP_MD_CTRL_ALG_CTRL 0x1000 + +#define EVP_PKEY_NULL_method NULL,NULL,{0,0,0,0} + +#ifndef OPENSSL_NO_DSA +#define EVP_PKEY_DSA_method (evp_sign_method *)DSA_sign, \ + (evp_verify_method *)DSA_verify, \ + {EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3, \ + EVP_PKEY_DSA4,0} +#else +#define EVP_PKEY_DSA_method EVP_PKEY_NULL_method +#endif + +#ifndef OPENSSL_NO_ECDSA +#define EVP_PKEY_ECDSA_method (evp_sign_method *)ECDSA_sign, \ + (evp_verify_method *)ECDSA_verify, \ + {EVP_PKEY_EC,0,0,0} +#else +#define EVP_PKEY_ECDSA_method EVP_PKEY_NULL_method +#endif + +#ifndef OPENSSL_NO_RSA +#define EVP_PKEY_RSA_method (evp_sign_method *)RSA_sign, \ + (evp_verify_method *)RSA_verify, \ + {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0} +#define EVP_PKEY_RSA_ASN1_OCTET_STRING_method \ + (evp_sign_method *)RSA_sign_ASN1_OCTET_STRING, \ + (evp_verify_method *)RSA_verify_ASN1_OCTET_STRING, \ + {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0} +#else +#define EVP_PKEY_RSA_method EVP_PKEY_NULL_method +#define EVP_PKEY_RSA_ASN1_OCTET_STRING_method EVP_PKEY_NULL_method +#endif + +#endif /* !EVP_MD */ + +struct env_md_ctx_st + { + const EVP_MD *digest; + ENGINE *engine; /* functional reference if 'digest' is ENGINE-provided */ + unsigned long flags; + void *md_data; + /* Public key context for sign/verify */ + EVP_PKEY_CTX *pctx; + /* Update function: usually copied from EVP_MD */ + int (*update)(EVP_MD_CTX *ctx,const void *data,size_t count); + } /* EVP_MD_CTX */; + +/* values for EVP_MD_CTX flags */ + +#define EVP_MD_CTX_FLAG_ONESHOT 0x0001 /* digest update will be called + * once only */ +#define EVP_MD_CTX_FLAG_CLEANED 0x0002 /* context has already been + * cleaned */ +#define EVP_MD_CTX_FLAG_REUSE 0x0004 /* Don't free up ctx->md_data + * in EVP_MD_CTX_cleanup */ +/* FIPS and pad options are ignored in 1.0.0, definitions are here + * so we don't accidentally reuse the values for other purposes. + */ + +#define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0x0008 /* Allow use of non FIPS digest + * in FIPS mode */ + +/* The following PAD options are also currently ignored in 1.0.0, digest + * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*() + * instead. + */ +#define EVP_MD_CTX_FLAG_PAD_MASK 0xF0 /* RSA mode to use */ +#define EVP_MD_CTX_FLAG_PAD_PKCS1 0x00 /* PKCS#1 v1.5 mode */ +#define EVP_MD_CTX_FLAG_PAD_X931 0x10 /* X9.31 mode */ +#define EVP_MD_CTX_FLAG_PAD_PSS 0x20 /* PSS mode */ + +#define EVP_MD_CTX_FLAG_NO_INIT 0x0100 /* Don't initialize md_data */ + +struct evp_cipher_st + { + int nid; + int block_size; + int key_len; /* Default value for variable length ciphers */ + int iv_len; + unsigned long flags; /* Various flags */ + int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); /* init key */ + int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl);/* encrypt/decrypt data */ + int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */ + int ctx_size; /* how big ctx->cipher_data needs to be */ + int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */ + int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */ + int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Miscellaneous operations */ + void *app_data; /* Application data */ + } /* EVP_CIPHER */; + +/* Values for cipher flags */ + +/* Modes for ciphers */ + +#define EVP_CIPH_STREAM_CIPHER 0x0 +#define EVP_CIPH_ECB_MODE 0x1 +#define EVP_CIPH_CBC_MODE 0x2 +#define EVP_CIPH_CFB_MODE 0x3 +#define EVP_CIPH_OFB_MODE 0x4 +#define EVP_CIPH_MODE 0xF0007 +/* Set if variable length cipher */ +#define EVP_CIPH_VARIABLE_LENGTH 0x8 +/* Set if the iv handling should be done by the cipher itself */ +#define EVP_CIPH_CUSTOM_IV 0x10 +/* Set if the cipher's init() function should be called if key is NULL */ +#define EVP_CIPH_ALWAYS_CALL_INIT 0x20 +/* Call ctrl() to init cipher parameters */ +#define EVP_CIPH_CTRL_INIT 0x40 +/* Don't use standard key length function */ +#define EVP_CIPH_CUSTOM_KEY_LENGTH 0x80 +/* Don't use standard block padding */ +#define EVP_CIPH_NO_PADDING 0x100 +/* cipher handles random key generation */ +#define EVP_CIPH_RAND_KEY 0x200 +/* cipher has its own additional copying logic */ +#define EVP_CIPH_CUSTOM_COPY 0x400 +/* Allow use default ASN1 get/set iv */ +#define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000 +/* Buffer length in bits not bytes: CFB1 mode only */ +#define EVP_CIPH_FLAG_LENGTH_BITS 0x2000 + +/* ctrl() values */ + +#define EVP_CTRL_INIT 0x0 +#define EVP_CTRL_SET_KEY_LENGTH 0x1 +#define EVP_CTRL_GET_RC2_KEY_BITS 0x2 +#define EVP_CTRL_SET_RC2_KEY_BITS 0x3 +#define EVP_CTRL_GET_RC5_ROUNDS 0x4 +#define EVP_CTRL_SET_RC5_ROUNDS 0x5 +#define EVP_CTRL_RAND_KEY 0x6 +#define EVP_CTRL_PBE_PRF_NID 0x7 +#define EVP_CTRL_COPY 0x8 + +typedef struct evp_cipher_info_st + { + const EVP_CIPHER *cipher; + unsigned char iv[EVP_MAX_IV_LENGTH]; + } EVP_CIPHER_INFO; + +struct evp_cipher_ctx_st + { + const EVP_CIPHER *cipher; + ENGINE *engine; /* functional reference if 'cipher' is ENGINE-provided */ + int encrypt; /* encrypt or decrypt */ + int buf_len; /* number we have left */ + + unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */ + unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */ + unsigned char buf[EVP_MAX_BLOCK_LENGTH];/* saved partial block */ + int num; /* used by cfb/ofb mode */ + + void *app_data; /* application stuff */ + int key_len; /* May change for variable length cipher */ + unsigned long flags; /* Various flags */ + void *cipher_data; /* per EVP data */ + int final_used; + int block_mask; + unsigned char final[EVP_MAX_BLOCK_LENGTH];/* possible final block */ + } /* EVP_CIPHER_CTX */; + +typedef struct evp_Encode_Ctx_st + { + int num; /* number saved in a partial encode/decode */ + int length; /* The length is either the output line length + * (in input bytes) or the shortest input line + * length that is ok. Once decoding begins, + * the length is adjusted up each time a longer + * line is decoded */ + unsigned char enc_data[80]; /* data to encode */ + int line_num; /* number read on current line */ + int expect_nl; + } EVP_ENCODE_CTX; + +/* Password based encryption function */ +typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de); + +#ifndef OPENSSL_NO_RSA +#define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\ + (char *)(rsa)) +#endif + +#ifndef OPENSSL_NO_DSA +#define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\ + (char *)(dsa)) +#endif + +#ifndef OPENSSL_NO_DH +#define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\ + (char *)(dh)) +#endif + +#ifndef OPENSSL_NO_EC +#define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\ + (char *)(eckey)) +#endif + +/* Add some extra combinations */ +#define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a)) +#define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a)) +#define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a)) +#define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a)) + +int EVP_MD_type(const EVP_MD *md); +#define EVP_MD_nid(e) EVP_MD_type(e) +#define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_nid(e)) +int EVP_MD_pkey_type(const EVP_MD *md); +int EVP_MD_size(const EVP_MD *md); +int EVP_MD_block_size(const EVP_MD *md); +unsigned long EVP_MD_flags(const EVP_MD *md); + +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx); +#define EVP_MD_CTX_size(e) EVP_MD_size(EVP_MD_CTX_md(e)) +#define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e)) +#define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e)) + +int EVP_CIPHER_nid(const EVP_CIPHER *cipher); +#define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) +int EVP_CIPHER_block_size(const EVP_CIPHER *cipher); +int EVP_CIPHER_key_length(const EVP_CIPHER *cipher); +int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher); +unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher); +#define EVP_CIPHER_mode(e) (EVP_CIPHER_flags(e) & EVP_CIPH_MODE) + +const EVP_CIPHER * EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in); +void * EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx); +void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data); +#define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)) +unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx); +#define EVP_CIPHER_CTX_mode(e) (EVP_CIPHER_CTX_flags(e) & EVP_CIPH_MODE) + +#define EVP_ENCODE_LENGTH(l) (((l+2)/3*4)+(l/48+1)*2+80) +#define EVP_DECODE_LENGTH(l) ((l+3)/4*3+80) + +#define EVP_SignInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) +#define EVP_SignInit(a,b) EVP_DigestInit(a,b) +#define EVP_SignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +#define EVP_VerifyInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) +#define EVP_VerifyInit(a,b) EVP_DigestInit(a,b) +#define EVP_VerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +#define EVP_OpenUpdate(a,b,c,d,e) EVP_DecryptUpdate(a,b,c,d,e) +#define EVP_SealUpdate(a,b,c,d,e) EVP_EncryptUpdate(a,b,c,d,e) +#define EVP_DigestSignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +#define EVP_DigestVerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) + +#ifdef CONST_STRICT +void BIO_set_md(BIO *,const EVP_MD *md); +#else +# define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,0,(char *)md) +#endif +#define BIO_get_md(b,mdp) BIO_ctrl(b,BIO_C_GET_MD,0,(char *)mdp) +#define BIO_get_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(char *)mdcp) +#define BIO_set_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_SET_MD_CTX,0,(char *)mdcp) +#define BIO_get_cipher_status(b) BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL) +#define BIO_get_cipher_ctx(b,c_pp) BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(char *)c_pp) + +int EVP_Cipher(EVP_CIPHER_CTX *c, + unsigned char *out, + const unsigned char *in, + unsigned int inl); + +#define EVP_add_cipher_alias(n,alias) \ + OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n)) +#define EVP_add_digest_alias(n,alias) \ + OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n)) +#define EVP_delete_cipher_alias(alias) \ + OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS); +#define EVP_delete_digest_alias(alias) \ + OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS); + +void EVP_MD_CTX_init(EVP_MD_CTX *ctx); +int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx); +EVP_MD_CTX *EVP_MD_CTX_create(void); +void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); +int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out,const EVP_MD_CTX *in); +void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); +void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags); +int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx,int flags); +int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); +int EVP_DigestUpdate(EVP_MD_CTX *ctx,const void *d, + size_t cnt); +int EVP_DigestFinal_ex(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s); +int EVP_Digest(const void *data, size_t count, + unsigned char *md, unsigned int *size, const EVP_MD *type, ENGINE *impl); + +int EVP_MD_CTX_copy(EVP_MD_CTX *out,const EVP_MD_CTX *in); +int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); +int EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s); + +int EVP_read_pw_string(char *buf,int length,const char *prompt,int verify); +int EVP_read_pw_string_min(char *buf,int minlen,int maxlen,const char *prompt,int verify); +void EVP_set_pw_prompt(const char *prompt); +char * EVP_get_pw_prompt(void); + +int EVP_BytesToKey(const EVP_CIPHER *type,const EVP_MD *md, + const unsigned char *salt, const unsigned char *data, + int datal, int count, unsigned char *key,unsigned char *iv); + +void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags); +void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags); +int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx,int flags); + +int EVP_EncryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv); +int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl, + const unsigned char *key, const unsigned char *iv); +int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl, const unsigned char *in, int inl); +int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); +int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); + +int EVP_DecryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv); +int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl, + const unsigned char *key, const unsigned char *iv); +int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl, const unsigned char *in, int inl); +int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); +int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); + +int EVP_CipherInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, + const unsigned char *key,const unsigned char *iv, + int enc); +int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl, + const unsigned char *key,const unsigned char *iv, + int enc); +int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *outl, const unsigned char *in, int inl); +int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); +int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); + +int EVP_SignFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s, + EVP_PKEY *pkey); + +int EVP_VerifyFinal(EVP_MD_CTX *ctx,const unsigned char *sigbuf, + unsigned int siglen,EVP_PKEY *pkey); + +int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); +int EVP_DigestSignFinal(EVP_MD_CTX *ctx, + unsigned char *sigret, size_t *siglen); + +int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); +int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, + unsigned char *sig, size_t siglen); + +int EVP_OpenInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type, + const unsigned char *ek, int ekl, const unsigned char *iv, + EVP_PKEY *priv); +int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); + +int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + unsigned char **ek, int *ekl, unsigned char *iv, + EVP_PKEY **pubk, int npubk); +int EVP_SealFinal(EVP_CIPHER_CTX *ctx,unsigned char *out,int *outl); + +void EVP_EncodeInit(EVP_ENCODE_CTX *ctx); +void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl, + const unsigned char *in,int inl); +void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl); +int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n); + +void EVP_DecodeInit(EVP_ENCODE_CTX *ctx); +int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl, + const unsigned char *in, int inl); +int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned + char *out, int *outl); +int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n); + +void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a); +int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a); +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *a); +int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen); +int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad); +int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); +int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key); + +#ifndef OPENSSL_NO_BIO +BIO_METHOD *BIO_f_md(void); +BIO_METHOD *BIO_f_base64(void); +BIO_METHOD *BIO_f_cipher(void); +BIO_METHOD *BIO_f_reliable(void); +void BIO_set_cipher(BIO *b,const EVP_CIPHER *c,const unsigned char *k, + const unsigned char *i, int enc); +#endif + +const EVP_MD *EVP_md_null(void); +#ifndef OPENSSL_NO_MD2 +const EVP_MD *EVP_md2(void); +#endif +#ifndef OPENSSL_NO_MD4 +const EVP_MD *EVP_md4(void); +#endif +#ifndef OPENSSL_NO_MD5 +const EVP_MD *EVP_md5(void); +#endif +#ifndef OPENSSL_NO_SHA +const EVP_MD *EVP_sha(void); +const EVP_MD *EVP_sha1(void); +const EVP_MD *EVP_dss(void); +const EVP_MD *EVP_dss1(void); +const EVP_MD *EVP_ecdsa(void); +#endif +#ifndef OPENSSL_NO_SHA256 +const EVP_MD *EVP_sha224(void); +const EVP_MD *EVP_sha256(void); +#endif +#ifndef OPENSSL_NO_SHA512 +const EVP_MD *EVP_sha384(void); +const EVP_MD *EVP_sha512(void); +#endif +#ifndef OPENSSL_NO_MDC2 +const EVP_MD *EVP_mdc2(void); +#endif +#ifndef OPENSSL_NO_RIPEMD +const EVP_MD *EVP_ripemd160(void); +#endif +#ifndef OPENSSL_NO_WHIRLPOOL +const EVP_MD *EVP_whirlpool(void); +#endif +const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */ +#ifndef OPENSSL_NO_DES +const EVP_CIPHER *EVP_des_ecb(void); +const EVP_CIPHER *EVP_des_ede(void); +const EVP_CIPHER *EVP_des_ede3(void); +const EVP_CIPHER *EVP_des_ede_ecb(void); +const EVP_CIPHER *EVP_des_ede3_ecb(void); +const EVP_CIPHER *EVP_des_cfb64(void); +# define EVP_des_cfb EVP_des_cfb64 +const EVP_CIPHER *EVP_des_cfb1(void); +const EVP_CIPHER *EVP_des_cfb8(void); +const EVP_CIPHER *EVP_des_ede_cfb64(void); +# define EVP_des_ede_cfb EVP_des_ede_cfb64 +#if 0 +const EVP_CIPHER *EVP_des_ede_cfb1(void); +const EVP_CIPHER *EVP_des_ede_cfb8(void); +#endif +const EVP_CIPHER *EVP_des_ede3_cfb64(void); +# define EVP_des_ede3_cfb EVP_des_ede3_cfb64 +const EVP_CIPHER *EVP_des_ede3_cfb1(void); +const EVP_CIPHER *EVP_des_ede3_cfb8(void); +const EVP_CIPHER *EVP_des_ofb(void); +const EVP_CIPHER *EVP_des_ede_ofb(void); +const EVP_CIPHER *EVP_des_ede3_ofb(void); +const EVP_CIPHER *EVP_des_cbc(void); +const EVP_CIPHER *EVP_des_ede_cbc(void); +const EVP_CIPHER *EVP_des_ede3_cbc(void); +const EVP_CIPHER *EVP_desx_cbc(void); +/* This should now be supported through the dev_crypto ENGINE. But also, why are + * rc4 and md5 declarations made here inside a "NO_DES" precompiler branch? */ +#if 0 +# ifdef OPENSSL_OPENBSD_DEV_CRYPTO +const EVP_CIPHER *EVP_dev_crypto_des_ede3_cbc(void); +const EVP_CIPHER *EVP_dev_crypto_rc4(void); +const EVP_MD *EVP_dev_crypto_md5(void); +# endif +#endif +#endif +#ifndef OPENSSL_NO_RC4 +const EVP_CIPHER *EVP_rc4(void); +const EVP_CIPHER *EVP_rc4_40(void); +#endif +#ifndef OPENSSL_NO_IDEA +const EVP_CIPHER *EVP_idea_ecb(void); +const EVP_CIPHER *EVP_idea_cfb64(void); +# define EVP_idea_cfb EVP_idea_cfb64 +const EVP_CIPHER *EVP_idea_ofb(void); +const EVP_CIPHER *EVP_idea_cbc(void); +#endif +#ifndef OPENSSL_NO_RC2 +const EVP_CIPHER *EVP_rc2_ecb(void); +const EVP_CIPHER *EVP_rc2_cbc(void); +const EVP_CIPHER *EVP_rc2_40_cbc(void); +const EVP_CIPHER *EVP_rc2_64_cbc(void); +const EVP_CIPHER *EVP_rc2_cfb64(void); +# define EVP_rc2_cfb EVP_rc2_cfb64 +const EVP_CIPHER *EVP_rc2_ofb(void); +#endif +#ifndef OPENSSL_NO_BF +const EVP_CIPHER *EVP_bf_ecb(void); +const EVP_CIPHER *EVP_bf_cbc(void); +const EVP_CIPHER *EVP_bf_cfb64(void); +# define EVP_bf_cfb EVP_bf_cfb64 +const EVP_CIPHER *EVP_bf_ofb(void); +#endif +#ifndef OPENSSL_NO_CAST +const EVP_CIPHER *EVP_cast5_ecb(void); +const EVP_CIPHER *EVP_cast5_cbc(void); +const EVP_CIPHER *EVP_cast5_cfb64(void); +# define EVP_cast5_cfb EVP_cast5_cfb64 +const EVP_CIPHER *EVP_cast5_ofb(void); +#endif +#ifndef OPENSSL_NO_RC5 +const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void); +const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void); +const EVP_CIPHER *EVP_rc5_32_12_16_cfb64(void); +# define EVP_rc5_32_12_16_cfb EVP_rc5_32_12_16_cfb64 +const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void); +#endif +#ifndef OPENSSL_NO_AES +const EVP_CIPHER *EVP_aes_128_ecb(void); +const EVP_CIPHER *EVP_aes_128_cbc(void); +const EVP_CIPHER *EVP_aes_128_cfb1(void); +const EVP_CIPHER *EVP_aes_128_cfb8(void); +const EVP_CIPHER *EVP_aes_128_cfb128(void); +# define EVP_aes_128_cfb EVP_aes_128_cfb128 +const EVP_CIPHER *EVP_aes_128_ofb(void); +#if 0 +const EVP_CIPHER *EVP_aes_128_ctr(void); +#endif +const EVP_CIPHER *EVP_aes_192_ecb(void); +const EVP_CIPHER *EVP_aes_192_cbc(void); +const EVP_CIPHER *EVP_aes_192_cfb1(void); +const EVP_CIPHER *EVP_aes_192_cfb8(void); +const EVP_CIPHER *EVP_aes_192_cfb128(void); +# define EVP_aes_192_cfb EVP_aes_192_cfb128 +const EVP_CIPHER *EVP_aes_192_ofb(void); +#if 0 +const EVP_CIPHER *EVP_aes_192_ctr(void); +#endif +const EVP_CIPHER *EVP_aes_256_ecb(void); +const EVP_CIPHER *EVP_aes_256_cbc(void); +const EVP_CIPHER *EVP_aes_256_cfb1(void); +const EVP_CIPHER *EVP_aes_256_cfb8(void); +const EVP_CIPHER *EVP_aes_256_cfb128(void); +# define EVP_aes_256_cfb EVP_aes_256_cfb128 +const EVP_CIPHER *EVP_aes_256_ofb(void); +#if 0 +const EVP_CIPHER *EVP_aes_256_ctr(void); +#endif +#endif +#ifndef OPENSSL_NO_CAMELLIA +const EVP_CIPHER *EVP_camellia_128_ecb(void); +const EVP_CIPHER *EVP_camellia_128_cbc(void); +const EVP_CIPHER *EVP_camellia_128_cfb1(void); +const EVP_CIPHER *EVP_camellia_128_cfb8(void); +const EVP_CIPHER *EVP_camellia_128_cfb128(void); +# define EVP_camellia_128_cfb EVP_camellia_128_cfb128 +const EVP_CIPHER *EVP_camellia_128_ofb(void); +const EVP_CIPHER *EVP_camellia_192_ecb(void); +const EVP_CIPHER *EVP_camellia_192_cbc(void); +const EVP_CIPHER *EVP_camellia_192_cfb1(void); +const EVP_CIPHER *EVP_camellia_192_cfb8(void); +const EVP_CIPHER *EVP_camellia_192_cfb128(void); +# define EVP_camellia_192_cfb EVP_camellia_192_cfb128 +const EVP_CIPHER *EVP_camellia_192_ofb(void); +const EVP_CIPHER *EVP_camellia_256_ecb(void); +const EVP_CIPHER *EVP_camellia_256_cbc(void); +const EVP_CIPHER *EVP_camellia_256_cfb1(void); +const EVP_CIPHER *EVP_camellia_256_cfb8(void); +const EVP_CIPHER *EVP_camellia_256_cfb128(void); +# define EVP_camellia_256_cfb EVP_camellia_256_cfb128 +const EVP_CIPHER *EVP_camellia_256_ofb(void); +#endif + +#ifndef OPENSSL_NO_SEED +const EVP_CIPHER *EVP_seed_ecb(void); +const EVP_CIPHER *EVP_seed_cbc(void); +const EVP_CIPHER *EVP_seed_cfb128(void); +# define EVP_seed_cfb EVP_seed_cfb128 +const EVP_CIPHER *EVP_seed_ofb(void); +#endif + +void OPENSSL_add_all_algorithms_noconf(void); +void OPENSSL_add_all_algorithms_conf(void); + +#ifdef OPENSSL_LOAD_CONF +#define OpenSSL_add_all_algorithms() \ + OPENSSL_add_all_algorithms_conf() +#else +#define OpenSSL_add_all_algorithms() \ + OPENSSL_add_all_algorithms_noconf() +#endif + +void OpenSSL_add_all_ciphers(void); +void OpenSSL_add_all_digests(void); +#define SSLeay_add_all_algorithms() OpenSSL_add_all_algorithms() +#define SSLeay_add_all_ciphers() OpenSSL_add_all_ciphers() +#define SSLeay_add_all_digests() OpenSSL_add_all_digests() + +int EVP_add_cipher(const EVP_CIPHER *cipher); +int EVP_add_digest(const EVP_MD *digest); + +const EVP_CIPHER *EVP_get_cipherbyname(const char *name); +const EVP_MD *EVP_get_digestbyname(const char *name); +void EVP_cleanup(void); + +void EVP_CIPHER_do_all(void (*fn)(const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), void *arg); +void EVP_CIPHER_do_all_sorted(void (*fn)(const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), void *arg); + +void EVP_MD_do_all(void (*fn)(const EVP_MD *ciph, + const char *from, const char *to, void *x), void *arg); +void EVP_MD_do_all_sorted(void (*fn)(const EVP_MD *ciph, + const char *from, const char *to, void *x), void *arg); + +int EVP_PKEY_decrypt_old(unsigned char *dec_key, + const unsigned char *enc_key,int enc_key_len, + EVP_PKEY *private_key); +int EVP_PKEY_encrypt_old(unsigned char *enc_key, + const unsigned char *key,int key_len, + EVP_PKEY *pub_key); +int EVP_PKEY_type(int type); +int EVP_PKEY_id(const EVP_PKEY *pkey); +int EVP_PKEY_base_id(const EVP_PKEY *pkey); +int EVP_PKEY_bits(EVP_PKEY *pkey); +int EVP_PKEY_size(EVP_PKEY *pkey); +int EVP_PKEY_set_type(EVP_PKEY *pkey,int type); +int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len); +int EVP_PKEY_assign(EVP_PKEY *pkey,int type,void *key); +void * EVP_PKEY_get0(EVP_PKEY *pkey); + +#ifndef OPENSSL_NO_RSA +struct rsa_st; +int EVP_PKEY_set1_RSA(EVP_PKEY *pkey,struct rsa_st *key); +struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey); +#endif +#ifndef OPENSSL_NO_DSA +struct dsa_st; +int EVP_PKEY_set1_DSA(EVP_PKEY *pkey,struct dsa_st *key); +struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey); +#endif +#ifndef OPENSSL_NO_DH +struct dh_st; +int EVP_PKEY_set1_DH(EVP_PKEY *pkey,struct dh_st *key); +struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey); +#endif +#ifndef OPENSSL_NO_EC +struct ec_key_st; +int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey,struct ec_key_st *key); +struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); +#endif + +EVP_PKEY * EVP_PKEY_new(void); +void EVP_PKEY_free(EVP_PKEY *pkey); + +EVP_PKEY * d2i_PublicKey(int type,EVP_PKEY **a, const unsigned char **pp, + long length); +int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp); + +EVP_PKEY * d2i_PrivateKey(int type,EVP_PKEY **a, const unsigned char **pp, + long length); +EVP_PKEY * d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, + long length); +int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp); + +int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); +int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); +int EVP_PKEY_save_parameters(EVP_PKEY *pkey,int mode); +int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b); + +int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); + +int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); +int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); +int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + +int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid); + +int EVP_CIPHER_type(const EVP_CIPHER *ctx); + +/* calls methods */ +int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + +/* These are used by EVP_CIPHER methods */ +int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c,ASN1_TYPE *type); +int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c,ASN1_TYPE *type); + +/* PKCS5 password based encryption */ +int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, + int en_de); +int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + int keylen, unsigned char *out); +int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + const EVP_MD *digest, + int keylen, unsigned char *out); +int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md, + int en_de); + +void PKCS5_PBE_add(void); + +int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen, + ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de); + +/* PBE type */ + +/* Can appear as the outermost AlgorithmIdentifier */ +#define EVP_PBE_TYPE_OUTER 0x0 +/* Is an PRF type OID */ +#define EVP_PBE_TYPE_PRF 0x1 + +int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, int md_nid, + EVP_PBE_KEYGEN *keygen); +int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, + EVP_PBE_KEYGEN *keygen); +int EVP_PBE_find(int type, int pbe_nid, + int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen); +void EVP_PBE_cleanup(void); + +#define ASN1_PKEY_ALIAS 0x1 +#define ASN1_PKEY_DYNAMIC 0x2 +#define ASN1_PKEY_SIGPARAM_NULL 0x4 + +#define ASN1_PKEY_CTRL_PKCS7_SIGN 0x1 +#define ASN1_PKEY_CTRL_PKCS7_ENCRYPT 0x2 +#define ASN1_PKEY_CTRL_DEFAULT_MD_NID 0x3 +#define ASN1_PKEY_CTRL_CMS_SIGN 0x5 +#define ASN1_PKEY_CTRL_CMS_ENVELOPE 0x7 + +int EVP_PKEY_asn1_get_count(void); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, + const char *str, int len); +int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth); +int EVP_PKEY_asn1_add_alias(int to, int from); +int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, int *ppkey_flags, + const char **pinfo, const char **ppem_str, + const EVP_PKEY_ASN1_METHOD *ameth); + +const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey); +EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags, + const char *pem_str, const char *info); +void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, + const EVP_PKEY_ASN1_METHOD *src); +void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth); +void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, + int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub), + int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk), + int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b), + int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx), + int (*pkey_size)(const EVP_PKEY *pk), + int (*pkey_bits)(const EVP_PKEY *pk)); +void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth, + int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf), + int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk), + int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx)); +void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth, + int (*param_decode)(EVP_PKEY *pkey, + const unsigned char **pder, int derlen), + int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder), + int (*param_missing)(const EVP_PKEY *pk), + int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from), + int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b), + int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx)); + +void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth, + void (*pkey_free)(EVP_PKEY *pkey)); +void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_ctrl)(EVP_PKEY *pkey, int op, + long arg1, void *arg2)); + + +#define EVP_PKEY_OP_UNDEFINED 0 +#define EVP_PKEY_OP_PARAMGEN (1<<1) +#define EVP_PKEY_OP_KEYGEN (1<<2) +#define EVP_PKEY_OP_SIGN (1<<3) +#define EVP_PKEY_OP_VERIFY (1<<4) +#define EVP_PKEY_OP_VERIFYRECOVER (1<<5) +#define EVP_PKEY_OP_SIGNCTX (1<<6) +#define EVP_PKEY_OP_VERIFYCTX (1<<7) +#define EVP_PKEY_OP_ENCRYPT (1<<8) +#define EVP_PKEY_OP_DECRYPT (1<<9) +#define EVP_PKEY_OP_DERIVE (1<<10) + +#define EVP_PKEY_OP_TYPE_SIG \ + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \ + | EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX) + +#define EVP_PKEY_OP_TYPE_CRYPT \ + (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT) + +#define EVP_PKEY_OP_TYPE_NOGEN \ + (EVP_PKEY_OP_SIG | EVP_PKEY_OP_CRYPT | EVP_PKEY_OP_DERIVE) + +#define EVP_PKEY_OP_TYPE_GEN \ + (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN) + +#define EVP_PKEY_CTX_set_signature_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_MD, 0, (void *)md) + +#define EVP_PKEY_CTRL_MD 1 +#define EVP_PKEY_CTRL_PEER_KEY 2 + +#define EVP_PKEY_CTRL_PKCS7_ENCRYPT 3 +#define EVP_PKEY_CTRL_PKCS7_DECRYPT 4 + +#define EVP_PKEY_CTRL_PKCS7_SIGN 5 + +#define EVP_PKEY_CTRL_SET_MAC_KEY 6 + +#define EVP_PKEY_CTRL_DIGESTINIT 7 + +/* Used by GOST key encryption in TLS */ +#define EVP_PKEY_CTRL_SET_IV 8 + +#define EVP_PKEY_CTRL_CMS_ENCRYPT 9 +#define EVP_PKEY_CTRL_CMS_DECRYPT 10 +#define EVP_PKEY_CTRL_CMS_SIGN 11 + +#define EVP_PKEY_ALG_CTRL 0x1000 + + +#define EVP_PKEY_FLAG_AUTOARGLEN 2 + +const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type); +EVP_PKEY_METHOD* EVP_PKEY_meth_new(int id, int flags); +void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth); +int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth); + +EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2); +int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, + const char *value); + +int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen); + +EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, + unsigned char *key, int keylen); + +void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx); +EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx); + +EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx); + +void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen); +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); + +typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); + +void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb); +EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx); + +void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, + int (*init)(EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, + int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)); + +void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, + void (*cleanup)(EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, + int (*paramgen_init)(EVP_PKEY_CTX *ctx), + int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, + int (*keygen_init)(EVP_PKEY_CTX *ctx), + int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, + int (*sign_init)(EVP_PKEY_CTX *ctx), + int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen)); + +void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, + int (*verify_init)(EVP_PKEY_CTX *ctx), + int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen)); + +void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, + int (*verify_recover_init)(EVP_PKEY_CTX *ctx), + int (*verify_recover)(EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen)); + +void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, + int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx), + int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, + int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx), + int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig,int siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, + int (*encrypt_init)(EVP_PKEY_CTX *ctx), + int (*encryptfn)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen)); + +void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, + int (*decrypt_init)(EVP_PKEY_CTX *ctx), + int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen)); + +void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, + int (*derive_init)(EVP_PKEY_CTX *ctx), + int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)); + +void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, + int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2), + int (*ctrl_str)(EVP_PKEY_CTX *ctx, + const char *type, const char *value)); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_EVP_strings(void); + +/* Error codes for the EVP functions. */ + +/* Function codes. */ +#define EVP_F_AES_INIT_KEY 133 +#define EVP_F_CAMELLIA_INIT_KEY 159 +#define EVP_F_D2I_PKEY 100 +#define EVP_F_DO_SIGVER_INIT 161 +#define EVP_F_DSAPKEY2PKCS8 134 +#define EVP_F_DSA_PKEY2PKCS8 135 +#define EVP_F_ECDSA_PKEY2PKCS8 129 +#define EVP_F_ECKEY_PKEY2PKCS8 132 +#define EVP_F_EVP_CIPHERINIT_EX 123 +#define EVP_F_EVP_CIPHER_CTX_COPY 163 +#define EVP_F_EVP_CIPHER_CTX_CTRL 124 +#define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122 +#define EVP_F_EVP_DECRYPTFINAL_EX 101 +#define EVP_F_EVP_DIGESTINIT_EX 128 +#define EVP_F_EVP_ENCRYPTFINAL_EX 127 +#define EVP_F_EVP_MD_CTX_COPY_EX 110 +#define EVP_F_EVP_MD_SIZE 162 +#define EVP_F_EVP_OPENINIT 102 +#define EVP_F_EVP_PBE_ALG_ADD 115 +#define EVP_F_EVP_PBE_ALG_ADD_TYPE 160 +#define EVP_F_EVP_PBE_CIPHERINIT 116 +#define EVP_F_EVP_PKCS82PKEY 111 +#define EVP_F_EVP_PKCS82PKEY_BROKEN 136 +#define EVP_F_EVP_PKEY2PKCS8_BROKEN 113 +#define EVP_F_EVP_PKEY_COPY_PARAMETERS 103 +#define EVP_F_EVP_PKEY_CTX_CTRL 137 +#define EVP_F_EVP_PKEY_CTX_CTRL_STR 150 +#define EVP_F_EVP_PKEY_CTX_DUP 156 +#define EVP_F_EVP_PKEY_DECRYPT 104 +#define EVP_F_EVP_PKEY_DECRYPT_INIT 138 +#define EVP_F_EVP_PKEY_DECRYPT_OLD 151 +#define EVP_F_EVP_PKEY_DERIVE 153 +#define EVP_F_EVP_PKEY_DERIVE_INIT 154 +#define EVP_F_EVP_PKEY_DERIVE_SET_PEER 155 +#define EVP_F_EVP_PKEY_ENCRYPT 105 +#define EVP_F_EVP_PKEY_ENCRYPT_INIT 139 +#define EVP_F_EVP_PKEY_ENCRYPT_OLD 152 +#define EVP_F_EVP_PKEY_GET1_DH 119 +#define EVP_F_EVP_PKEY_GET1_DSA 120 +#define EVP_F_EVP_PKEY_GET1_ECDSA 130 +#define EVP_F_EVP_PKEY_GET1_EC_KEY 131 +#define EVP_F_EVP_PKEY_GET1_RSA 121 +#define EVP_F_EVP_PKEY_KEYGEN 146 +#define EVP_F_EVP_PKEY_KEYGEN_INIT 147 +#define EVP_F_EVP_PKEY_NEW 106 +#define EVP_F_EVP_PKEY_PARAMGEN 148 +#define EVP_F_EVP_PKEY_PARAMGEN_INIT 149 +#define EVP_F_EVP_PKEY_SIGN 140 +#define EVP_F_EVP_PKEY_SIGN_INIT 141 +#define EVP_F_EVP_PKEY_VERIFY 142 +#define EVP_F_EVP_PKEY_VERIFY_INIT 143 +#define EVP_F_EVP_PKEY_VERIFY_RECOVER 144 +#define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT 145 +#define EVP_F_EVP_RIJNDAEL 126 +#define EVP_F_EVP_SIGNFINAL 107 +#define EVP_F_EVP_VERIFYFINAL 108 +#define EVP_F_INT_CTX_NEW 157 +#define EVP_F_PKCS5_PBE_KEYIVGEN 117 +#define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118 +#define EVP_F_PKCS8_SET_BROKEN 112 +#define EVP_F_PKEY_SET_TYPE 158 +#define EVP_F_RC2_MAGIC_TO_METH 109 +#define EVP_F_RC5_CTRL 125 + +/* Reason codes. */ +#define EVP_R_AES_KEY_SETUP_FAILED 143 +#define EVP_R_ASN1_LIB 140 +#define EVP_R_BAD_BLOCK_LENGTH 136 +#define EVP_R_BAD_DECRYPT 100 +#define EVP_R_BAD_KEY_LENGTH 137 +#define EVP_R_BN_DECODE_ERROR 112 +#define EVP_R_BN_PUBKEY_ERROR 113 +#define EVP_R_BUFFER_TOO_SMALL 155 +#define EVP_R_CAMELLIA_KEY_SETUP_FAILED 157 +#define EVP_R_CIPHER_PARAMETER_ERROR 122 +#define EVP_R_COMMAND_NOT_SUPPORTED 147 +#define EVP_R_CTRL_NOT_IMPLEMENTED 132 +#define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED 133 +#define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138 +#define EVP_R_DECODE_ERROR 114 +#define EVP_R_DIFFERENT_KEY_TYPES 101 +#define EVP_R_DIFFERENT_PARAMETERS 153 +#define EVP_R_ENCODE_ERROR 115 +#define EVP_R_EVP_PBE_CIPHERINIT_ERROR 119 +#define EVP_R_EXPECTING_AN_RSA_KEY 127 +#define EVP_R_EXPECTING_A_DH_KEY 128 +#define EVP_R_EXPECTING_A_DSA_KEY 129 +#define EVP_R_EXPECTING_A_ECDSA_KEY 141 +#define EVP_R_EXPECTING_A_EC_KEY 142 +#define EVP_R_INITIALIZATION_ERROR 134 +#define EVP_R_INPUT_NOT_INITIALIZED 111 +#define EVP_R_INVALID_DIGEST 152 +#define EVP_R_INVALID_KEY_LENGTH 130 +#define EVP_R_INVALID_OPERATION 148 +#define EVP_R_IV_TOO_LARGE 102 +#define EVP_R_KEYGEN_FAILURE 120 +#define EVP_R_MESSAGE_DIGEST_IS_NULL 159 +#define EVP_R_METHOD_NOT_SUPPORTED 144 +#define EVP_R_MISSING_PARAMETERS 103 +#define EVP_R_NO_CIPHER_SET 131 +#define EVP_R_NO_DEFAULT_DIGEST 158 +#define EVP_R_NO_DIGEST_SET 139 +#define EVP_R_NO_DSA_PARAMETERS 116 +#define EVP_R_NO_KEY_SET 154 +#define EVP_R_NO_OPERATION_SET 149 +#define EVP_R_NO_SIGN_FUNCTION_CONFIGURED 104 +#define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105 +#define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150 +#define EVP_R_OPERATON_NOT_INITIALIZED 151 +#define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE 117 +#define EVP_R_PRIVATE_KEY_DECODE_ERROR 145 +#define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146 +#define EVP_R_PUBLIC_KEY_NOT_RSA 106 +#define EVP_R_UNKNOWN_CIPHER 160 +#define EVP_R_UNKNOWN_DIGEST 161 +#define EVP_R_UNKNOWN_PBE_ALGORITHM 121 +#define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135 +#define EVP_R_UNSUPPORTED_ALGORITHM 156 +#define EVP_R_UNSUPPORTED_CIPHER 107 +#define EVP_R_UNSUPPORTED_KEYLENGTH 123 +#define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 124 +#define EVP_R_UNSUPPORTED_KEY_SIZE 108 +#define EVP_R_UNSUPPORTED_PRF 125 +#define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 118 +#define EVP_R_UNSUPPORTED_SALT_TYPE 126 +#define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109 +#define EVP_R_WRONG_PUBLIC_KEY_TYPE 110 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/hmac.h b/extra_lib/include/openssl/hmac.h new file mode 100644 index 0000000..1be0022 --- /dev/null +++ b/extra_lib/include/openssl/hmac.h @@ -0,0 +1,110 @@ +/* crypto/hmac/hmac.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +#ifndef HEADER_HMAC_H +#define HEADER_HMAC_H + +#include + +#ifdef OPENSSL_NO_HMAC +#error HMAC is disabled. +#endif + +#include + +#define HMAC_MAX_MD_CBLOCK 128 /* largest known is SHA512 */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct hmac_ctx_st + { + const EVP_MD *md; + EVP_MD_CTX md_ctx; + EVP_MD_CTX i_ctx; + EVP_MD_CTX o_ctx; + unsigned int key_length; + unsigned char key[HMAC_MAX_MD_CBLOCK]; + } HMAC_CTX; + +#define HMAC_size(e) (EVP_MD_size((e)->md)) + + +void HMAC_CTX_init(HMAC_CTX *ctx); +void HMAC_CTX_cleanup(HMAC_CTX *ctx); + +#define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx) /* deprecated */ + +int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, + const EVP_MD *md); /* deprecated */ +int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, + const EVP_MD *md, ENGINE *impl); +int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len); +int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); +unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, + const unsigned char *d, size_t n, unsigned char *md, + unsigned int *md_len); +int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx); + +void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/extra_lib/include/openssl/kssl.h b/extra_lib/include/openssl/kssl.h new file mode 100644 index 0000000..a3d20e1 --- /dev/null +++ b/extra_lib/include/openssl/kssl.h @@ -0,0 +1,179 @@ +/* ssl/kssl.h -*- mode: C; c-file-style: "eay" -*- */ +/* Written by Vern Staats for the OpenSSL project 2000. + * project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* +** 19990701 VRS Started. +*/ + +#ifndef KSSL_H +#define KSSL_H + +#include + +#ifndef OPENSSL_NO_KRB5 + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Depending on which KRB5 implementation used, some types from +** the other may be missing. Resolve that here and now +*/ +#ifdef KRB5_HEIMDAL +typedef unsigned char krb5_octet; +#define FAR +#else + +#ifndef FAR +#define FAR +#endif + +#endif + +/* Uncomment this to debug kssl problems or +** to trace usage of the Kerberos session key +** +** #define KSSL_DEBUG +*/ + +#ifndef KRB5SVC +#define KRB5SVC "host" +#endif + +#ifndef KRB5KEYTAB +#define KRB5KEYTAB "/etc/krb5.keytab" +#endif + +#ifndef KRB5SENDAUTH +#define KRB5SENDAUTH 1 +#endif + +#ifndef KRB5CHECKAUTH +#define KRB5CHECKAUTH 1 +#endif + +#ifndef KSSL_CLOCKSKEW +#define KSSL_CLOCKSKEW 300; +#endif + +#define KSSL_ERR_MAX 255 +typedef struct kssl_err_st { + int reason; + char text[KSSL_ERR_MAX+1]; + } KSSL_ERR; + + +/* Context for passing +** (1) Kerberos session key to SSL, and +** (2) Config data between application and SSL lib +*/ +typedef struct kssl_ctx_st + { + /* used by: disposition: */ + char *service_name; /* C,S default ok (kssl) */ + char *service_host; /* C input, REQUIRED */ + char *client_princ; /* S output from krb5 ticket */ + char *keytab_file; /* S NULL (/etc/krb5.keytab) */ + char *cred_cache; /* C NULL (default) */ + krb5_enctype enctype; + int length; + krb5_octet FAR *key; + } KSSL_CTX; + +#define KSSL_CLIENT 1 +#define KSSL_SERVER 2 +#define KSSL_SERVICE 3 +#define KSSL_KEYTAB 4 + +#define KSSL_CTX_OK 0 +#define KSSL_CTX_ERR 1 +#define KSSL_NOMEM 2 + +/* Public (for use by applications that use OpenSSL with Kerberos 5 support */ +krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text); +KSSL_CTX *kssl_ctx_new(void); +KSSL_CTX *kssl_ctx_free(KSSL_CTX *kssl_ctx); +void kssl_ctx_show(KSSL_CTX *kssl_ctx); +krb5_error_code kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which, + krb5_data *realm, krb5_data *entity, int nentities); +krb5_error_code kssl_cget_tkt(KSSL_CTX *kssl_ctx, krb5_data **enc_tktp, + krb5_data *authenp, KSSL_ERR *kssl_err); +krb5_error_code kssl_sget_tkt(KSSL_CTX *kssl_ctx, krb5_data *indata, + krb5_ticket_times *ttimes, KSSL_ERR *kssl_err); +krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session); +void kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text); +void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data); +krb5_error_code kssl_build_principal_2(krb5_context context, + krb5_principal *princ, int rlen, const char *realm, + int slen, const char *svc, int hlen, const char *host); +krb5_error_code kssl_validate_times(krb5_timestamp atime, + krb5_ticket_times *ttimes); +krb5_error_code kssl_check_authent(KSSL_CTX *kssl_ctx, krb5_data *authentp, + krb5_timestamp *atimep, KSSL_ERR *kssl_err); +unsigned char *kssl_skip_confound(krb5_enctype enctype, unsigned char *authn); + +#ifdef __cplusplus +} +#endif +#endif /* OPENSSL_NO_KRB5 */ +#endif /* KSSL_H */ diff --git a/extra_lib/include/openssl/lhash.h b/extra_lib/include/openssl/lhash.h new file mode 100644 index 0000000..e7d8763 --- /dev/null +++ b/extra_lib/include/openssl/lhash.h @@ -0,0 +1,241 @@ +/* crypto/lhash/lhash.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Header for dynamic hash table routines + * Author - Eric Young + */ + +#ifndef HEADER_LHASH_H +#define HEADER_LHASH_H + +#include +#ifndef OPENSSL_NO_FP_API +#include +#endif + +#ifndef OPENSSL_NO_BIO +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct lhash_node_st + { + void *data; + struct lhash_node_st *next; +#ifndef OPENSSL_NO_HASH_COMP + unsigned long hash; +#endif + } LHASH_NODE; + +typedef int (*LHASH_COMP_FN_TYPE)(const void *, const void *); +typedef unsigned long (*LHASH_HASH_FN_TYPE)(const void *); +typedef void (*LHASH_DOALL_FN_TYPE)(void *); +typedef void (*LHASH_DOALL_ARG_FN_TYPE)(void *, void *); + +/* Macros for declaring and implementing type-safe wrappers for LHASH callbacks. + * This way, callbacks can be provided to LHASH structures without function + * pointer casting and the macro-defined callbacks provide per-variable casting + * before deferring to the underlying type-specific callbacks. NB: It is + * possible to place a "static" in front of both the DECLARE and IMPLEMENT + * macros if the functions are strictly internal. */ + +/* First: "hash" functions */ +#define DECLARE_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *); +#define IMPLEMENT_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *arg) { \ + const o_type *a = arg; \ + return name##_hash(a); } +#define LHASH_HASH_FN(name) name##_LHASH_HASH + +/* Second: "compare" functions */ +#define DECLARE_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *, const void *); +#define IMPLEMENT_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *arg1, const void *arg2) { \ + const o_type *a = arg1; \ + const o_type *b = arg2; \ + return name##_cmp(a,b); } +#define LHASH_COMP_FN(name) name##_LHASH_COMP + +/* Third: "doall" functions */ +#define DECLARE_LHASH_DOALL_FN(name, o_type) \ + void name##_LHASH_DOALL(void *); +#define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \ + void name##_LHASH_DOALL(void *arg) { \ + o_type *a = arg; \ + name##_doall(a); } +#define LHASH_DOALL_FN(name) name##_LHASH_DOALL + +/* Fourth: "doall_arg" functions */ +#define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *, void *); +#define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \ + o_type *a = arg1; \ + a_type *b = arg2; \ + name##_doall_arg(a, b); } +#define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG + +typedef struct lhash_st + { + LHASH_NODE **b; + LHASH_COMP_FN_TYPE comp; + LHASH_HASH_FN_TYPE hash; + unsigned int num_nodes; + unsigned int num_alloc_nodes; + unsigned int p; + unsigned int pmax; + unsigned long up_load; /* load times 256 */ + unsigned long down_load; /* load times 256 */ + unsigned long num_items; + + unsigned long num_expands; + unsigned long num_expand_reallocs; + unsigned long num_contracts; + unsigned long num_contract_reallocs; + unsigned long num_hash_calls; + unsigned long num_comp_calls; + unsigned long num_insert; + unsigned long num_replace; + unsigned long num_delete; + unsigned long num_no_delete; + unsigned long num_retrieve; + unsigned long num_retrieve_miss; + unsigned long num_hash_comps; + + int error; + } _LHASH; /* Do not use _LHASH directly, use LHASH_OF + * and friends */ + +#define LH_LOAD_MULT 256 + +/* Indicates a malloc() error in the last call, this is only bad + * in lh_insert(). */ +#define lh_error(lh) ((lh)->error) + +_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c); +void lh_free(_LHASH *lh); +void *lh_insert(_LHASH *lh, void *data); +void *lh_delete(_LHASH *lh, const void *data); +void *lh_retrieve(_LHASH *lh, const void *data); +void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func); +void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg); +unsigned long lh_strhash(const char *c); +unsigned long lh_num_items(const _LHASH *lh); + +#ifndef OPENSSL_NO_FP_API +void lh_stats(const _LHASH *lh, FILE *out); +void lh_node_stats(const _LHASH *lh, FILE *out); +void lh_node_usage_stats(const _LHASH *lh, FILE *out); +#endif + +#ifndef OPENSSL_NO_BIO +void lh_stats_bio(const _LHASH *lh, BIO *out); +void lh_node_stats_bio(const _LHASH *lh, BIO *out); +void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out); +#endif + +/* Type checking... */ + +#define LHASH_OF(type) struct lhash_st_##type + +#define DECLARE_LHASH_OF(type) LHASH_OF(type) { int dummy; } + +#define CHECKED_LHASH_OF(type,lh) \ + ((_LHASH *)CHECKED_PTR_OF(LHASH_OF(type),lh)) + +/* Define wrapper functions. */ +#define LHM_lh_new(type, name) \ + ((LHASH_OF(type) *)lh_new(LHASH_HASH_FN(name), LHASH_COMP_FN(name))) +#define LHM_lh_error(type, lh) \ + lh_error(CHECKED_LHASH_OF(type,lh)) +#define LHM_lh_insert(type, lh, inst) \ + ((type *)lh_insert(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +#define LHM_lh_retrieve(type, lh, inst) \ + ((type *)lh_retrieve(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +#define LHM_lh_delete(type, lh, inst) \ + ((type *)lh_delete(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +#define LHM_lh_doall(type, lh,fn) lh_doall(CHECKED_LHASH_OF(type, lh), fn) +#define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \ + lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg)) +#define LHM_lh_num_items(type, lh) lh_num_items(CHECKED_LHASH_OF(type, lh)) +#define LHM_lh_down_load(type, lh) (CHECKED_LHASH_OF(type, lh)->down_load) +#define LHM_lh_node_stats_bio(type, lh, out) \ + lh_node_stats_bio(CHECKED_LHASH_OF(type, lh), out) +#define LHM_lh_node_usage_stats_bio(type, lh, out) \ + lh_node_usage_stats_bio(CHECKED_LHASH_OF(type, lh), out) +#define LHM_lh_stats_bio(type, lh, out) \ + lh_stats_bio(CHECKED_LHASH_OF(type, lh), out) +#define LHM_lh_free(type, lh) lh_free(CHECKED_LHASH_OF(type, lh)) + +DECLARE_LHASH_OF(OPENSSL_STRING); +DECLARE_LHASH_OF(OPENSSL_CSTRING); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/extra_lib/include/openssl/obj_mac.h b/extra_lib/include/openssl/obj_mac.h new file mode 100644 index 0000000..282f11a --- /dev/null +++ b/extra_lib/include/openssl/obj_mac.h @@ -0,0 +1,3914 @@ +/* crypto/objects/obj_mac.h */ + +/* THIS FILE IS GENERATED FROM objects.txt by objects.pl via the + * following command: + * perl objects.pl objects.txt obj_mac.num obj_mac.h + */ + +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#define SN_undef "UNDEF" +#define LN_undef "undefined" +#define NID_undef 0 +#define OBJ_undef 0L + +#define SN_itu_t "ITU-T" +#define LN_itu_t "itu-t" +#define NID_itu_t 645 +#define OBJ_itu_t 0L + +#define NID_ccitt 404 +#define OBJ_ccitt OBJ_itu_t + +#define SN_iso "ISO" +#define LN_iso "iso" +#define NID_iso 181 +#define OBJ_iso 1L + +#define SN_joint_iso_itu_t "JOINT-ISO-ITU-T" +#define LN_joint_iso_itu_t "joint-iso-itu-t" +#define NID_joint_iso_itu_t 646 +#define OBJ_joint_iso_itu_t 2L + +#define NID_joint_iso_ccitt 393 +#define OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t + +#define SN_member_body "member-body" +#define LN_member_body "ISO Member Body" +#define NID_member_body 182 +#define OBJ_member_body OBJ_iso,2L + +#define SN_identified_organization "identified-organization" +#define NID_identified_organization 676 +#define OBJ_identified_organization OBJ_iso,3L + +#define SN_hmac_md5 "HMAC-MD5" +#define LN_hmac_md5 "hmac-md5" +#define NID_hmac_md5 780 +#define OBJ_hmac_md5 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L + +#define SN_hmac_sha1 "HMAC-SHA1" +#define LN_hmac_sha1 "hmac-sha1" +#define NID_hmac_sha1 781 +#define OBJ_hmac_sha1 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L + +#define SN_certicom_arc "certicom-arc" +#define NID_certicom_arc 677 +#define OBJ_certicom_arc OBJ_identified_organization,132L + +#define SN_international_organizations "international-organizations" +#define LN_international_organizations "International Organizations" +#define NID_international_organizations 647 +#define OBJ_international_organizations OBJ_joint_iso_itu_t,23L + +#define SN_wap "wap" +#define NID_wap 678 +#define OBJ_wap OBJ_international_organizations,43L + +#define SN_wap_wsg "wap-wsg" +#define NID_wap_wsg 679 +#define OBJ_wap_wsg OBJ_wap,1L + +#define SN_selected_attribute_types "selected-attribute-types" +#define LN_selected_attribute_types "Selected Attribute Types" +#define NID_selected_attribute_types 394 +#define OBJ_selected_attribute_types OBJ_joint_iso_itu_t,5L,1L,5L + +#define SN_clearance "clearance" +#define NID_clearance 395 +#define OBJ_clearance OBJ_selected_attribute_types,55L + +#define SN_ISO_US "ISO-US" +#define LN_ISO_US "ISO US Member Body" +#define NID_ISO_US 183 +#define OBJ_ISO_US OBJ_member_body,840L + +#define SN_X9_57 "X9-57" +#define LN_X9_57 "X9.57" +#define NID_X9_57 184 +#define OBJ_X9_57 OBJ_ISO_US,10040L + +#define SN_X9cm "X9cm" +#define LN_X9cm "X9.57 CM ?" +#define NID_X9cm 185 +#define OBJ_X9cm OBJ_X9_57,4L + +#define SN_dsa "DSA" +#define LN_dsa "dsaEncryption" +#define NID_dsa 116 +#define OBJ_dsa OBJ_X9cm,1L + +#define SN_dsaWithSHA1 "DSA-SHA1" +#define LN_dsaWithSHA1 "dsaWithSHA1" +#define NID_dsaWithSHA1 113 +#define OBJ_dsaWithSHA1 OBJ_X9cm,3L + +#define SN_ansi_X9_62 "ansi-X9-62" +#define LN_ansi_X9_62 "ANSI X9.62" +#define NID_ansi_X9_62 405 +#define OBJ_ansi_X9_62 OBJ_ISO_US,10045L + +#define OBJ_X9_62_id_fieldType OBJ_ansi_X9_62,1L + +#define SN_X9_62_prime_field "prime-field" +#define NID_X9_62_prime_field 406 +#define OBJ_X9_62_prime_field OBJ_X9_62_id_fieldType,1L + +#define SN_X9_62_characteristic_two_field "characteristic-two-field" +#define NID_X9_62_characteristic_two_field 407 +#define OBJ_X9_62_characteristic_two_field OBJ_X9_62_id_fieldType,2L + +#define SN_X9_62_id_characteristic_two_basis "id-characteristic-two-basis" +#define NID_X9_62_id_characteristic_two_basis 680 +#define OBJ_X9_62_id_characteristic_two_basis OBJ_X9_62_characteristic_two_field,3L + +#define SN_X9_62_onBasis "onBasis" +#define NID_X9_62_onBasis 681 +#define OBJ_X9_62_onBasis OBJ_X9_62_id_characteristic_two_basis,1L + +#define SN_X9_62_tpBasis "tpBasis" +#define NID_X9_62_tpBasis 682 +#define OBJ_X9_62_tpBasis OBJ_X9_62_id_characteristic_two_basis,2L + +#define SN_X9_62_ppBasis "ppBasis" +#define NID_X9_62_ppBasis 683 +#define OBJ_X9_62_ppBasis OBJ_X9_62_id_characteristic_two_basis,3L + +#define OBJ_X9_62_id_publicKeyType OBJ_ansi_X9_62,2L + +#define SN_X9_62_id_ecPublicKey "id-ecPublicKey" +#define NID_X9_62_id_ecPublicKey 408 +#define OBJ_X9_62_id_ecPublicKey OBJ_X9_62_id_publicKeyType,1L + +#define OBJ_X9_62_ellipticCurve OBJ_ansi_X9_62,3L + +#define OBJ_X9_62_c_TwoCurve OBJ_X9_62_ellipticCurve,0L + +#define SN_X9_62_c2pnb163v1 "c2pnb163v1" +#define NID_X9_62_c2pnb163v1 684 +#define OBJ_X9_62_c2pnb163v1 OBJ_X9_62_c_TwoCurve,1L + +#define SN_X9_62_c2pnb163v2 "c2pnb163v2" +#define NID_X9_62_c2pnb163v2 685 +#define OBJ_X9_62_c2pnb163v2 OBJ_X9_62_c_TwoCurve,2L + +#define SN_X9_62_c2pnb163v3 "c2pnb163v3" +#define NID_X9_62_c2pnb163v3 686 +#define OBJ_X9_62_c2pnb163v3 OBJ_X9_62_c_TwoCurve,3L + +#define SN_X9_62_c2pnb176v1 "c2pnb176v1" +#define NID_X9_62_c2pnb176v1 687 +#define OBJ_X9_62_c2pnb176v1 OBJ_X9_62_c_TwoCurve,4L + +#define SN_X9_62_c2tnb191v1 "c2tnb191v1" +#define NID_X9_62_c2tnb191v1 688 +#define OBJ_X9_62_c2tnb191v1 OBJ_X9_62_c_TwoCurve,5L + +#define SN_X9_62_c2tnb191v2 "c2tnb191v2" +#define NID_X9_62_c2tnb191v2 689 +#define OBJ_X9_62_c2tnb191v2 OBJ_X9_62_c_TwoCurve,6L + +#define SN_X9_62_c2tnb191v3 "c2tnb191v3" +#define NID_X9_62_c2tnb191v3 690 +#define OBJ_X9_62_c2tnb191v3 OBJ_X9_62_c_TwoCurve,7L + +#define SN_X9_62_c2onb191v4 "c2onb191v4" +#define NID_X9_62_c2onb191v4 691 +#define OBJ_X9_62_c2onb191v4 OBJ_X9_62_c_TwoCurve,8L + +#define SN_X9_62_c2onb191v5 "c2onb191v5" +#define NID_X9_62_c2onb191v5 692 +#define OBJ_X9_62_c2onb191v5 OBJ_X9_62_c_TwoCurve,9L + +#define SN_X9_62_c2pnb208w1 "c2pnb208w1" +#define NID_X9_62_c2pnb208w1 693 +#define OBJ_X9_62_c2pnb208w1 OBJ_X9_62_c_TwoCurve,10L + +#define SN_X9_62_c2tnb239v1 "c2tnb239v1" +#define NID_X9_62_c2tnb239v1 694 +#define OBJ_X9_62_c2tnb239v1 OBJ_X9_62_c_TwoCurve,11L + +#define SN_X9_62_c2tnb239v2 "c2tnb239v2" +#define NID_X9_62_c2tnb239v2 695 +#define OBJ_X9_62_c2tnb239v2 OBJ_X9_62_c_TwoCurve,12L + +#define SN_X9_62_c2tnb239v3 "c2tnb239v3" +#define NID_X9_62_c2tnb239v3 696 +#define OBJ_X9_62_c2tnb239v3 OBJ_X9_62_c_TwoCurve,13L + +#define SN_X9_62_c2onb239v4 "c2onb239v4" +#define NID_X9_62_c2onb239v4 697 +#define OBJ_X9_62_c2onb239v4 OBJ_X9_62_c_TwoCurve,14L + +#define SN_X9_62_c2onb239v5 "c2onb239v5" +#define NID_X9_62_c2onb239v5 698 +#define OBJ_X9_62_c2onb239v5 OBJ_X9_62_c_TwoCurve,15L + +#define SN_X9_62_c2pnb272w1 "c2pnb272w1" +#define NID_X9_62_c2pnb272w1 699 +#define OBJ_X9_62_c2pnb272w1 OBJ_X9_62_c_TwoCurve,16L + +#define SN_X9_62_c2pnb304w1 "c2pnb304w1" +#define NID_X9_62_c2pnb304w1 700 +#define OBJ_X9_62_c2pnb304w1 OBJ_X9_62_c_TwoCurve,17L + +#define SN_X9_62_c2tnb359v1 "c2tnb359v1" +#define NID_X9_62_c2tnb359v1 701 +#define OBJ_X9_62_c2tnb359v1 OBJ_X9_62_c_TwoCurve,18L + +#define SN_X9_62_c2pnb368w1 "c2pnb368w1" +#define NID_X9_62_c2pnb368w1 702 +#define OBJ_X9_62_c2pnb368w1 OBJ_X9_62_c_TwoCurve,19L + +#define SN_X9_62_c2tnb431r1 "c2tnb431r1" +#define NID_X9_62_c2tnb431r1 703 +#define OBJ_X9_62_c2tnb431r1 OBJ_X9_62_c_TwoCurve,20L + +#define OBJ_X9_62_primeCurve OBJ_X9_62_ellipticCurve,1L + +#define SN_X9_62_prime192v1 "prime192v1" +#define NID_X9_62_prime192v1 409 +#define OBJ_X9_62_prime192v1 OBJ_X9_62_primeCurve,1L + +#define SN_X9_62_prime192v2 "prime192v2" +#define NID_X9_62_prime192v2 410 +#define OBJ_X9_62_prime192v2 OBJ_X9_62_primeCurve,2L + +#define SN_X9_62_prime192v3 "prime192v3" +#define NID_X9_62_prime192v3 411 +#define OBJ_X9_62_prime192v3 OBJ_X9_62_primeCurve,3L + +#define SN_X9_62_prime239v1 "prime239v1" +#define NID_X9_62_prime239v1 412 +#define OBJ_X9_62_prime239v1 OBJ_X9_62_primeCurve,4L + +#define SN_X9_62_prime239v2 "prime239v2" +#define NID_X9_62_prime239v2 413 +#define OBJ_X9_62_prime239v2 OBJ_X9_62_primeCurve,5L + +#define SN_X9_62_prime239v3 "prime239v3" +#define NID_X9_62_prime239v3 414 +#define OBJ_X9_62_prime239v3 OBJ_X9_62_primeCurve,6L + +#define SN_X9_62_prime256v1 "prime256v1" +#define NID_X9_62_prime256v1 415 +#define OBJ_X9_62_prime256v1 OBJ_X9_62_primeCurve,7L + +#define OBJ_X9_62_id_ecSigType OBJ_ansi_X9_62,4L + +#define SN_ecdsa_with_SHA1 "ecdsa-with-SHA1" +#define NID_ecdsa_with_SHA1 416 +#define OBJ_ecdsa_with_SHA1 OBJ_X9_62_id_ecSigType,1L + +#define SN_ecdsa_with_Recommended "ecdsa-with-Recommended" +#define NID_ecdsa_with_Recommended 791 +#define OBJ_ecdsa_with_Recommended OBJ_X9_62_id_ecSigType,2L + +#define SN_ecdsa_with_Specified "ecdsa-with-Specified" +#define NID_ecdsa_with_Specified 792 +#define OBJ_ecdsa_with_Specified OBJ_X9_62_id_ecSigType,3L + +#define SN_ecdsa_with_SHA224 "ecdsa-with-SHA224" +#define NID_ecdsa_with_SHA224 793 +#define OBJ_ecdsa_with_SHA224 OBJ_ecdsa_with_Specified,1L + +#define SN_ecdsa_with_SHA256 "ecdsa-with-SHA256" +#define NID_ecdsa_with_SHA256 794 +#define OBJ_ecdsa_with_SHA256 OBJ_ecdsa_with_Specified,2L + +#define SN_ecdsa_with_SHA384 "ecdsa-with-SHA384" +#define NID_ecdsa_with_SHA384 795 +#define OBJ_ecdsa_with_SHA384 OBJ_ecdsa_with_Specified,3L + +#define SN_ecdsa_with_SHA512 "ecdsa-with-SHA512" +#define NID_ecdsa_with_SHA512 796 +#define OBJ_ecdsa_with_SHA512 OBJ_ecdsa_with_Specified,4L + +#define OBJ_secg_ellipticCurve OBJ_certicom_arc,0L + +#define SN_secp112r1 "secp112r1" +#define NID_secp112r1 704 +#define OBJ_secp112r1 OBJ_secg_ellipticCurve,6L + +#define SN_secp112r2 "secp112r2" +#define NID_secp112r2 705 +#define OBJ_secp112r2 OBJ_secg_ellipticCurve,7L + +#define SN_secp128r1 "secp128r1" +#define NID_secp128r1 706 +#define OBJ_secp128r1 OBJ_secg_ellipticCurve,28L + +#define SN_secp128r2 "secp128r2" +#define NID_secp128r2 707 +#define OBJ_secp128r2 OBJ_secg_ellipticCurve,29L + +#define SN_secp160k1 "secp160k1" +#define NID_secp160k1 708 +#define OBJ_secp160k1 OBJ_secg_ellipticCurve,9L + +#define SN_secp160r1 "secp160r1" +#define NID_secp160r1 709 +#define OBJ_secp160r1 OBJ_secg_ellipticCurve,8L + +#define SN_secp160r2 "secp160r2" +#define NID_secp160r2 710 +#define OBJ_secp160r2 OBJ_secg_ellipticCurve,30L + +#define SN_secp192k1 "secp192k1" +#define NID_secp192k1 711 +#define OBJ_secp192k1 OBJ_secg_ellipticCurve,31L + +#define SN_secp224k1 "secp224k1" +#define NID_secp224k1 712 +#define OBJ_secp224k1 OBJ_secg_ellipticCurve,32L + +#define SN_secp224r1 "secp224r1" +#define NID_secp224r1 713 +#define OBJ_secp224r1 OBJ_secg_ellipticCurve,33L + +#define SN_secp256k1 "secp256k1" +#define NID_secp256k1 714 +#define OBJ_secp256k1 OBJ_secg_ellipticCurve,10L + +#define SN_secp384r1 "secp384r1" +#define NID_secp384r1 715 +#define OBJ_secp384r1 OBJ_secg_ellipticCurve,34L + +#define SN_secp521r1 "secp521r1" +#define NID_secp521r1 716 +#define OBJ_secp521r1 OBJ_secg_ellipticCurve,35L + +#define SN_sect113r1 "sect113r1" +#define NID_sect113r1 717 +#define OBJ_sect113r1 OBJ_secg_ellipticCurve,4L + +#define SN_sect113r2 "sect113r2" +#define NID_sect113r2 718 +#define OBJ_sect113r2 OBJ_secg_ellipticCurve,5L + +#define SN_sect131r1 "sect131r1" +#define NID_sect131r1 719 +#define OBJ_sect131r1 OBJ_secg_ellipticCurve,22L + +#define SN_sect131r2 "sect131r2" +#define NID_sect131r2 720 +#define OBJ_sect131r2 OBJ_secg_ellipticCurve,23L + +#define SN_sect163k1 "sect163k1" +#define NID_sect163k1 721 +#define OBJ_sect163k1 OBJ_secg_ellipticCurve,1L + +#define SN_sect163r1 "sect163r1" +#define NID_sect163r1 722 +#define OBJ_sect163r1 OBJ_secg_ellipticCurve,2L + +#define SN_sect163r2 "sect163r2" +#define NID_sect163r2 723 +#define OBJ_sect163r2 OBJ_secg_ellipticCurve,15L + +#define SN_sect193r1 "sect193r1" +#define NID_sect193r1 724 +#define OBJ_sect193r1 OBJ_secg_ellipticCurve,24L + +#define SN_sect193r2 "sect193r2" +#define NID_sect193r2 725 +#define OBJ_sect193r2 OBJ_secg_ellipticCurve,25L + +#define SN_sect233k1 "sect233k1" +#define NID_sect233k1 726 +#define OBJ_sect233k1 OBJ_secg_ellipticCurve,26L + +#define SN_sect233r1 "sect233r1" +#define NID_sect233r1 727 +#define OBJ_sect233r1 OBJ_secg_ellipticCurve,27L + +#define SN_sect239k1 "sect239k1" +#define NID_sect239k1 728 +#define OBJ_sect239k1 OBJ_secg_ellipticCurve,3L + +#define SN_sect283k1 "sect283k1" +#define NID_sect283k1 729 +#define OBJ_sect283k1 OBJ_secg_ellipticCurve,16L + +#define SN_sect283r1 "sect283r1" +#define NID_sect283r1 730 +#define OBJ_sect283r1 OBJ_secg_ellipticCurve,17L + +#define SN_sect409k1 "sect409k1" +#define NID_sect409k1 731 +#define OBJ_sect409k1 OBJ_secg_ellipticCurve,36L + +#define SN_sect409r1 "sect409r1" +#define NID_sect409r1 732 +#define OBJ_sect409r1 OBJ_secg_ellipticCurve,37L + +#define SN_sect571k1 "sect571k1" +#define NID_sect571k1 733 +#define OBJ_sect571k1 OBJ_secg_ellipticCurve,38L + +#define SN_sect571r1 "sect571r1" +#define NID_sect571r1 734 +#define OBJ_sect571r1 OBJ_secg_ellipticCurve,39L + +#define OBJ_wap_wsg_idm_ecid OBJ_wap_wsg,4L + +#define SN_wap_wsg_idm_ecid_wtls1 "wap-wsg-idm-ecid-wtls1" +#define NID_wap_wsg_idm_ecid_wtls1 735 +#define OBJ_wap_wsg_idm_ecid_wtls1 OBJ_wap_wsg_idm_ecid,1L + +#define SN_wap_wsg_idm_ecid_wtls3 "wap-wsg-idm-ecid-wtls3" +#define NID_wap_wsg_idm_ecid_wtls3 736 +#define OBJ_wap_wsg_idm_ecid_wtls3 OBJ_wap_wsg_idm_ecid,3L + +#define SN_wap_wsg_idm_ecid_wtls4 "wap-wsg-idm-ecid-wtls4" +#define NID_wap_wsg_idm_ecid_wtls4 737 +#define OBJ_wap_wsg_idm_ecid_wtls4 OBJ_wap_wsg_idm_ecid,4L + +#define SN_wap_wsg_idm_ecid_wtls5 "wap-wsg-idm-ecid-wtls5" +#define NID_wap_wsg_idm_ecid_wtls5 738 +#define OBJ_wap_wsg_idm_ecid_wtls5 OBJ_wap_wsg_idm_ecid,5L + +#define SN_wap_wsg_idm_ecid_wtls6 "wap-wsg-idm-ecid-wtls6" +#define NID_wap_wsg_idm_ecid_wtls6 739 +#define OBJ_wap_wsg_idm_ecid_wtls6 OBJ_wap_wsg_idm_ecid,6L + +#define SN_wap_wsg_idm_ecid_wtls7 "wap-wsg-idm-ecid-wtls7" +#define NID_wap_wsg_idm_ecid_wtls7 740 +#define OBJ_wap_wsg_idm_ecid_wtls7 OBJ_wap_wsg_idm_ecid,7L + +#define SN_wap_wsg_idm_ecid_wtls8 "wap-wsg-idm-ecid-wtls8" +#define NID_wap_wsg_idm_ecid_wtls8 741 +#define OBJ_wap_wsg_idm_ecid_wtls8 OBJ_wap_wsg_idm_ecid,8L + +#define SN_wap_wsg_idm_ecid_wtls9 "wap-wsg-idm-ecid-wtls9" +#define NID_wap_wsg_idm_ecid_wtls9 742 +#define OBJ_wap_wsg_idm_ecid_wtls9 OBJ_wap_wsg_idm_ecid,9L + +#define SN_wap_wsg_idm_ecid_wtls10 "wap-wsg-idm-ecid-wtls10" +#define NID_wap_wsg_idm_ecid_wtls10 743 +#define OBJ_wap_wsg_idm_ecid_wtls10 OBJ_wap_wsg_idm_ecid,10L + +#define SN_wap_wsg_idm_ecid_wtls11 "wap-wsg-idm-ecid-wtls11" +#define NID_wap_wsg_idm_ecid_wtls11 744 +#define OBJ_wap_wsg_idm_ecid_wtls11 OBJ_wap_wsg_idm_ecid,11L + +#define SN_wap_wsg_idm_ecid_wtls12 "wap-wsg-idm-ecid-wtls12" +#define NID_wap_wsg_idm_ecid_wtls12 745 +#define OBJ_wap_wsg_idm_ecid_wtls12 OBJ_wap_wsg_idm_ecid,12L + +#define SN_cast5_cbc "CAST5-CBC" +#define LN_cast5_cbc "cast5-cbc" +#define NID_cast5_cbc 108 +#define OBJ_cast5_cbc OBJ_ISO_US,113533L,7L,66L,10L + +#define SN_cast5_ecb "CAST5-ECB" +#define LN_cast5_ecb "cast5-ecb" +#define NID_cast5_ecb 109 + +#define SN_cast5_cfb64 "CAST5-CFB" +#define LN_cast5_cfb64 "cast5-cfb" +#define NID_cast5_cfb64 110 + +#define SN_cast5_ofb64 "CAST5-OFB" +#define LN_cast5_ofb64 "cast5-ofb" +#define NID_cast5_ofb64 111 + +#define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC" +#define NID_pbeWithMD5AndCast5_CBC 112 +#define OBJ_pbeWithMD5AndCast5_CBC OBJ_ISO_US,113533L,7L,66L,12L + +#define SN_id_PasswordBasedMAC "id-PasswordBasedMAC" +#define LN_id_PasswordBasedMAC "password based MAC" +#define NID_id_PasswordBasedMAC 782 +#define OBJ_id_PasswordBasedMAC OBJ_ISO_US,113533L,7L,66L,13L + +#define SN_id_DHBasedMac "id-DHBasedMac" +#define LN_id_DHBasedMac "Diffie-Hellman based MAC" +#define NID_id_DHBasedMac 783 +#define OBJ_id_DHBasedMac OBJ_ISO_US,113533L,7L,66L,30L + +#define SN_rsadsi "rsadsi" +#define LN_rsadsi "RSA Data Security, Inc." +#define NID_rsadsi 1 +#define OBJ_rsadsi OBJ_ISO_US,113549L + +#define SN_pkcs "pkcs" +#define LN_pkcs "RSA Data Security, Inc. PKCS" +#define NID_pkcs 2 +#define OBJ_pkcs OBJ_rsadsi,1L + +#define SN_pkcs1 "pkcs1" +#define NID_pkcs1 186 +#define OBJ_pkcs1 OBJ_pkcs,1L + +#define LN_rsaEncryption "rsaEncryption" +#define NID_rsaEncryption 6 +#define OBJ_rsaEncryption OBJ_pkcs1,1L + +#define SN_md2WithRSAEncryption "RSA-MD2" +#define LN_md2WithRSAEncryption "md2WithRSAEncryption" +#define NID_md2WithRSAEncryption 7 +#define OBJ_md2WithRSAEncryption OBJ_pkcs1,2L + +#define SN_md4WithRSAEncryption "RSA-MD4" +#define LN_md4WithRSAEncryption "md4WithRSAEncryption" +#define NID_md4WithRSAEncryption 396 +#define OBJ_md4WithRSAEncryption OBJ_pkcs1,3L + +#define SN_md5WithRSAEncryption "RSA-MD5" +#define LN_md5WithRSAEncryption "md5WithRSAEncryption" +#define NID_md5WithRSAEncryption 8 +#define OBJ_md5WithRSAEncryption OBJ_pkcs1,4L + +#define SN_sha1WithRSAEncryption "RSA-SHA1" +#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" +#define NID_sha1WithRSAEncryption 65 +#define OBJ_sha1WithRSAEncryption OBJ_pkcs1,5L + +#define SN_sha256WithRSAEncryption "RSA-SHA256" +#define LN_sha256WithRSAEncryption "sha256WithRSAEncryption" +#define NID_sha256WithRSAEncryption 668 +#define OBJ_sha256WithRSAEncryption OBJ_pkcs1,11L + +#define SN_sha384WithRSAEncryption "RSA-SHA384" +#define LN_sha384WithRSAEncryption "sha384WithRSAEncryption" +#define NID_sha384WithRSAEncryption 669 +#define OBJ_sha384WithRSAEncryption OBJ_pkcs1,12L + +#define SN_sha512WithRSAEncryption "RSA-SHA512" +#define LN_sha512WithRSAEncryption "sha512WithRSAEncryption" +#define NID_sha512WithRSAEncryption 670 +#define OBJ_sha512WithRSAEncryption OBJ_pkcs1,13L + +#define SN_sha224WithRSAEncryption "RSA-SHA224" +#define LN_sha224WithRSAEncryption "sha224WithRSAEncryption" +#define NID_sha224WithRSAEncryption 671 +#define OBJ_sha224WithRSAEncryption OBJ_pkcs1,14L + +#define SN_pkcs3 "pkcs3" +#define NID_pkcs3 27 +#define OBJ_pkcs3 OBJ_pkcs,3L + +#define LN_dhKeyAgreement "dhKeyAgreement" +#define NID_dhKeyAgreement 28 +#define OBJ_dhKeyAgreement OBJ_pkcs3,1L + +#define SN_pkcs5 "pkcs5" +#define NID_pkcs5 187 +#define OBJ_pkcs5 OBJ_pkcs,5L + +#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" +#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" +#define NID_pbeWithMD2AndDES_CBC 9 +#define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs5,1L + +#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" +#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" +#define NID_pbeWithMD5AndDES_CBC 10 +#define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs5,3L + +#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" +#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" +#define NID_pbeWithMD2AndRC2_CBC 168 +#define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs5,4L + +#define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64" +#define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC" +#define NID_pbeWithMD5AndRC2_CBC 169 +#define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs5,6L + +#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" +#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" +#define NID_pbeWithSHA1AndDES_CBC 170 +#define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs5,10L + +#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" +#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" +#define NID_pbeWithSHA1AndRC2_CBC 68 +#define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs5,11L + +#define LN_id_pbkdf2 "PBKDF2" +#define NID_id_pbkdf2 69 +#define OBJ_id_pbkdf2 OBJ_pkcs5,12L + +#define LN_pbes2 "PBES2" +#define NID_pbes2 161 +#define OBJ_pbes2 OBJ_pkcs5,13L + +#define LN_pbmac1 "PBMAC1" +#define NID_pbmac1 162 +#define OBJ_pbmac1 OBJ_pkcs5,14L + +#define SN_pkcs7 "pkcs7" +#define NID_pkcs7 20 +#define OBJ_pkcs7 OBJ_pkcs,7L + +#define LN_pkcs7_data "pkcs7-data" +#define NID_pkcs7_data 21 +#define OBJ_pkcs7_data OBJ_pkcs7,1L + +#define LN_pkcs7_signed "pkcs7-signedData" +#define NID_pkcs7_signed 22 +#define OBJ_pkcs7_signed OBJ_pkcs7,2L + +#define LN_pkcs7_enveloped "pkcs7-envelopedData" +#define NID_pkcs7_enveloped 23 +#define OBJ_pkcs7_enveloped OBJ_pkcs7,3L + +#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" +#define NID_pkcs7_signedAndEnveloped 24 +#define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L + +#define LN_pkcs7_digest "pkcs7-digestData" +#define NID_pkcs7_digest 25 +#define OBJ_pkcs7_digest OBJ_pkcs7,5L + +#define LN_pkcs7_encrypted "pkcs7-encryptedData" +#define NID_pkcs7_encrypted 26 +#define OBJ_pkcs7_encrypted OBJ_pkcs7,6L + +#define SN_pkcs9 "pkcs9" +#define NID_pkcs9 47 +#define OBJ_pkcs9 OBJ_pkcs,9L + +#define LN_pkcs9_emailAddress "emailAddress" +#define NID_pkcs9_emailAddress 48 +#define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L + +#define LN_pkcs9_unstructuredName "unstructuredName" +#define NID_pkcs9_unstructuredName 49 +#define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L + +#define LN_pkcs9_contentType "contentType" +#define NID_pkcs9_contentType 50 +#define OBJ_pkcs9_contentType OBJ_pkcs9,3L + +#define LN_pkcs9_messageDigest "messageDigest" +#define NID_pkcs9_messageDigest 51 +#define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L + +#define LN_pkcs9_signingTime "signingTime" +#define NID_pkcs9_signingTime 52 +#define OBJ_pkcs9_signingTime OBJ_pkcs9,5L + +#define LN_pkcs9_countersignature "countersignature" +#define NID_pkcs9_countersignature 53 +#define OBJ_pkcs9_countersignature OBJ_pkcs9,6L + +#define LN_pkcs9_challengePassword "challengePassword" +#define NID_pkcs9_challengePassword 54 +#define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L + +#define LN_pkcs9_unstructuredAddress "unstructuredAddress" +#define NID_pkcs9_unstructuredAddress 55 +#define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L + +#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" +#define NID_pkcs9_extCertAttributes 56 +#define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L + +#define SN_ext_req "extReq" +#define LN_ext_req "Extension Request" +#define NID_ext_req 172 +#define OBJ_ext_req OBJ_pkcs9,14L + +#define SN_SMIMECapabilities "SMIME-CAPS" +#define LN_SMIMECapabilities "S/MIME Capabilities" +#define NID_SMIMECapabilities 167 +#define OBJ_SMIMECapabilities OBJ_pkcs9,15L + +#define SN_SMIME "SMIME" +#define LN_SMIME "S/MIME" +#define NID_SMIME 188 +#define OBJ_SMIME OBJ_pkcs9,16L + +#define SN_id_smime_mod "id-smime-mod" +#define NID_id_smime_mod 189 +#define OBJ_id_smime_mod OBJ_SMIME,0L + +#define SN_id_smime_ct "id-smime-ct" +#define NID_id_smime_ct 190 +#define OBJ_id_smime_ct OBJ_SMIME,1L + +#define SN_id_smime_aa "id-smime-aa" +#define NID_id_smime_aa 191 +#define OBJ_id_smime_aa OBJ_SMIME,2L + +#define SN_id_smime_alg "id-smime-alg" +#define NID_id_smime_alg 192 +#define OBJ_id_smime_alg OBJ_SMIME,3L + +#define SN_id_smime_cd "id-smime-cd" +#define NID_id_smime_cd 193 +#define OBJ_id_smime_cd OBJ_SMIME,4L + +#define SN_id_smime_spq "id-smime-spq" +#define NID_id_smime_spq 194 +#define OBJ_id_smime_spq OBJ_SMIME,5L + +#define SN_id_smime_cti "id-smime-cti" +#define NID_id_smime_cti 195 +#define OBJ_id_smime_cti OBJ_SMIME,6L + +#define SN_id_smime_mod_cms "id-smime-mod-cms" +#define NID_id_smime_mod_cms 196 +#define OBJ_id_smime_mod_cms OBJ_id_smime_mod,1L + +#define SN_id_smime_mod_ess "id-smime-mod-ess" +#define NID_id_smime_mod_ess 197 +#define OBJ_id_smime_mod_ess OBJ_id_smime_mod,2L + +#define SN_id_smime_mod_oid "id-smime-mod-oid" +#define NID_id_smime_mod_oid 198 +#define OBJ_id_smime_mod_oid OBJ_id_smime_mod,3L + +#define SN_id_smime_mod_msg_v3 "id-smime-mod-msg-v3" +#define NID_id_smime_mod_msg_v3 199 +#define OBJ_id_smime_mod_msg_v3 OBJ_id_smime_mod,4L + +#define SN_id_smime_mod_ets_eSignature_88 "id-smime-mod-ets-eSignature-88" +#define NID_id_smime_mod_ets_eSignature_88 200 +#define OBJ_id_smime_mod_ets_eSignature_88 OBJ_id_smime_mod,5L + +#define SN_id_smime_mod_ets_eSignature_97 "id-smime-mod-ets-eSignature-97" +#define NID_id_smime_mod_ets_eSignature_97 201 +#define OBJ_id_smime_mod_ets_eSignature_97 OBJ_id_smime_mod,6L + +#define SN_id_smime_mod_ets_eSigPolicy_88 "id-smime-mod-ets-eSigPolicy-88" +#define NID_id_smime_mod_ets_eSigPolicy_88 202 +#define OBJ_id_smime_mod_ets_eSigPolicy_88 OBJ_id_smime_mod,7L + +#define SN_id_smime_mod_ets_eSigPolicy_97 "id-smime-mod-ets-eSigPolicy-97" +#define NID_id_smime_mod_ets_eSigPolicy_97 203 +#define OBJ_id_smime_mod_ets_eSigPolicy_97 OBJ_id_smime_mod,8L + +#define SN_id_smime_ct_receipt "id-smime-ct-receipt" +#define NID_id_smime_ct_receipt 204 +#define OBJ_id_smime_ct_receipt OBJ_id_smime_ct,1L + +#define SN_id_smime_ct_authData "id-smime-ct-authData" +#define NID_id_smime_ct_authData 205 +#define OBJ_id_smime_ct_authData OBJ_id_smime_ct,2L + +#define SN_id_smime_ct_publishCert "id-smime-ct-publishCert" +#define NID_id_smime_ct_publishCert 206 +#define OBJ_id_smime_ct_publishCert OBJ_id_smime_ct,3L + +#define SN_id_smime_ct_TSTInfo "id-smime-ct-TSTInfo" +#define NID_id_smime_ct_TSTInfo 207 +#define OBJ_id_smime_ct_TSTInfo OBJ_id_smime_ct,4L + +#define SN_id_smime_ct_TDTInfo "id-smime-ct-TDTInfo" +#define NID_id_smime_ct_TDTInfo 208 +#define OBJ_id_smime_ct_TDTInfo OBJ_id_smime_ct,5L + +#define SN_id_smime_ct_contentInfo "id-smime-ct-contentInfo" +#define NID_id_smime_ct_contentInfo 209 +#define OBJ_id_smime_ct_contentInfo OBJ_id_smime_ct,6L + +#define SN_id_smime_ct_DVCSRequestData "id-smime-ct-DVCSRequestData" +#define NID_id_smime_ct_DVCSRequestData 210 +#define OBJ_id_smime_ct_DVCSRequestData OBJ_id_smime_ct,7L + +#define SN_id_smime_ct_DVCSResponseData "id-smime-ct-DVCSResponseData" +#define NID_id_smime_ct_DVCSResponseData 211 +#define OBJ_id_smime_ct_DVCSResponseData OBJ_id_smime_ct,8L + +#define SN_id_smime_ct_compressedData "id-smime-ct-compressedData" +#define NID_id_smime_ct_compressedData 786 +#define OBJ_id_smime_ct_compressedData OBJ_id_smime_ct,9L + +#define SN_id_ct_asciiTextWithCRLF "id-ct-asciiTextWithCRLF" +#define NID_id_ct_asciiTextWithCRLF 787 +#define OBJ_id_ct_asciiTextWithCRLF OBJ_id_smime_ct,27L + +#define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest" +#define NID_id_smime_aa_receiptRequest 212 +#define OBJ_id_smime_aa_receiptRequest OBJ_id_smime_aa,1L + +#define SN_id_smime_aa_securityLabel "id-smime-aa-securityLabel" +#define NID_id_smime_aa_securityLabel 213 +#define OBJ_id_smime_aa_securityLabel OBJ_id_smime_aa,2L + +#define SN_id_smime_aa_mlExpandHistory "id-smime-aa-mlExpandHistory" +#define NID_id_smime_aa_mlExpandHistory 214 +#define OBJ_id_smime_aa_mlExpandHistory OBJ_id_smime_aa,3L + +#define SN_id_smime_aa_contentHint "id-smime-aa-contentHint" +#define NID_id_smime_aa_contentHint 215 +#define OBJ_id_smime_aa_contentHint OBJ_id_smime_aa,4L + +#define SN_id_smime_aa_msgSigDigest "id-smime-aa-msgSigDigest" +#define NID_id_smime_aa_msgSigDigest 216 +#define OBJ_id_smime_aa_msgSigDigest OBJ_id_smime_aa,5L + +#define SN_id_smime_aa_encapContentType "id-smime-aa-encapContentType" +#define NID_id_smime_aa_encapContentType 217 +#define OBJ_id_smime_aa_encapContentType OBJ_id_smime_aa,6L + +#define SN_id_smime_aa_contentIdentifier "id-smime-aa-contentIdentifier" +#define NID_id_smime_aa_contentIdentifier 218 +#define OBJ_id_smime_aa_contentIdentifier OBJ_id_smime_aa,7L + +#define SN_id_smime_aa_macValue "id-smime-aa-macValue" +#define NID_id_smime_aa_macValue 219 +#define OBJ_id_smime_aa_macValue OBJ_id_smime_aa,8L + +#define SN_id_smime_aa_equivalentLabels "id-smime-aa-equivalentLabels" +#define NID_id_smime_aa_equivalentLabels 220 +#define OBJ_id_smime_aa_equivalentLabels OBJ_id_smime_aa,9L + +#define SN_id_smime_aa_contentReference "id-smime-aa-contentReference" +#define NID_id_smime_aa_contentReference 221 +#define OBJ_id_smime_aa_contentReference OBJ_id_smime_aa,10L + +#define SN_id_smime_aa_encrypKeyPref "id-smime-aa-encrypKeyPref" +#define NID_id_smime_aa_encrypKeyPref 222 +#define OBJ_id_smime_aa_encrypKeyPref OBJ_id_smime_aa,11L + +#define SN_id_smime_aa_signingCertificate "id-smime-aa-signingCertificate" +#define NID_id_smime_aa_signingCertificate 223 +#define OBJ_id_smime_aa_signingCertificate OBJ_id_smime_aa,12L + +#define SN_id_smime_aa_smimeEncryptCerts "id-smime-aa-smimeEncryptCerts" +#define NID_id_smime_aa_smimeEncryptCerts 224 +#define OBJ_id_smime_aa_smimeEncryptCerts OBJ_id_smime_aa,13L + +#define SN_id_smime_aa_timeStampToken "id-smime-aa-timeStampToken" +#define NID_id_smime_aa_timeStampToken 225 +#define OBJ_id_smime_aa_timeStampToken OBJ_id_smime_aa,14L + +#define SN_id_smime_aa_ets_sigPolicyId "id-smime-aa-ets-sigPolicyId" +#define NID_id_smime_aa_ets_sigPolicyId 226 +#define OBJ_id_smime_aa_ets_sigPolicyId OBJ_id_smime_aa,15L + +#define SN_id_smime_aa_ets_commitmentType "id-smime-aa-ets-commitmentType" +#define NID_id_smime_aa_ets_commitmentType 227 +#define OBJ_id_smime_aa_ets_commitmentType OBJ_id_smime_aa,16L + +#define SN_id_smime_aa_ets_signerLocation "id-smime-aa-ets-signerLocation" +#define NID_id_smime_aa_ets_signerLocation 228 +#define OBJ_id_smime_aa_ets_signerLocation OBJ_id_smime_aa,17L + +#define SN_id_smime_aa_ets_signerAttr "id-smime-aa-ets-signerAttr" +#define NID_id_smime_aa_ets_signerAttr 229 +#define OBJ_id_smime_aa_ets_signerAttr OBJ_id_smime_aa,18L + +#define SN_id_smime_aa_ets_otherSigCert "id-smime-aa-ets-otherSigCert" +#define NID_id_smime_aa_ets_otherSigCert 230 +#define OBJ_id_smime_aa_ets_otherSigCert OBJ_id_smime_aa,19L + +#define SN_id_smime_aa_ets_contentTimestamp "id-smime-aa-ets-contentTimestamp" +#define NID_id_smime_aa_ets_contentTimestamp 231 +#define OBJ_id_smime_aa_ets_contentTimestamp OBJ_id_smime_aa,20L + +#define SN_id_smime_aa_ets_CertificateRefs "id-smime-aa-ets-CertificateRefs" +#define NID_id_smime_aa_ets_CertificateRefs 232 +#define OBJ_id_smime_aa_ets_CertificateRefs OBJ_id_smime_aa,21L + +#define SN_id_smime_aa_ets_RevocationRefs "id-smime-aa-ets-RevocationRefs" +#define NID_id_smime_aa_ets_RevocationRefs 233 +#define OBJ_id_smime_aa_ets_RevocationRefs OBJ_id_smime_aa,22L + +#define SN_id_smime_aa_ets_certValues "id-smime-aa-ets-certValues" +#define NID_id_smime_aa_ets_certValues 234 +#define OBJ_id_smime_aa_ets_certValues OBJ_id_smime_aa,23L + +#define SN_id_smime_aa_ets_revocationValues "id-smime-aa-ets-revocationValues" +#define NID_id_smime_aa_ets_revocationValues 235 +#define OBJ_id_smime_aa_ets_revocationValues OBJ_id_smime_aa,24L + +#define SN_id_smime_aa_ets_escTimeStamp "id-smime-aa-ets-escTimeStamp" +#define NID_id_smime_aa_ets_escTimeStamp 236 +#define OBJ_id_smime_aa_ets_escTimeStamp OBJ_id_smime_aa,25L + +#define SN_id_smime_aa_ets_certCRLTimestamp "id-smime-aa-ets-certCRLTimestamp" +#define NID_id_smime_aa_ets_certCRLTimestamp 237 +#define OBJ_id_smime_aa_ets_certCRLTimestamp OBJ_id_smime_aa,26L + +#define SN_id_smime_aa_ets_archiveTimeStamp "id-smime-aa-ets-archiveTimeStamp" +#define NID_id_smime_aa_ets_archiveTimeStamp 238 +#define OBJ_id_smime_aa_ets_archiveTimeStamp OBJ_id_smime_aa,27L + +#define SN_id_smime_aa_signatureType "id-smime-aa-signatureType" +#define NID_id_smime_aa_signatureType 239 +#define OBJ_id_smime_aa_signatureType OBJ_id_smime_aa,28L + +#define SN_id_smime_aa_dvcs_dvc "id-smime-aa-dvcs-dvc" +#define NID_id_smime_aa_dvcs_dvc 240 +#define OBJ_id_smime_aa_dvcs_dvc OBJ_id_smime_aa,29L + +#define SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES" +#define NID_id_smime_alg_ESDHwith3DES 241 +#define OBJ_id_smime_alg_ESDHwith3DES OBJ_id_smime_alg,1L + +#define SN_id_smime_alg_ESDHwithRC2 "id-smime-alg-ESDHwithRC2" +#define NID_id_smime_alg_ESDHwithRC2 242 +#define OBJ_id_smime_alg_ESDHwithRC2 OBJ_id_smime_alg,2L + +#define SN_id_smime_alg_3DESwrap "id-smime-alg-3DESwrap" +#define NID_id_smime_alg_3DESwrap 243 +#define OBJ_id_smime_alg_3DESwrap OBJ_id_smime_alg,3L + +#define SN_id_smime_alg_RC2wrap "id-smime-alg-RC2wrap" +#define NID_id_smime_alg_RC2wrap 244 +#define OBJ_id_smime_alg_RC2wrap OBJ_id_smime_alg,4L + +#define SN_id_smime_alg_ESDH "id-smime-alg-ESDH" +#define NID_id_smime_alg_ESDH 245 +#define OBJ_id_smime_alg_ESDH OBJ_id_smime_alg,5L + +#define SN_id_smime_alg_CMS3DESwrap "id-smime-alg-CMS3DESwrap" +#define NID_id_smime_alg_CMS3DESwrap 246 +#define OBJ_id_smime_alg_CMS3DESwrap OBJ_id_smime_alg,6L + +#define SN_id_smime_alg_CMSRC2wrap "id-smime-alg-CMSRC2wrap" +#define NID_id_smime_alg_CMSRC2wrap 247 +#define OBJ_id_smime_alg_CMSRC2wrap OBJ_id_smime_alg,7L + +#define SN_id_smime_cd_ldap "id-smime-cd-ldap" +#define NID_id_smime_cd_ldap 248 +#define OBJ_id_smime_cd_ldap OBJ_id_smime_cd,1L + +#define SN_id_smime_spq_ets_sqt_uri "id-smime-spq-ets-sqt-uri" +#define NID_id_smime_spq_ets_sqt_uri 249 +#define OBJ_id_smime_spq_ets_sqt_uri OBJ_id_smime_spq,1L + +#define SN_id_smime_spq_ets_sqt_unotice "id-smime-spq-ets-sqt-unotice" +#define NID_id_smime_spq_ets_sqt_unotice 250 +#define OBJ_id_smime_spq_ets_sqt_unotice OBJ_id_smime_spq,2L + +#define SN_id_smime_cti_ets_proofOfOrigin "id-smime-cti-ets-proofOfOrigin" +#define NID_id_smime_cti_ets_proofOfOrigin 251 +#define OBJ_id_smime_cti_ets_proofOfOrigin OBJ_id_smime_cti,1L + +#define SN_id_smime_cti_ets_proofOfReceipt "id-smime-cti-ets-proofOfReceipt" +#define NID_id_smime_cti_ets_proofOfReceipt 252 +#define OBJ_id_smime_cti_ets_proofOfReceipt OBJ_id_smime_cti,2L + +#define SN_id_smime_cti_ets_proofOfDelivery "id-smime-cti-ets-proofOfDelivery" +#define NID_id_smime_cti_ets_proofOfDelivery 253 +#define OBJ_id_smime_cti_ets_proofOfDelivery OBJ_id_smime_cti,3L + +#define SN_id_smime_cti_ets_proofOfSender "id-smime-cti-ets-proofOfSender" +#define NID_id_smime_cti_ets_proofOfSender 254 +#define OBJ_id_smime_cti_ets_proofOfSender OBJ_id_smime_cti,4L + +#define SN_id_smime_cti_ets_proofOfApproval "id-smime-cti-ets-proofOfApproval" +#define NID_id_smime_cti_ets_proofOfApproval 255 +#define OBJ_id_smime_cti_ets_proofOfApproval OBJ_id_smime_cti,5L + +#define SN_id_smime_cti_ets_proofOfCreation "id-smime-cti-ets-proofOfCreation" +#define NID_id_smime_cti_ets_proofOfCreation 256 +#define OBJ_id_smime_cti_ets_proofOfCreation OBJ_id_smime_cti,6L + +#define LN_friendlyName "friendlyName" +#define NID_friendlyName 156 +#define OBJ_friendlyName OBJ_pkcs9,20L + +#define LN_localKeyID "localKeyID" +#define NID_localKeyID 157 +#define OBJ_localKeyID OBJ_pkcs9,21L + +#define SN_ms_csp_name "CSPName" +#define LN_ms_csp_name "Microsoft CSP Name" +#define NID_ms_csp_name 417 +#define OBJ_ms_csp_name 1L,3L,6L,1L,4L,1L,311L,17L,1L + +#define SN_LocalKeySet "LocalKeySet" +#define LN_LocalKeySet "Microsoft Local Key set" +#define NID_LocalKeySet 856 +#define OBJ_LocalKeySet 1L,3L,6L,1L,4L,1L,311L,17L,2L + +#define OBJ_certTypes OBJ_pkcs9,22L + +#define LN_x509Certificate "x509Certificate" +#define NID_x509Certificate 158 +#define OBJ_x509Certificate OBJ_certTypes,1L + +#define LN_sdsiCertificate "sdsiCertificate" +#define NID_sdsiCertificate 159 +#define OBJ_sdsiCertificate OBJ_certTypes,2L + +#define OBJ_crlTypes OBJ_pkcs9,23L + +#define LN_x509Crl "x509Crl" +#define NID_x509Crl 160 +#define OBJ_x509Crl OBJ_crlTypes,1L + +#define OBJ_pkcs12 OBJ_pkcs,12L + +#define OBJ_pkcs12_pbeids OBJ_pkcs12,1L + +#define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" +#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" +#define NID_pbe_WithSHA1And128BitRC4 144 +#define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids,1L + +#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" +#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" +#define NID_pbe_WithSHA1And40BitRC4 145 +#define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids,2L + +#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES" +#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146 +#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids,3L + +#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES" +#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147 +#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids,4L + +#define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128" +#define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC" +#define NID_pbe_WithSHA1And128BitRC2_CBC 148 +#define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids,5L + +#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40" +#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC" +#define NID_pbe_WithSHA1And40BitRC2_CBC 149 +#define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids,6L + +#define OBJ_pkcs12_Version1 OBJ_pkcs12,10L + +#define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1,1L + +#define LN_keyBag "keyBag" +#define NID_keyBag 150 +#define OBJ_keyBag OBJ_pkcs12_BagIds,1L + +#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" +#define NID_pkcs8ShroudedKeyBag 151 +#define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds,2L + +#define LN_certBag "certBag" +#define NID_certBag 152 +#define OBJ_certBag OBJ_pkcs12_BagIds,3L + +#define LN_crlBag "crlBag" +#define NID_crlBag 153 +#define OBJ_crlBag OBJ_pkcs12_BagIds,4L + +#define LN_secretBag "secretBag" +#define NID_secretBag 154 +#define OBJ_secretBag OBJ_pkcs12_BagIds,5L + +#define LN_safeContentsBag "safeContentsBag" +#define NID_safeContentsBag 155 +#define OBJ_safeContentsBag OBJ_pkcs12_BagIds,6L + +#define SN_md2 "MD2" +#define LN_md2 "md2" +#define NID_md2 3 +#define OBJ_md2 OBJ_rsadsi,2L,2L + +#define SN_md4 "MD4" +#define LN_md4 "md4" +#define NID_md4 257 +#define OBJ_md4 OBJ_rsadsi,2L,4L + +#define SN_md5 "MD5" +#define LN_md5 "md5" +#define NID_md5 4 +#define OBJ_md5 OBJ_rsadsi,2L,5L + +#define SN_md5_sha1 "MD5-SHA1" +#define LN_md5_sha1 "md5-sha1" +#define NID_md5_sha1 114 + +#define LN_hmacWithMD5 "hmacWithMD5" +#define NID_hmacWithMD5 797 +#define OBJ_hmacWithMD5 OBJ_rsadsi,2L,6L + +#define LN_hmacWithSHA1 "hmacWithSHA1" +#define NID_hmacWithSHA1 163 +#define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L + +#define LN_hmacWithSHA224 "hmacWithSHA224" +#define NID_hmacWithSHA224 798 +#define OBJ_hmacWithSHA224 OBJ_rsadsi,2L,8L + +#define LN_hmacWithSHA256 "hmacWithSHA256" +#define NID_hmacWithSHA256 799 +#define OBJ_hmacWithSHA256 OBJ_rsadsi,2L,9L + +#define LN_hmacWithSHA384 "hmacWithSHA384" +#define NID_hmacWithSHA384 800 +#define OBJ_hmacWithSHA384 OBJ_rsadsi,2L,10L + +#define LN_hmacWithSHA512 "hmacWithSHA512" +#define NID_hmacWithSHA512 801 +#define OBJ_hmacWithSHA512 OBJ_rsadsi,2L,11L + +#define SN_rc2_cbc "RC2-CBC" +#define LN_rc2_cbc "rc2-cbc" +#define NID_rc2_cbc 37 +#define OBJ_rc2_cbc OBJ_rsadsi,3L,2L + +#define SN_rc2_ecb "RC2-ECB" +#define LN_rc2_ecb "rc2-ecb" +#define NID_rc2_ecb 38 + +#define SN_rc2_cfb64 "RC2-CFB" +#define LN_rc2_cfb64 "rc2-cfb" +#define NID_rc2_cfb64 39 + +#define SN_rc2_ofb64 "RC2-OFB" +#define LN_rc2_ofb64 "rc2-ofb" +#define NID_rc2_ofb64 40 + +#define SN_rc2_40_cbc "RC2-40-CBC" +#define LN_rc2_40_cbc "rc2-40-cbc" +#define NID_rc2_40_cbc 98 + +#define SN_rc2_64_cbc "RC2-64-CBC" +#define LN_rc2_64_cbc "rc2-64-cbc" +#define NID_rc2_64_cbc 166 + +#define SN_rc4 "RC4" +#define LN_rc4 "rc4" +#define NID_rc4 5 +#define OBJ_rc4 OBJ_rsadsi,3L,4L + +#define SN_rc4_40 "RC4-40" +#define LN_rc4_40 "rc4-40" +#define NID_rc4_40 97 + +#define SN_des_ede3_cbc "DES-EDE3-CBC" +#define LN_des_ede3_cbc "des-ede3-cbc" +#define NID_des_ede3_cbc 44 +#define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L + +#define SN_rc5_cbc "RC5-CBC" +#define LN_rc5_cbc "rc5-cbc" +#define NID_rc5_cbc 120 +#define OBJ_rc5_cbc OBJ_rsadsi,3L,8L + +#define SN_rc5_ecb "RC5-ECB" +#define LN_rc5_ecb "rc5-ecb" +#define NID_rc5_ecb 121 + +#define SN_rc5_cfb64 "RC5-CFB" +#define LN_rc5_cfb64 "rc5-cfb" +#define NID_rc5_cfb64 122 + +#define SN_rc5_ofb64 "RC5-OFB" +#define LN_rc5_ofb64 "rc5-ofb" +#define NID_rc5_ofb64 123 + +#define SN_ms_ext_req "msExtReq" +#define LN_ms_ext_req "Microsoft Extension Request" +#define NID_ms_ext_req 171 +#define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L + +#define SN_ms_code_ind "msCodeInd" +#define LN_ms_code_ind "Microsoft Individual Code Signing" +#define NID_ms_code_ind 134 +#define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L + +#define SN_ms_code_com "msCodeCom" +#define LN_ms_code_com "Microsoft Commercial Code Signing" +#define NID_ms_code_com 135 +#define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L + +#define SN_ms_ctl_sign "msCTLSign" +#define LN_ms_ctl_sign "Microsoft Trust List Signing" +#define NID_ms_ctl_sign 136 +#define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L + +#define SN_ms_sgc "msSGC" +#define LN_ms_sgc "Microsoft Server Gated Crypto" +#define NID_ms_sgc 137 +#define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L + +#define SN_ms_efs "msEFS" +#define LN_ms_efs "Microsoft Encrypted File System" +#define NID_ms_efs 138 +#define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L + +#define SN_ms_smartcard_login "msSmartcardLogin" +#define LN_ms_smartcard_login "Microsoft Smartcardlogin" +#define NID_ms_smartcard_login 648 +#define OBJ_ms_smartcard_login 1L,3L,6L,1L,4L,1L,311L,20L,2L,2L + +#define SN_ms_upn "msUPN" +#define LN_ms_upn "Microsoft Universal Principal Name" +#define NID_ms_upn 649 +#define OBJ_ms_upn 1L,3L,6L,1L,4L,1L,311L,20L,2L,3L + +#define SN_idea_cbc "IDEA-CBC" +#define LN_idea_cbc "idea-cbc" +#define NID_idea_cbc 34 +#define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L + +#define SN_idea_ecb "IDEA-ECB" +#define LN_idea_ecb "idea-ecb" +#define NID_idea_ecb 36 + +#define SN_idea_cfb64 "IDEA-CFB" +#define LN_idea_cfb64 "idea-cfb" +#define NID_idea_cfb64 35 + +#define SN_idea_ofb64 "IDEA-OFB" +#define LN_idea_ofb64 "idea-ofb" +#define NID_idea_ofb64 46 + +#define SN_bf_cbc "BF-CBC" +#define LN_bf_cbc "bf-cbc" +#define NID_bf_cbc 91 +#define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L + +#define SN_bf_ecb "BF-ECB" +#define LN_bf_ecb "bf-ecb" +#define NID_bf_ecb 92 + +#define SN_bf_cfb64 "BF-CFB" +#define LN_bf_cfb64 "bf-cfb" +#define NID_bf_cfb64 93 + +#define SN_bf_ofb64 "BF-OFB" +#define LN_bf_ofb64 "bf-ofb" +#define NID_bf_ofb64 94 + +#define SN_id_pkix "PKIX" +#define NID_id_pkix 127 +#define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L + +#define SN_id_pkix_mod "id-pkix-mod" +#define NID_id_pkix_mod 258 +#define OBJ_id_pkix_mod OBJ_id_pkix,0L + +#define SN_id_pe "id-pe" +#define NID_id_pe 175 +#define OBJ_id_pe OBJ_id_pkix,1L + +#define SN_id_qt "id-qt" +#define NID_id_qt 259 +#define OBJ_id_qt OBJ_id_pkix,2L + +#define SN_id_kp "id-kp" +#define NID_id_kp 128 +#define OBJ_id_kp OBJ_id_pkix,3L + +#define SN_id_it "id-it" +#define NID_id_it 260 +#define OBJ_id_it OBJ_id_pkix,4L + +#define SN_id_pkip "id-pkip" +#define NID_id_pkip 261 +#define OBJ_id_pkip OBJ_id_pkix,5L + +#define SN_id_alg "id-alg" +#define NID_id_alg 262 +#define OBJ_id_alg OBJ_id_pkix,6L + +#define SN_id_cmc "id-cmc" +#define NID_id_cmc 263 +#define OBJ_id_cmc OBJ_id_pkix,7L + +#define SN_id_on "id-on" +#define NID_id_on 264 +#define OBJ_id_on OBJ_id_pkix,8L + +#define SN_id_pda "id-pda" +#define NID_id_pda 265 +#define OBJ_id_pda OBJ_id_pkix,9L + +#define SN_id_aca "id-aca" +#define NID_id_aca 266 +#define OBJ_id_aca OBJ_id_pkix,10L + +#define SN_id_qcs "id-qcs" +#define NID_id_qcs 267 +#define OBJ_id_qcs OBJ_id_pkix,11L + +#define SN_id_cct "id-cct" +#define NID_id_cct 268 +#define OBJ_id_cct OBJ_id_pkix,12L + +#define SN_id_ppl "id-ppl" +#define NID_id_ppl 662 +#define OBJ_id_ppl OBJ_id_pkix,21L + +#define SN_id_ad "id-ad" +#define NID_id_ad 176 +#define OBJ_id_ad OBJ_id_pkix,48L + +#define SN_id_pkix1_explicit_88 "id-pkix1-explicit-88" +#define NID_id_pkix1_explicit_88 269 +#define OBJ_id_pkix1_explicit_88 OBJ_id_pkix_mod,1L + +#define SN_id_pkix1_implicit_88 "id-pkix1-implicit-88" +#define NID_id_pkix1_implicit_88 270 +#define OBJ_id_pkix1_implicit_88 OBJ_id_pkix_mod,2L + +#define SN_id_pkix1_explicit_93 "id-pkix1-explicit-93" +#define NID_id_pkix1_explicit_93 271 +#define OBJ_id_pkix1_explicit_93 OBJ_id_pkix_mod,3L + +#define SN_id_pkix1_implicit_93 "id-pkix1-implicit-93" +#define NID_id_pkix1_implicit_93 272 +#define OBJ_id_pkix1_implicit_93 OBJ_id_pkix_mod,4L + +#define SN_id_mod_crmf "id-mod-crmf" +#define NID_id_mod_crmf 273 +#define OBJ_id_mod_crmf OBJ_id_pkix_mod,5L + +#define SN_id_mod_cmc "id-mod-cmc" +#define NID_id_mod_cmc 274 +#define OBJ_id_mod_cmc OBJ_id_pkix_mod,6L + +#define SN_id_mod_kea_profile_88 "id-mod-kea-profile-88" +#define NID_id_mod_kea_profile_88 275 +#define OBJ_id_mod_kea_profile_88 OBJ_id_pkix_mod,7L + +#define SN_id_mod_kea_profile_93 "id-mod-kea-profile-93" +#define NID_id_mod_kea_profile_93 276 +#define OBJ_id_mod_kea_profile_93 OBJ_id_pkix_mod,8L + +#define SN_id_mod_cmp "id-mod-cmp" +#define NID_id_mod_cmp 277 +#define OBJ_id_mod_cmp OBJ_id_pkix_mod,9L + +#define SN_id_mod_qualified_cert_88 "id-mod-qualified-cert-88" +#define NID_id_mod_qualified_cert_88 278 +#define OBJ_id_mod_qualified_cert_88 OBJ_id_pkix_mod,10L + +#define SN_id_mod_qualified_cert_93 "id-mod-qualified-cert-93" +#define NID_id_mod_qualified_cert_93 279 +#define OBJ_id_mod_qualified_cert_93 OBJ_id_pkix_mod,11L + +#define SN_id_mod_attribute_cert "id-mod-attribute-cert" +#define NID_id_mod_attribute_cert 280 +#define OBJ_id_mod_attribute_cert OBJ_id_pkix_mod,12L + +#define SN_id_mod_timestamp_protocol "id-mod-timestamp-protocol" +#define NID_id_mod_timestamp_protocol 281 +#define OBJ_id_mod_timestamp_protocol OBJ_id_pkix_mod,13L + +#define SN_id_mod_ocsp "id-mod-ocsp" +#define NID_id_mod_ocsp 282 +#define OBJ_id_mod_ocsp OBJ_id_pkix_mod,14L + +#define SN_id_mod_dvcs "id-mod-dvcs" +#define NID_id_mod_dvcs 283 +#define OBJ_id_mod_dvcs OBJ_id_pkix_mod,15L + +#define SN_id_mod_cmp2000 "id-mod-cmp2000" +#define NID_id_mod_cmp2000 284 +#define OBJ_id_mod_cmp2000 OBJ_id_pkix_mod,16L + +#define SN_info_access "authorityInfoAccess" +#define LN_info_access "Authority Information Access" +#define NID_info_access 177 +#define OBJ_info_access OBJ_id_pe,1L + +#define SN_biometricInfo "biometricInfo" +#define LN_biometricInfo "Biometric Info" +#define NID_biometricInfo 285 +#define OBJ_biometricInfo OBJ_id_pe,2L + +#define SN_qcStatements "qcStatements" +#define NID_qcStatements 286 +#define OBJ_qcStatements OBJ_id_pe,3L + +#define SN_ac_auditEntity "ac-auditEntity" +#define NID_ac_auditEntity 287 +#define OBJ_ac_auditEntity OBJ_id_pe,4L + +#define SN_ac_targeting "ac-targeting" +#define NID_ac_targeting 288 +#define OBJ_ac_targeting OBJ_id_pe,5L + +#define SN_aaControls "aaControls" +#define NID_aaControls 289 +#define OBJ_aaControls OBJ_id_pe,6L + +#define SN_sbgp_ipAddrBlock "sbgp-ipAddrBlock" +#define NID_sbgp_ipAddrBlock 290 +#define OBJ_sbgp_ipAddrBlock OBJ_id_pe,7L + +#define SN_sbgp_autonomousSysNum "sbgp-autonomousSysNum" +#define NID_sbgp_autonomousSysNum 291 +#define OBJ_sbgp_autonomousSysNum OBJ_id_pe,8L + +#define SN_sbgp_routerIdentifier "sbgp-routerIdentifier" +#define NID_sbgp_routerIdentifier 292 +#define OBJ_sbgp_routerIdentifier OBJ_id_pe,9L + +#define SN_ac_proxying "ac-proxying" +#define NID_ac_proxying 397 +#define OBJ_ac_proxying OBJ_id_pe,10L + +#define SN_sinfo_access "subjectInfoAccess" +#define LN_sinfo_access "Subject Information Access" +#define NID_sinfo_access 398 +#define OBJ_sinfo_access OBJ_id_pe,11L + +#define SN_proxyCertInfo "proxyCertInfo" +#define LN_proxyCertInfo "Proxy Certificate Information" +#define NID_proxyCertInfo 663 +#define OBJ_proxyCertInfo OBJ_id_pe,14L + +#define SN_id_qt_cps "id-qt-cps" +#define LN_id_qt_cps "Policy Qualifier CPS" +#define NID_id_qt_cps 164 +#define OBJ_id_qt_cps OBJ_id_qt,1L + +#define SN_id_qt_unotice "id-qt-unotice" +#define LN_id_qt_unotice "Policy Qualifier User Notice" +#define NID_id_qt_unotice 165 +#define OBJ_id_qt_unotice OBJ_id_qt,2L + +#define SN_textNotice "textNotice" +#define NID_textNotice 293 +#define OBJ_textNotice OBJ_id_qt,3L + +#define SN_server_auth "serverAuth" +#define LN_server_auth "TLS Web Server Authentication" +#define NID_server_auth 129 +#define OBJ_server_auth OBJ_id_kp,1L + +#define SN_client_auth "clientAuth" +#define LN_client_auth "TLS Web Client Authentication" +#define NID_client_auth 130 +#define OBJ_client_auth OBJ_id_kp,2L + +#define SN_code_sign "codeSigning" +#define LN_code_sign "Code Signing" +#define NID_code_sign 131 +#define OBJ_code_sign OBJ_id_kp,3L + +#define SN_email_protect "emailProtection" +#define LN_email_protect "E-mail Protection" +#define NID_email_protect 132 +#define OBJ_email_protect OBJ_id_kp,4L + +#define SN_ipsecEndSystem "ipsecEndSystem" +#define LN_ipsecEndSystem "IPSec End System" +#define NID_ipsecEndSystem 294 +#define OBJ_ipsecEndSystem OBJ_id_kp,5L + +#define SN_ipsecTunnel "ipsecTunnel" +#define LN_ipsecTunnel "IPSec Tunnel" +#define NID_ipsecTunnel 295 +#define OBJ_ipsecTunnel OBJ_id_kp,6L + +#define SN_ipsecUser "ipsecUser" +#define LN_ipsecUser "IPSec User" +#define NID_ipsecUser 296 +#define OBJ_ipsecUser OBJ_id_kp,7L + +#define SN_time_stamp "timeStamping" +#define LN_time_stamp "Time Stamping" +#define NID_time_stamp 133 +#define OBJ_time_stamp OBJ_id_kp,8L + +#define SN_OCSP_sign "OCSPSigning" +#define LN_OCSP_sign "OCSP Signing" +#define NID_OCSP_sign 180 +#define OBJ_OCSP_sign OBJ_id_kp,9L + +#define SN_dvcs "DVCS" +#define LN_dvcs "dvcs" +#define NID_dvcs 297 +#define OBJ_dvcs OBJ_id_kp,10L + +#define SN_id_it_caProtEncCert "id-it-caProtEncCert" +#define NID_id_it_caProtEncCert 298 +#define OBJ_id_it_caProtEncCert OBJ_id_it,1L + +#define SN_id_it_signKeyPairTypes "id-it-signKeyPairTypes" +#define NID_id_it_signKeyPairTypes 299 +#define OBJ_id_it_signKeyPairTypes OBJ_id_it,2L + +#define SN_id_it_encKeyPairTypes "id-it-encKeyPairTypes" +#define NID_id_it_encKeyPairTypes 300 +#define OBJ_id_it_encKeyPairTypes OBJ_id_it,3L + +#define SN_id_it_preferredSymmAlg "id-it-preferredSymmAlg" +#define NID_id_it_preferredSymmAlg 301 +#define OBJ_id_it_preferredSymmAlg OBJ_id_it,4L + +#define SN_id_it_caKeyUpdateInfo "id-it-caKeyUpdateInfo" +#define NID_id_it_caKeyUpdateInfo 302 +#define OBJ_id_it_caKeyUpdateInfo OBJ_id_it,5L + +#define SN_id_it_currentCRL "id-it-currentCRL" +#define NID_id_it_currentCRL 303 +#define OBJ_id_it_currentCRL OBJ_id_it,6L + +#define SN_id_it_unsupportedOIDs "id-it-unsupportedOIDs" +#define NID_id_it_unsupportedOIDs 304 +#define OBJ_id_it_unsupportedOIDs OBJ_id_it,7L + +#define SN_id_it_subscriptionRequest "id-it-subscriptionRequest" +#define NID_id_it_subscriptionRequest 305 +#define OBJ_id_it_subscriptionRequest OBJ_id_it,8L + +#define SN_id_it_subscriptionResponse "id-it-subscriptionResponse" +#define NID_id_it_subscriptionResponse 306 +#define OBJ_id_it_subscriptionResponse OBJ_id_it,9L + +#define SN_id_it_keyPairParamReq "id-it-keyPairParamReq" +#define NID_id_it_keyPairParamReq 307 +#define OBJ_id_it_keyPairParamReq OBJ_id_it,10L + +#define SN_id_it_keyPairParamRep "id-it-keyPairParamRep" +#define NID_id_it_keyPairParamRep 308 +#define OBJ_id_it_keyPairParamRep OBJ_id_it,11L + +#define SN_id_it_revPassphrase "id-it-revPassphrase" +#define NID_id_it_revPassphrase 309 +#define OBJ_id_it_revPassphrase OBJ_id_it,12L + +#define SN_id_it_implicitConfirm "id-it-implicitConfirm" +#define NID_id_it_implicitConfirm 310 +#define OBJ_id_it_implicitConfirm OBJ_id_it,13L + +#define SN_id_it_confirmWaitTime "id-it-confirmWaitTime" +#define NID_id_it_confirmWaitTime 311 +#define OBJ_id_it_confirmWaitTime OBJ_id_it,14L + +#define SN_id_it_origPKIMessage "id-it-origPKIMessage" +#define NID_id_it_origPKIMessage 312 +#define OBJ_id_it_origPKIMessage OBJ_id_it,15L + +#define SN_id_it_suppLangTags "id-it-suppLangTags" +#define NID_id_it_suppLangTags 784 +#define OBJ_id_it_suppLangTags OBJ_id_it,16L + +#define SN_id_regCtrl "id-regCtrl" +#define NID_id_regCtrl 313 +#define OBJ_id_regCtrl OBJ_id_pkip,1L + +#define SN_id_regInfo "id-regInfo" +#define NID_id_regInfo 314 +#define OBJ_id_regInfo OBJ_id_pkip,2L + +#define SN_id_regCtrl_regToken "id-regCtrl-regToken" +#define NID_id_regCtrl_regToken 315 +#define OBJ_id_regCtrl_regToken OBJ_id_regCtrl,1L + +#define SN_id_regCtrl_authenticator "id-regCtrl-authenticator" +#define NID_id_regCtrl_authenticator 316 +#define OBJ_id_regCtrl_authenticator OBJ_id_regCtrl,2L + +#define SN_id_regCtrl_pkiPublicationInfo "id-regCtrl-pkiPublicationInfo" +#define NID_id_regCtrl_pkiPublicationInfo 317 +#define OBJ_id_regCtrl_pkiPublicationInfo OBJ_id_regCtrl,3L + +#define SN_id_regCtrl_pkiArchiveOptions "id-regCtrl-pkiArchiveOptions" +#define NID_id_regCtrl_pkiArchiveOptions 318 +#define OBJ_id_regCtrl_pkiArchiveOptions OBJ_id_regCtrl,4L + +#define SN_id_regCtrl_oldCertID "id-regCtrl-oldCertID" +#define NID_id_regCtrl_oldCertID 319 +#define OBJ_id_regCtrl_oldCertID OBJ_id_regCtrl,5L + +#define SN_id_regCtrl_protocolEncrKey "id-regCtrl-protocolEncrKey" +#define NID_id_regCtrl_protocolEncrKey 320 +#define OBJ_id_regCtrl_protocolEncrKey OBJ_id_regCtrl,6L + +#define SN_id_regInfo_utf8Pairs "id-regInfo-utf8Pairs" +#define NID_id_regInfo_utf8Pairs 321 +#define OBJ_id_regInfo_utf8Pairs OBJ_id_regInfo,1L + +#define SN_id_regInfo_certReq "id-regInfo-certReq" +#define NID_id_regInfo_certReq 322 +#define OBJ_id_regInfo_certReq OBJ_id_regInfo,2L + +#define SN_id_alg_des40 "id-alg-des40" +#define NID_id_alg_des40 323 +#define OBJ_id_alg_des40 OBJ_id_alg,1L + +#define SN_id_alg_noSignature "id-alg-noSignature" +#define NID_id_alg_noSignature 324 +#define OBJ_id_alg_noSignature OBJ_id_alg,2L + +#define SN_id_alg_dh_sig_hmac_sha1 "id-alg-dh-sig-hmac-sha1" +#define NID_id_alg_dh_sig_hmac_sha1 325 +#define OBJ_id_alg_dh_sig_hmac_sha1 OBJ_id_alg,3L + +#define SN_id_alg_dh_pop "id-alg-dh-pop" +#define NID_id_alg_dh_pop 326 +#define OBJ_id_alg_dh_pop OBJ_id_alg,4L + +#define SN_id_cmc_statusInfo "id-cmc-statusInfo" +#define NID_id_cmc_statusInfo 327 +#define OBJ_id_cmc_statusInfo OBJ_id_cmc,1L + +#define SN_id_cmc_identification "id-cmc-identification" +#define NID_id_cmc_identification 328 +#define OBJ_id_cmc_identification OBJ_id_cmc,2L + +#define SN_id_cmc_identityProof "id-cmc-identityProof" +#define NID_id_cmc_identityProof 329 +#define OBJ_id_cmc_identityProof OBJ_id_cmc,3L + +#define SN_id_cmc_dataReturn "id-cmc-dataReturn" +#define NID_id_cmc_dataReturn 330 +#define OBJ_id_cmc_dataReturn OBJ_id_cmc,4L + +#define SN_id_cmc_transactionId "id-cmc-transactionId" +#define NID_id_cmc_transactionId 331 +#define OBJ_id_cmc_transactionId OBJ_id_cmc,5L + +#define SN_id_cmc_senderNonce "id-cmc-senderNonce" +#define NID_id_cmc_senderNonce 332 +#define OBJ_id_cmc_senderNonce OBJ_id_cmc,6L + +#define SN_id_cmc_recipientNonce "id-cmc-recipientNonce" +#define NID_id_cmc_recipientNonce 333 +#define OBJ_id_cmc_recipientNonce OBJ_id_cmc,7L + +#define SN_id_cmc_addExtensions "id-cmc-addExtensions" +#define NID_id_cmc_addExtensions 334 +#define OBJ_id_cmc_addExtensions OBJ_id_cmc,8L + +#define SN_id_cmc_encryptedPOP "id-cmc-encryptedPOP" +#define NID_id_cmc_encryptedPOP 335 +#define OBJ_id_cmc_encryptedPOP OBJ_id_cmc,9L + +#define SN_id_cmc_decryptedPOP "id-cmc-decryptedPOP" +#define NID_id_cmc_decryptedPOP 336 +#define OBJ_id_cmc_decryptedPOP OBJ_id_cmc,10L + +#define SN_id_cmc_lraPOPWitness "id-cmc-lraPOPWitness" +#define NID_id_cmc_lraPOPWitness 337 +#define OBJ_id_cmc_lraPOPWitness OBJ_id_cmc,11L + +#define SN_id_cmc_getCert "id-cmc-getCert" +#define NID_id_cmc_getCert 338 +#define OBJ_id_cmc_getCert OBJ_id_cmc,15L + +#define SN_id_cmc_getCRL "id-cmc-getCRL" +#define NID_id_cmc_getCRL 339 +#define OBJ_id_cmc_getCRL OBJ_id_cmc,16L + +#define SN_id_cmc_revokeRequest "id-cmc-revokeRequest" +#define NID_id_cmc_revokeRequest 340 +#define OBJ_id_cmc_revokeRequest OBJ_id_cmc,17L + +#define SN_id_cmc_regInfo "id-cmc-regInfo" +#define NID_id_cmc_regInfo 341 +#define OBJ_id_cmc_regInfo OBJ_id_cmc,18L + +#define SN_id_cmc_responseInfo "id-cmc-responseInfo" +#define NID_id_cmc_responseInfo 342 +#define OBJ_id_cmc_responseInfo OBJ_id_cmc,19L + +#define SN_id_cmc_queryPending "id-cmc-queryPending" +#define NID_id_cmc_queryPending 343 +#define OBJ_id_cmc_queryPending OBJ_id_cmc,21L + +#define SN_id_cmc_popLinkRandom "id-cmc-popLinkRandom" +#define NID_id_cmc_popLinkRandom 344 +#define OBJ_id_cmc_popLinkRandom OBJ_id_cmc,22L + +#define SN_id_cmc_popLinkWitness "id-cmc-popLinkWitness" +#define NID_id_cmc_popLinkWitness 345 +#define OBJ_id_cmc_popLinkWitness OBJ_id_cmc,23L + +#define SN_id_cmc_confirmCertAcceptance "id-cmc-confirmCertAcceptance" +#define NID_id_cmc_confirmCertAcceptance 346 +#define OBJ_id_cmc_confirmCertAcceptance OBJ_id_cmc,24L + +#define SN_id_on_personalData "id-on-personalData" +#define NID_id_on_personalData 347 +#define OBJ_id_on_personalData OBJ_id_on,1L + +#define SN_id_on_permanentIdentifier "id-on-permanentIdentifier" +#define LN_id_on_permanentIdentifier "Permanent Identifier" +#define NID_id_on_permanentIdentifier 858 +#define OBJ_id_on_permanentIdentifier OBJ_id_on,3L + +#define SN_id_pda_dateOfBirth "id-pda-dateOfBirth" +#define NID_id_pda_dateOfBirth 348 +#define OBJ_id_pda_dateOfBirth OBJ_id_pda,1L + +#define SN_id_pda_placeOfBirth "id-pda-placeOfBirth" +#define NID_id_pda_placeOfBirth 349 +#define OBJ_id_pda_placeOfBirth OBJ_id_pda,2L + +#define SN_id_pda_gender "id-pda-gender" +#define NID_id_pda_gender 351 +#define OBJ_id_pda_gender OBJ_id_pda,3L + +#define SN_id_pda_countryOfCitizenship "id-pda-countryOfCitizenship" +#define NID_id_pda_countryOfCitizenship 352 +#define OBJ_id_pda_countryOfCitizenship OBJ_id_pda,4L + +#define SN_id_pda_countryOfResidence "id-pda-countryOfResidence" +#define NID_id_pda_countryOfResidence 353 +#define OBJ_id_pda_countryOfResidence OBJ_id_pda,5L + +#define SN_id_aca_authenticationInfo "id-aca-authenticationInfo" +#define NID_id_aca_authenticationInfo 354 +#define OBJ_id_aca_authenticationInfo OBJ_id_aca,1L + +#define SN_id_aca_accessIdentity "id-aca-accessIdentity" +#define NID_id_aca_accessIdentity 355 +#define OBJ_id_aca_accessIdentity OBJ_id_aca,2L + +#define SN_id_aca_chargingIdentity "id-aca-chargingIdentity" +#define NID_id_aca_chargingIdentity 356 +#define OBJ_id_aca_chargingIdentity OBJ_id_aca,3L + +#define SN_id_aca_group "id-aca-group" +#define NID_id_aca_group 357 +#define OBJ_id_aca_group OBJ_id_aca,4L + +#define SN_id_aca_role "id-aca-role" +#define NID_id_aca_role 358 +#define OBJ_id_aca_role OBJ_id_aca,5L + +#define SN_id_aca_encAttrs "id-aca-encAttrs" +#define NID_id_aca_encAttrs 399 +#define OBJ_id_aca_encAttrs OBJ_id_aca,6L + +#define SN_id_qcs_pkixQCSyntax_v1 "id-qcs-pkixQCSyntax-v1" +#define NID_id_qcs_pkixQCSyntax_v1 359 +#define OBJ_id_qcs_pkixQCSyntax_v1 OBJ_id_qcs,1L + +#define SN_id_cct_crs "id-cct-crs" +#define NID_id_cct_crs 360 +#define OBJ_id_cct_crs OBJ_id_cct,1L + +#define SN_id_cct_PKIData "id-cct-PKIData" +#define NID_id_cct_PKIData 361 +#define OBJ_id_cct_PKIData OBJ_id_cct,2L + +#define SN_id_cct_PKIResponse "id-cct-PKIResponse" +#define NID_id_cct_PKIResponse 362 +#define OBJ_id_cct_PKIResponse OBJ_id_cct,3L + +#define SN_id_ppl_anyLanguage "id-ppl-anyLanguage" +#define LN_id_ppl_anyLanguage "Any language" +#define NID_id_ppl_anyLanguage 664 +#define OBJ_id_ppl_anyLanguage OBJ_id_ppl,0L + +#define SN_id_ppl_inheritAll "id-ppl-inheritAll" +#define LN_id_ppl_inheritAll "Inherit all" +#define NID_id_ppl_inheritAll 665 +#define OBJ_id_ppl_inheritAll OBJ_id_ppl,1L + +#define SN_Independent "id-ppl-independent" +#define LN_Independent "Independent" +#define NID_Independent 667 +#define OBJ_Independent OBJ_id_ppl,2L + +#define SN_ad_OCSP "OCSP" +#define LN_ad_OCSP "OCSP" +#define NID_ad_OCSP 178 +#define OBJ_ad_OCSP OBJ_id_ad,1L + +#define SN_ad_ca_issuers "caIssuers" +#define LN_ad_ca_issuers "CA Issuers" +#define NID_ad_ca_issuers 179 +#define OBJ_ad_ca_issuers OBJ_id_ad,2L + +#define SN_ad_timeStamping "ad_timestamping" +#define LN_ad_timeStamping "AD Time Stamping" +#define NID_ad_timeStamping 363 +#define OBJ_ad_timeStamping OBJ_id_ad,3L + +#define SN_ad_dvcs "AD_DVCS" +#define LN_ad_dvcs "ad dvcs" +#define NID_ad_dvcs 364 +#define OBJ_ad_dvcs OBJ_id_ad,4L + +#define SN_caRepository "caRepository" +#define LN_caRepository "CA Repository" +#define NID_caRepository 785 +#define OBJ_caRepository OBJ_id_ad,5L + +#define OBJ_id_pkix_OCSP OBJ_ad_OCSP + +#define SN_id_pkix_OCSP_basic "basicOCSPResponse" +#define LN_id_pkix_OCSP_basic "Basic OCSP Response" +#define NID_id_pkix_OCSP_basic 365 +#define OBJ_id_pkix_OCSP_basic OBJ_id_pkix_OCSP,1L + +#define SN_id_pkix_OCSP_Nonce "Nonce" +#define LN_id_pkix_OCSP_Nonce "OCSP Nonce" +#define NID_id_pkix_OCSP_Nonce 366 +#define OBJ_id_pkix_OCSP_Nonce OBJ_id_pkix_OCSP,2L + +#define SN_id_pkix_OCSP_CrlID "CrlID" +#define LN_id_pkix_OCSP_CrlID "OCSP CRL ID" +#define NID_id_pkix_OCSP_CrlID 367 +#define OBJ_id_pkix_OCSP_CrlID OBJ_id_pkix_OCSP,3L + +#define SN_id_pkix_OCSP_acceptableResponses "acceptableResponses" +#define LN_id_pkix_OCSP_acceptableResponses "Acceptable OCSP Responses" +#define NID_id_pkix_OCSP_acceptableResponses 368 +#define OBJ_id_pkix_OCSP_acceptableResponses OBJ_id_pkix_OCSP,4L + +#define SN_id_pkix_OCSP_noCheck "noCheck" +#define LN_id_pkix_OCSP_noCheck "OCSP No Check" +#define NID_id_pkix_OCSP_noCheck 369 +#define OBJ_id_pkix_OCSP_noCheck OBJ_id_pkix_OCSP,5L + +#define SN_id_pkix_OCSP_archiveCutoff "archiveCutoff" +#define LN_id_pkix_OCSP_archiveCutoff "OCSP Archive Cutoff" +#define NID_id_pkix_OCSP_archiveCutoff 370 +#define OBJ_id_pkix_OCSP_archiveCutoff OBJ_id_pkix_OCSP,6L + +#define SN_id_pkix_OCSP_serviceLocator "serviceLocator" +#define LN_id_pkix_OCSP_serviceLocator "OCSP Service Locator" +#define NID_id_pkix_OCSP_serviceLocator 371 +#define OBJ_id_pkix_OCSP_serviceLocator OBJ_id_pkix_OCSP,7L + +#define SN_id_pkix_OCSP_extendedStatus "extendedStatus" +#define LN_id_pkix_OCSP_extendedStatus "Extended OCSP Status" +#define NID_id_pkix_OCSP_extendedStatus 372 +#define OBJ_id_pkix_OCSP_extendedStatus OBJ_id_pkix_OCSP,8L + +#define SN_id_pkix_OCSP_valid "valid" +#define NID_id_pkix_OCSP_valid 373 +#define OBJ_id_pkix_OCSP_valid OBJ_id_pkix_OCSP,9L + +#define SN_id_pkix_OCSP_path "path" +#define NID_id_pkix_OCSP_path 374 +#define OBJ_id_pkix_OCSP_path OBJ_id_pkix_OCSP,10L + +#define SN_id_pkix_OCSP_trustRoot "trustRoot" +#define LN_id_pkix_OCSP_trustRoot "Trust Root" +#define NID_id_pkix_OCSP_trustRoot 375 +#define OBJ_id_pkix_OCSP_trustRoot OBJ_id_pkix_OCSP,11L + +#define SN_algorithm "algorithm" +#define LN_algorithm "algorithm" +#define NID_algorithm 376 +#define OBJ_algorithm 1L,3L,14L,3L,2L + +#define SN_md5WithRSA "RSA-NP-MD5" +#define LN_md5WithRSA "md5WithRSA" +#define NID_md5WithRSA 104 +#define OBJ_md5WithRSA OBJ_algorithm,3L + +#define SN_des_ecb "DES-ECB" +#define LN_des_ecb "des-ecb" +#define NID_des_ecb 29 +#define OBJ_des_ecb OBJ_algorithm,6L + +#define SN_des_cbc "DES-CBC" +#define LN_des_cbc "des-cbc" +#define NID_des_cbc 31 +#define OBJ_des_cbc OBJ_algorithm,7L + +#define SN_des_ofb64 "DES-OFB" +#define LN_des_ofb64 "des-ofb" +#define NID_des_ofb64 45 +#define OBJ_des_ofb64 OBJ_algorithm,8L + +#define SN_des_cfb64 "DES-CFB" +#define LN_des_cfb64 "des-cfb" +#define NID_des_cfb64 30 +#define OBJ_des_cfb64 OBJ_algorithm,9L + +#define SN_rsaSignature "rsaSignature" +#define NID_rsaSignature 377 +#define OBJ_rsaSignature OBJ_algorithm,11L + +#define SN_dsa_2 "DSA-old" +#define LN_dsa_2 "dsaEncryption-old" +#define NID_dsa_2 67 +#define OBJ_dsa_2 OBJ_algorithm,12L + +#define SN_dsaWithSHA "DSA-SHA" +#define LN_dsaWithSHA "dsaWithSHA" +#define NID_dsaWithSHA 66 +#define OBJ_dsaWithSHA OBJ_algorithm,13L + +#define SN_shaWithRSAEncryption "RSA-SHA" +#define LN_shaWithRSAEncryption "shaWithRSAEncryption" +#define NID_shaWithRSAEncryption 42 +#define OBJ_shaWithRSAEncryption OBJ_algorithm,15L + +#define SN_des_ede_ecb "DES-EDE" +#define LN_des_ede_ecb "des-ede" +#define NID_des_ede_ecb 32 +#define OBJ_des_ede_ecb OBJ_algorithm,17L + +#define SN_des_ede3_ecb "DES-EDE3" +#define LN_des_ede3_ecb "des-ede3" +#define NID_des_ede3_ecb 33 + +#define SN_des_ede_cbc "DES-EDE-CBC" +#define LN_des_ede_cbc "des-ede-cbc" +#define NID_des_ede_cbc 43 + +#define SN_des_ede_cfb64 "DES-EDE-CFB" +#define LN_des_ede_cfb64 "des-ede-cfb" +#define NID_des_ede_cfb64 60 + +#define SN_des_ede3_cfb64 "DES-EDE3-CFB" +#define LN_des_ede3_cfb64 "des-ede3-cfb" +#define NID_des_ede3_cfb64 61 + +#define SN_des_ede_ofb64 "DES-EDE-OFB" +#define LN_des_ede_ofb64 "des-ede-ofb" +#define NID_des_ede_ofb64 62 + +#define SN_des_ede3_ofb64 "DES-EDE3-OFB" +#define LN_des_ede3_ofb64 "des-ede3-ofb" +#define NID_des_ede3_ofb64 63 + +#define SN_desx_cbc "DESX-CBC" +#define LN_desx_cbc "desx-cbc" +#define NID_desx_cbc 80 + +#define SN_sha "SHA" +#define LN_sha "sha" +#define NID_sha 41 +#define OBJ_sha OBJ_algorithm,18L + +#define SN_sha1 "SHA1" +#define LN_sha1 "sha1" +#define NID_sha1 64 +#define OBJ_sha1 OBJ_algorithm,26L + +#define SN_dsaWithSHA1_2 "DSA-SHA1-old" +#define LN_dsaWithSHA1_2 "dsaWithSHA1-old" +#define NID_dsaWithSHA1_2 70 +#define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L + +#define SN_sha1WithRSA "RSA-SHA1-2" +#define LN_sha1WithRSA "sha1WithRSA" +#define NID_sha1WithRSA 115 +#define OBJ_sha1WithRSA OBJ_algorithm,29L + +#define SN_ripemd160 "RIPEMD160" +#define LN_ripemd160 "ripemd160" +#define NID_ripemd160 117 +#define OBJ_ripemd160 1L,3L,36L,3L,2L,1L + +#define SN_ripemd160WithRSA "RSA-RIPEMD160" +#define LN_ripemd160WithRSA "ripemd160WithRSA" +#define NID_ripemd160WithRSA 119 +#define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L + +#define SN_sxnet "SXNetID" +#define LN_sxnet "Strong Extranet ID" +#define NID_sxnet 143 +#define OBJ_sxnet 1L,3L,101L,1L,4L,1L + +#define SN_X500 "X500" +#define LN_X500 "directory services (X.500)" +#define NID_X500 11 +#define OBJ_X500 2L,5L + +#define SN_X509 "X509" +#define NID_X509 12 +#define OBJ_X509 OBJ_X500,4L + +#define SN_commonName "CN" +#define LN_commonName "commonName" +#define NID_commonName 13 +#define OBJ_commonName OBJ_X509,3L + +#define SN_surname "SN" +#define LN_surname "surname" +#define NID_surname 100 +#define OBJ_surname OBJ_X509,4L + +#define LN_serialNumber "serialNumber" +#define NID_serialNumber 105 +#define OBJ_serialNumber OBJ_X509,5L + +#define SN_countryName "C" +#define LN_countryName "countryName" +#define NID_countryName 14 +#define OBJ_countryName OBJ_X509,6L + +#define SN_localityName "L" +#define LN_localityName "localityName" +#define NID_localityName 15 +#define OBJ_localityName OBJ_X509,7L + +#define SN_stateOrProvinceName "ST" +#define LN_stateOrProvinceName "stateOrProvinceName" +#define NID_stateOrProvinceName 16 +#define OBJ_stateOrProvinceName OBJ_X509,8L + +#define SN_streetAddress "street" +#define LN_streetAddress "streetAddress" +#define NID_streetAddress 660 +#define OBJ_streetAddress OBJ_X509,9L + +#define SN_organizationName "O" +#define LN_organizationName "organizationName" +#define NID_organizationName 17 +#define OBJ_organizationName OBJ_X509,10L + +#define SN_organizationalUnitName "OU" +#define LN_organizationalUnitName "organizationalUnitName" +#define NID_organizationalUnitName 18 +#define OBJ_organizationalUnitName OBJ_X509,11L + +#define SN_title "title" +#define LN_title "title" +#define NID_title 106 +#define OBJ_title OBJ_X509,12L + +#define LN_description "description" +#define NID_description 107 +#define OBJ_description OBJ_X509,13L + +#define LN_searchGuide "searchGuide" +#define NID_searchGuide 859 +#define OBJ_searchGuide OBJ_X509,14L + +#define LN_businessCategory "businessCategory" +#define NID_businessCategory 860 +#define OBJ_businessCategory OBJ_X509,15L + +#define LN_postalAddress "postalAddress" +#define NID_postalAddress 861 +#define OBJ_postalAddress OBJ_X509,16L + +#define LN_postalCode "postalCode" +#define NID_postalCode 661 +#define OBJ_postalCode OBJ_X509,17L + +#define LN_postOfficeBox "postOfficeBox" +#define NID_postOfficeBox 862 +#define OBJ_postOfficeBox OBJ_X509,18L + +#define LN_physicalDeliveryOfficeName "physicalDeliveryOfficeName" +#define NID_physicalDeliveryOfficeName 863 +#define OBJ_physicalDeliveryOfficeName OBJ_X509,19L + +#define LN_telephoneNumber "telephoneNumber" +#define NID_telephoneNumber 864 +#define OBJ_telephoneNumber OBJ_X509,20L + +#define LN_telexNumber "telexNumber" +#define NID_telexNumber 865 +#define OBJ_telexNumber OBJ_X509,21L + +#define LN_teletexTerminalIdentifier "teletexTerminalIdentifier" +#define NID_teletexTerminalIdentifier 866 +#define OBJ_teletexTerminalIdentifier OBJ_X509,22L + +#define LN_facsimileTelephoneNumber "facsimileTelephoneNumber" +#define NID_facsimileTelephoneNumber 867 +#define OBJ_facsimileTelephoneNumber OBJ_X509,23L + +#define LN_x121Address "x121Address" +#define NID_x121Address 868 +#define OBJ_x121Address OBJ_X509,24L + +#define LN_internationaliSDNNumber "internationaliSDNNumber" +#define NID_internationaliSDNNumber 869 +#define OBJ_internationaliSDNNumber OBJ_X509,25L + +#define LN_registeredAddress "registeredAddress" +#define NID_registeredAddress 870 +#define OBJ_registeredAddress OBJ_X509,26L + +#define LN_destinationIndicator "destinationIndicator" +#define NID_destinationIndicator 871 +#define OBJ_destinationIndicator OBJ_X509,27L + +#define LN_preferredDeliveryMethod "preferredDeliveryMethod" +#define NID_preferredDeliveryMethod 872 +#define OBJ_preferredDeliveryMethod OBJ_X509,28L + +#define LN_presentationAddress "presentationAddress" +#define NID_presentationAddress 873 +#define OBJ_presentationAddress OBJ_X509,29L + +#define LN_supportedApplicationContext "supportedApplicationContext" +#define NID_supportedApplicationContext 874 +#define OBJ_supportedApplicationContext OBJ_X509,30L + +#define SN_member "member" +#define NID_member 875 +#define OBJ_member OBJ_X509,31L + +#define SN_owner "owner" +#define NID_owner 876 +#define OBJ_owner OBJ_X509,32L + +#define LN_roleOccupant "roleOccupant" +#define NID_roleOccupant 877 +#define OBJ_roleOccupant OBJ_X509,33L + +#define SN_seeAlso "seeAlso" +#define NID_seeAlso 878 +#define OBJ_seeAlso OBJ_X509,34L + +#define LN_userPassword "userPassword" +#define NID_userPassword 879 +#define OBJ_userPassword OBJ_X509,35L + +#define LN_userCertificate "userCertificate" +#define NID_userCertificate 880 +#define OBJ_userCertificate OBJ_X509,36L + +#define LN_cACertificate "cACertificate" +#define NID_cACertificate 881 +#define OBJ_cACertificate OBJ_X509,37L + +#define LN_authorityRevocationList "authorityRevocationList" +#define NID_authorityRevocationList 882 +#define OBJ_authorityRevocationList OBJ_X509,38L + +#define LN_certificateRevocationList "certificateRevocationList" +#define NID_certificateRevocationList 883 +#define OBJ_certificateRevocationList OBJ_X509,39L + +#define LN_crossCertificatePair "crossCertificatePair" +#define NID_crossCertificatePair 884 +#define OBJ_crossCertificatePair OBJ_X509,40L + +#define SN_name "name" +#define LN_name "name" +#define NID_name 173 +#define OBJ_name OBJ_X509,41L + +#define SN_givenName "GN" +#define LN_givenName "givenName" +#define NID_givenName 99 +#define OBJ_givenName OBJ_X509,42L + +#define SN_initials "initials" +#define LN_initials "initials" +#define NID_initials 101 +#define OBJ_initials OBJ_X509,43L + +#define LN_generationQualifier "generationQualifier" +#define NID_generationQualifier 509 +#define OBJ_generationQualifier OBJ_X509,44L + +#define LN_x500UniqueIdentifier "x500UniqueIdentifier" +#define NID_x500UniqueIdentifier 503 +#define OBJ_x500UniqueIdentifier OBJ_X509,45L + +#define SN_dnQualifier "dnQualifier" +#define LN_dnQualifier "dnQualifier" +#define NID_dnQualifier 174 +#define OBJ_dnQualifier OBJ_X509,46L + +#define LN_enhancedSearchGuide "enhancedSearchGuide" +#define NID_enhancedSearchGuide 885 +#define OBJ_enhancedSearchGuide OBJ_X509,47L + +#define LN_protocolInformation "protocolInformation" +#define NID_protocolInformation 886 +#define OBJ_protocolInformation OBJ_X509,48L + +#define LN_distinguishedName "distinguishedName" +#define NID_distinguishedName 887 +#define OBJ_distinguishedName OBJ_X509,49L + +#define LN_uniqueMember "uniqueMember" +#define NID_uniqueMember 888 +#define OBJ_uniqueMember OBJ_X509,50L + +#define LN_houseIdentifier "houseIdentifier" +#define NID_houseIdentifier 889 +#define OBJ_houseIdentifier OBJ_X509,51L + +#define LN_supportedAlgorithms "supportedAlgorithms" +#define NID_supportedAlgorithms 890 +#define OBJ_supportedAlgorithms OBJ_X509,52L + +#define LN_deltaRevocationList "deltaRevocationList" +#define NID_deltaRevocationList 891 +#define OBJ_deltaRevocationList OBJ_X509,53L + +#define SN_dmdName "dmdName" +#define NID_dmdName 892 +#define OBJ_dmdName OBJ_X509,54L + +#define LN_pseudonym "pseudonym" +#define NID_pseudonym 510 +#define OBJ_pseudonym OBJ_X509,65L + +#define SN_role "role" +#define LN_role "role" +#define NID_role 400 +#define OBJ_role OBJ_X509,72L + +#define SN_X500algorithms "X500algorithms" +#define LN_X500algorithms "directory services - algorithms" +#define NID_X500algorithms 378 +#define OBJ_X500algorithms OBJ_X500,8L + +#define SN_rsa "RSA" +#define LN_rsa "rsa" +#define NID_rsa 19 +#define OBJ_rsa OBJ_X500algorithms,1L,1L + +#define SN_mdc2WithRSA "RSA-MDC2" +#define LN_mdc2WithRSA "mdc2WithRSA" +#define NID_mdc2WithRSA 96 +#define OBJ_mdc2WithRSA OBJ_X500algorithms,3L,100L + +#define SN_mdc2 "MDC2" +#define LN_mdc2 "mdc2" +#define NID_mdc2 95 +#define OBJ_mdc2 OBJ_X500algorithms,3L,101L + +#define SN_id_ce "id-ce" +#define NID_id_ce 81 +#define OBJ_id_ce OBJ_X500,29L + +#define SN_subject_directory_attributes "subjectDirectoryAttributes" +#define LN_subject_directory_attributes "X509v3 Subject Directory Attributes" +#define NID_subject_directory_attributes 769 +#define OBJ_subject_directory_attributes OBJ_id_ce,9L + +#define SN_subject_key_identifier "subjectKeyIdentifier" +#define LN_subject_key_identifier "X509v3 Subject Key Identifier" +#define NID_subject_key_identifier 82 +#define OBJ_subject_key_identifier OBJ_id_ce,14L + +#define SN_key_usage "keyUsage" +#define LN_key_usage "X509v3 Key Usage" +#define NID_key_usage 83 +#define OBJ_key_usage OBJ_id_ce,15L + +#define SN_private_key_usage_period "privateKeyUsagePeriod" +#define LN_private_key_usage_period "X509v3 Private Key Usage Period" +#define NID_private_key_usage_period 84 +#define OBJ_private_key_usage_period OBJ_id_ce,16L + +#define SN_subject_alt_name "subjectAltName" +#define LN_subject_alt_name "X509v3 Subject Alternative Name" +#define NID_subject_alt_name 85 +#define OBJ_subject_alt_name OBJ_id_ce,17L + +#define SN_issuer_alt_name "issuerAltName" +#define LN_issuer_alt_name "X509v3 Issuer Alternative Name" +#define NID_issuer_alt_name 86 +#define OBJ_issuer_alt_name OBJ_id_ce,18L + +#define SN_basic_constraints "basicConstraints" +#define LN_basic_constraints "X509v3 Basic Constraints" +#define NID_basic_constraints 87 +#define OBJ_basic_constraints OBJ_id_ce,19L + +#define SN_crl_number "crlNumber" +#define LN_crl_number "X509v3 CRL Number" +#define NID_crl_number 88 +#define OBJ_crl_number OBJ_id_ce,20L + +#define SN_crl_reason "CRLReason" +#define LN_crl_reason "X509v3 CRL Reason Code" +#define NID_crl_reason 141 +#define OBJ_crl_reason OBJ_id_ce,21L + +#define SN_invalidity_date "invalidityDate" +#define LN_invalidity_date "Invalidity Date" +#define NID_invalidity_date 142 +#define OBJ_invalidity_date OBJ_id_ce,24L + +#define SN_delta_crl "deltaCRL" +#define LN_delta_crl "X509v3 Delta CRL Indicator" +#define NID_delta_crl 140 +#define OBJ_delta_crl OBJ_id_ce,27L + +#define SN_issuing_distribution_point "issuingDistributionPoint" +#define LN_issuing_distribution_point "X509v3 Issuing Distrubution Point" +#define NID_issuing_distribution_point 770 +#define OBJ_issuing_distribution_point OBJ_id_ce,28L + +#define SN_certificate_issuer "certificateIssuer" +#define LN_certificate_issuer "X509v3 Certificate Issuer" +#define NID_certificate_issuer 771 +#define OBJ_certificate_issuer OBJ_id_ce,29L + +#define SN_name_constraints "nameConstraints" +#define LN_name_constraints "X509v3 Name Constraints" +#define NID_name_constraints 666 +#define OBJ_name_constraints OBJ_id_ce,30L + +#define SN_crl_distribution_points "crlDistributionPoints" +#define LN_crl_distribution_points "X509v3 CRL Distribution Points" +#define NID_crl_distribution_points 103 +#define OBJ_crl_distribution_points OBJ_id_ce,31L + +#define SN_certificate_policies "certificatePolicies" +#define LN_certificate_policies "X509v3 Certificate Policies" +#define NID_certificate_policies 89 +#define OBJ_certificate_policies OBJ_id_ce,32L + +#define SN_any_policy "anyPolicy" +#define LN_any_policy "X509v3 Any Policy" +#define NID_any_policy 746 +#define OBJ_any_policy OBJ_certificate_policies,0L + +#define SN_policy_mappings "policyMappings" +#define LN_policy_mappings "X509v3 Policy Mappings" +#define NID_policy_mappings 747 +#define OBJ_policy_mappings OBJ_id_ce,33L + +#define SN_authority_key_identifier "authorityKeyIdentifier" +#define LN_authority_key_identifier "X509v3 Authority Key Identifier" +#define NID_authority_key_identifier 90 +#define OBJ_authority_key_identifier OBJ_id_ce,35L + +#define SN_policy_constraints "policyConstraints" +#define LN_policy_constraints "X509v3 Policy Constraints" +#define NID_policy_constraints 401 +#define OBJ_policy_constraints OBJ_id_ce,36L + +#define SN_ext_key_usage "extendedKeyUsage" +#define LN_ext_key_usage "X509v3 Extended Key Usage" +#define NID_ext_key_usage 126 +#define OBJ_ext_key_usage OBJ_id_ce,37L + +#define SN_freshest_crl "freshestCRL" +#define LN_freshest_crl "X509v3 Freshest CRL" +#define NID_freshest_crl 857 +#define OBJ_freshest_crl OBJ_id_ce,46L + +#define SN_inhibit_any_policy "inhibitAnyPolicy" +#define LN_inhibit_any_policy "X509v3 Inhibit Any Policy" +#define NID_inhibit_any_policy 748 +#define OBJ_inhibit_any_policy OBJ_id_ce,54L + +#define SN_target_information "targetInformation" +#define LN_target_information "X509v3 AC Targeting" +#define NID_target_information 402 +#define OBJ_target_information OBJ_id_ce,55L + +#define SN_no_rev_avail "noRevAvail" +#define LN_no_rev_avail "X509v3 No Revocation Available" +#define NID_no_rev_avail 403 +#define OBJ_no_rev_avail OBJ_id_ce,56L + +#define SN_netscape "Netscape" +#define LN_netscape "Netscape Communications Corp." +#define NID_netscape 57 +#define OBJ_netscape 2L,16L,840L,1L,113730L + +#define SN_netscape_cert_extension "nsCertExt" +#define LN_netscape_cert_extension "Netscape Certificate Extension" +#define NID_netscape_cert_extension 58 +#define OBJ_netscape_cert_extension OBJ_netscape,1L + +#define SN_netscape_data_type "nsDataType" +#define LN_netscape_data_type "Netscape Data Type" +#define NID_netscape_data_type 59 +#define OBJ_netscape_data_type OBJ_netscape,2L + +#define SN_netscape_cert_type "nsCertType" +#define LN_netscape_cert_type "Netscape Cert Type" +#define NID_netscape_cert_type 71 +#define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L + +#define SN_netscape_base_url "nsBaseUrl" +#define LN_netscape_base_url "Netscape Base Url" +#define NID_netscape_base_url 72 +#define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L + +#define SN_netscape_revocation_url "nsRevocationUrl" +#define LN_netscape_revocation_url "Netscape Revocation Url" +#define NID_netscape_revocation_url 73 +#define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L + +#define SN_netscape_ca_revocation_url "nsCaRevocationUrl" +#define LN_netscape_ca_revocation_url "Netscape CA Revocation Url" +#define NID_netscape_ca_revocation_url 74 +#define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L + +#define SN_netscape_renewal_url "nsRenewalUrl" +#define LN_netscape_renewal_url "Netscape Renewal Url" +#define NID_netscape_renewal_url 75 +#define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L + +#define SN_netscape_ca_policy_url "nsCaPolicyUrl" +#define LN_netscape_ca_policy_url "Netscape CA Policy Url" +#define NID_netscape_ca_policy_url 76 +#define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L + +#define SN_netscape_ssl_server_name "nsSslServerName" +#define LN_netscape_ssl_server_name "Netscape SSL Server Name" +#define NID_netscape_ssl_server_name 77 +#define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L + +#define SN_netscape_comment "nsComment" +#define LN_netscape_comment "Netscape Comment" +#define NID_netscape_comment 78 +#define OBJ_netscape_comment OBJ_netscape_cert_extension,13L + +#define SN_netscape_cert_sequence "nsCertSequence" +#define LN_netscape_cert_sequence "Netscape Certificate Sequence" +#define NID_netscape_cert_sequence 79 +#define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L + +#define SN_ns_sgc "nsSGC" +#define LN_ns_sgc "Netscape Server Gated Crypto" +#define NID_ns_sgc 139 +#define OBJ_ns_sgc OBJ_netscape,4L,1L + +#define SN_org "ORG" +#define LN_org "org" +#define NID_org 379 +#define OBJ_org OBJ_iso,3L + +#define SN_dod "DOD" +#define LN_dod "dod" +#define NID_dod 380 +#define OBJ_dod OBJ_org,6L + +#define SN_iana "IANA" +#define LN_iana "iana" +#define NID_iana 381 +#define OBJ_iana OBJ_dod,1L + +#define OBJ_internet OBJ_iana + +#define SN_Directory "directory" +#define LN_Directory "Directory" +#define NID_Directory 382 +#define OBJ_Directory OBJ_internet,1L + +#define SN_Management "mgmt" +#define LN_Management "Management" +#define NID_Management 383 +#define OBJ_Management OBJ_internet,2L + +#define SN_Experimental "experimental" +#define LN_Experimental "Experimental" +#define NID_Experimental 384 +#define OBJ_Experimental OBJ_internet,3L + +#define SN_Private "private" +#define LN_Private "Private" +#define NID_Private 385 +#define OBJ_Private OBJ_internet,4L + +#define SN_Security "security" +#define LN_Security "Security" +#define NID_Security 386 +#define OBJ_Security OBJ_internet,5L + +#define SN_SNMPv2 "snmpv2" +#define LN_SNMPv2 "SNMPv2" +#define NID_SNMPv2 387 +#define OBJ_SNMPv2 OBJ_internet,6L + +#define LN_Mail "Mail" +#define NID_Mail 388 +#define OBJ_Mail OBJ_internet,7L + +#define SN_Enterprises "enterprises" +#define LN_Enterprises "Enterprises" +#define NID_Enterprises 389 +#define OBJ_Enterprises OBJ_Private,1L + +#define SN_dcObject "dcobject" +#define LN_dcObject "dcObject" +#define NID_dcObject 390 +#define OBJ_dcObject OBJ_Enterprises,1466L,344L + +#define SN_mime_mhs "mime-mhs" +#define LN_mime_mhs "MIME MHS" +#define NID_mime_mhs 504 +#define OBJ_mime_mhs OBJ_Mail,1L + +#define SN_mime_mhs_headings "mime-mhs-headings" +#define LN_mime_mhs_headings "mime-mhs-headings" +#define NID_mime_mhs_headings 505 +#define OBJ_mime_mhs_headings OBJ_mime_mhs,1L + +#define SN_mime_mhs_bodies "mime-mhs-bodies" +#define LN_mime_mhs_bodies "mime-mhs-bodies" +#define NID_mime_mhs_bodies 506 +#define OBJ_mime_mhs_bodies OBJ_mime_mhs,2L + +#define SN_id_hex_partial_message "id-hex-partial-message" +#define LN_id_hex_partial_message "id-hex-partial-message" +#define NID_id_hex_partial_message 507 +#define OBJ_id_hex_partial_message OBJ_mime_mhs_headings,1L + +#define SN_id_hex_multipart_message "id-hex-multipart-message" +#define LN_id_hex_multipart_message "id-hex-multipart-message" +#define NID_id_hex_multipart_message 508 +#define OBJ_id_hex_multipart_message OBJ_mime_mhs_headings,2L + +#define SN_rle_compression "RLE" +#define LN_rle_compression "run length compression" +#define NID_rle_compression 124 +#define OBJ_rle_compression 1L,1L,1L,1L,666L,1L + +#define SN_zlib_compression "ZLIB" +#define LN_zlib_compression "zlib compression" +#define NID_zlib_compression 125 +#define OBJ_zlib_compression OBJ_id_smime_alg,8L + +#define OBJ_csor 2L,16L,840L,1L,101L,3L + +#define OBJ_nistAlgorithms OBJ_csor,4L + +#define OBJ_aes OBJ_nistAlgorithms,1L + +#define SN_aes_128_ecb "AES-128-ECB" +#define LN_aes_128_ecb "aes-128-ecb" +#define NID_aes_128_ecb 418 +#define OBJ_aes_128_ecb OBJ_aes,1L + +#define SN_aes_128_cbc "AES-128-CBC" +#define LN_aes_128_cbc "aes-128-cbc" +#define NID_aes_128_cbc 419 +#define OBJ_aes_128_cbc OBJ_aes,2L + +#define SN_aes_128_ofb128 "AES-128-OFB" +#define LN_aes_128_ofb128 "aes-128-ofb" +#define NID_aes_128_ofb128 420 +#define OBJ_aes_128_ofb128 OBJ_aes,3L + +#define SN_aes_128_cfb128 "AES-128-CFB" +#define LN_aes_128_cfb128 "aes-128-cfb" +#define NID_aes_128_cfb128 421 +#define OBJ_aes_128_cfb128 OBJ_aes,4L + +#define SN_aes_192_ecb "AES-192-ECB" +#define LN_aes_192_ecb "aes-192-ecb" +#define NID_aes_192_ecb 422 +#define OBJ_aes_192_ecb OBJ_aes,21L + +#define SN_aes_192_cbc "AES-192-CBC" +#define LN_aes_192_cbc "aes-192-cbc" +#define NID_aes_192_cbc 423 +#define OBJ_aes_192_cbc OBJ_aes,22L + +#define SN_aes_192_ofb128 "AES-192-OFB" +#define LN_aes_192_ofb128 "aes-192-ofb" +#define NID_aes_192_ofb128 424 +#define OBJ_aes_192_ofb128 OBJ_aes,23L + +#define SN_aes_192_cfb128 "AES-192-CFB" +#define LN_aes_192_cfb128 "aes-192-cfb" +#define NID_aes_192_cfb128 425 +#define OBJ_aes_192_cfb128 OBJ_aes,24L + +#define SN_aes_256_ecb "AES-256-ECB" +#define LN_aes_256_ecb "aes-256-ecb" +#define NID_aes_256_ecb 426 +#define OBJ_aes_256_ecb OBJ_aes,41L + +#define SN_aes_256_cbc "AES-256-CBC" +#define LN_aes_256_cbc "aes-256-cbc" +#define NID_aes_256_cbc 427 +#define OBJ_aes_256_cbc OBJ_aes,42L + +#define SN_aes_256_ofb128 "AES-256-OFB" +#define LN_aes_256_ofb128 "aes-256-ofb" +#define NID_aes_256_ofb128 428 +#define OBJ_aes_256_ofb128 OBJ_aes,43L + +#define SN_aes_256_cfb128 "AES-256-CFB" +#define LN_aes_256_cfb128 "aes-256-cfb" +#define NID_aes_256_cfb128 429 +#define OBJ_aes_256_cfb128 OBJ_aes,44L + +#define SN_aes_128_cfb1 "AES-128-CFB1" +#define LN_aes_128_cfb1 "aes-128-cfb1" +#define NID_aes_128_cfb1 650 + +#define SN_aes_192_cfb1 "AES-192-CFB1" +#define LN_aes_192_cfb1 "aes-192-cfb1" +#define NID_aes_192_cfb1 651 + +#define SN_aes_256_cfb1 "AES-256-CFB1" +#define LN_aes_256_cfb1 "aes-256-cfb1" +#define NID_aes_256_cfb1 652 + +#define SN_aes_128_cfb8 "AES-128-CFB8" +#define LN_aes_128_cfb8 "aes-128-cfb8" +#define NID_aes_128_cfb8 653 + +#define SN_aes_192_cfb8 "AES-192-CFB8" +#define LN_aes_192_cfb8 "aes-192-cfb8" +#define NID_aes_192_cfb8 654 + +#define SN_aes_256_cfb8 "AES-256-CFB8" +#define LN_aes_256_cfb8 "aes-256-cfb8" +#define NID_aes_256_cfb8 655 + +#define SN_des_cfb1 "DES-CFB1" +#define LN_des_cfb1 "des-cfb1" +#define NID_des_cfb1 656 + +#define SN_des_cfb8 "DES-CFB8" +#define LN_des_cfb8 "des-cfb8" +#define NID_des_cfb8 657 + +#define SN_des_ede3_cfb1 "DES-EDE3-CFB1" +#define LN_des_ede3_cfb1 "des-ede3-cfb1" +#define NID_des_ede3_cfb1 658 + +#define SN_des_ede3_cfb8 "DES-EDE3-CFB8" +#define LN_des_ede3_cfb8 "des-ede3-cfb8" +#define NID_des_ede3_cfb8 659 + +#define SN_id_aes128_wrap "id-aes128-wrap" +#define NID_id_aes128_wrap 788 +#define OBJ_id_aes128_wrap OBJ_aes,5L + +#define SN_id_aes192_wrap "id-aes192-wrap" +#define NID_id_aes192_wrap 789 +#define OBJ_id_aes192_wrap OBJ_aes,25L + +#define SN_id_aes256_wrap "id-aes256-wrap" +#define NID_id_aes256_wrap 790 +#define OBJ_id_aes256_wrap OBJ_aes,45L + +#define OBJ_nist_hashalgs OBJ_nistAlgorithms,2L + +#define SN_sha256 "SHA256" +#define LN_sha256 "sha256" +#define NID_sha256 672 +#define OBJ_sha256 OBJ_nist_hashalgs,1L + +#define SN_sha384 "SHA384" +#define LN_sha384 "sha384" +#define NID_sha384 673 +#define OBJ_sha384 OBJ_nist_hashalgs,2L + +#define SN_sha512 "SHA512" +#define LN_sha512 "sha512" +#define NID_sha512 674 +#define OBJ_sha512 OBJ_nist_hashalgs,3L + +#define SN_sha224 "SHA224" +#define LN_sha224 "sha224" +#define NID_sha224 675 +#define OBJ_sha224 OBJ_nist_hashalgs,4L + +#define OBJ_dsa_with_sha2 OBJ_nistAlgorithms,3L + +#define SN_dsa_with_SHA224 "dsa_with_SHA224" +#define NID_dsa_with_SHA224 802 +#define OBJ_dsa_with_SHA224 OBJ_dsa_with_sha2,1L + +#define SN_dsa_with_SHA256 "dsa_with_SHA256" +#define NID_dsa_with_SHA256 803 +#define OBJ_dsa_with_SHA256 OBJ_dsa_with_sha2,2L + +#define SN_hold_instruction_code "holdInstructionCode" +#define LN_hold_instruction_code "Hold Instruction Code" +#define NID_hold_instruction_code 430 +#define OBJ_hold_instruction_code OBJ_id_ce,23L + +#define OBJ_holdInstruction OBJ_X9_57,2L + +#define SN_hold_instruction_none "holdInstructionNone" +#define LN_hold_instruction_none "Hold Instruction None" +#define NID_hold_instruction_none 431 +#define OBJ_hold_instruction_none OBJ_holdInstruction,1L + +#define SN_hold_instruction_call_issuer "holdInstructionCallIssuer" +#define LN_hold_instruction_call_issuer "Hold Instruction Call Issuer" +#define NID_hold_instruction_call_issuer 432 +#define OBJ_hold_instruction_call_issuer OBJ_holdInstruction,2L + +#define SN_hold_instruction_reject "holdInstructionReject" +#define LN_hold_instruction_reject "Hold Instruction Reject" +#define NID_hold_instruction_reject 433 +#define OBJ_hold_instruction_reject OBJ_holdInstruction,3L + +#define SN_data "data" +#define NID_data 434 +#define OBJ_data OBJ_itu_t,9L + +#define SN_pss "pss" +#define NID_pss 435 +#define OBJ_pss OBJ_data,2342L + +#define SN_ucl "ucl" +#define NID_ucl 436 +#define OBJ_ucl OBJ_pss,19200300L + +#define SN_pilot "pilot" +#define NID_pilot 437 +#define OBJ_pilot OBJ_ucl,100L + +#define LN_pilotAttributeType "pilotAttributeType" +#define NID_pilotAttributeType 438 +#define OBJ_pilotAttributeType OBJ_pilot,1L + +#define LN_pilotAttributeSyntax "pilotAttributeSyntax" +#define NID_pilotAttributeSyntax 439 +#define OBJ_pilotAttributeSyntax OBJ_pilot,3L + +#define LN_pilotObjectClass "pilotObjectClass" +#define NID_pilotObjectClass 440 +#define OBJ_pilotObjectClass OBJ_pilot,4L + +#define LN_pilotGroups "pilotGroups" +#define NID_pilotGroups 441 +#define OBJ_pilotGroups OBJ_pilot,10L + +#define LN_iA5StringSyntax "iA5StringSyntax" +#define NID_iA5StringSyntax 442 +#define OBJ_iA5StringSyntax OBJ_pilotAttributeSyntax,4L + +#define LN_caseIgnoreIA5StringSyntax "caseIgnoreIA5StringSyntax" +#define NID_caseIgnoreIA5StringSyntax 443 +#define OBJ_caseIgnoreIA5StringSyntax OBJ_pilotAttributeSyntax,5L + +#define LN_pilotObject "pilotObject" +#define NID_pilotObject 444 +#define OBJ_pilotObject OBJ_pilotObjectClass,3L + +#define LN_pilotPerson "pilotPerson" +#define NID_pilotPerson 445 +#define OBJ_pilotPerson OBJ_pilotObjectClass,4L + +#define SN_account "account" +#define NID_account 446 +#define OBJ_account OBJ_pilotObjectClass,5L + +#define SN_document "document" +#define NID_document 447 +#define OBJ_document OBJ_pilotObjectClass,6L + +#define SN_room "room" +#define NID_room 448 +#define OBJ_room OBJ_pilotObjectClass,7L + +#define LN_documentSeries "documentSeries" +#define NID_documentSeries 449 +#define OBJ_documentSeries OBJ_pilotObjectClass,9L + +#define SN_Domain "domain" +#define LN_Domain "Domain" +#define NID_Domain 392 +#define OBJ_Domain OBJ_pilotObjectClass,13L + +#define LN_rFC822localPart "rFC822localPart" +#define NID_rFC822localPart 450 +#define OBJ_rFC822localPart OBJ_pilotObjectClass,14L + +#define LN_dNSDomain "dNSDomain" +#define NID_dNSDomain 451 +#define OBJ_dNSDomain OBJ_pilotObjectClass,15L + +#define LN_domainRelatedObject "domainRelatedObject" +#define NID_domainRelatedObject 452 +#define OBJ_domainRelatedObject OBJ_pilotObjectClass,17L + +#define LN_friendlyCountry "friendlyCountry" +#define NID_friendlyCountry 453 +#define OBJ_friendlyCountry OBJ_pilotObjectClass,18L + +#define LN_simpleSecurityObject "simpleSecurityObject" +#define NID_simpleSecurityObject 454 +#define OBJ_simpleSecurityObject OBJ_pilotObjectClass,19L + +#define LN_pilotOrganization "pilotOrganization" +#define NID_pilotOrganization 455 +#define OBJ_pilotOrganization OBJ_pilotObjectClass,20L + +#define LN_pilotDSA "pilotDSA" +#define NID_pilotDSA 456 +#define OBJ_pilotDSA OBJ_pilotObjectClass,21L + +#define LN_qualityLabelledData "qualityLabelledData" +#define NID_qualityLabelledData 457 +#define OBJ_qualityLabelledData OBJ_pilotObjectClass,22L + +#define SN_userId "UID" +#define LN_userId "userId" +#define NID_userId 458 +#define OBJ_userId OBJ_pilotAttributeType,1L + +#define LN_textEncodedORAddress "textEncodedORAddress" +#define NID_textEncodedORAddress 459 +#define OBJ_textEncodedORAddress OBJ_pilotAttributeType,2L + +#define SN_rfc822Mailbox "mail" +#define LN_rfc822Mailbox "rfc822Mailbox" +#define NID_rfc822Mailbox 460 +#define OBJ_rfc822Mailbox OBJ_pilotAttributeType,3L + +#define SN_info "info" +#define NID_info 461 +#define OBJ_info OBJ_pilotAttributeType,4L + +#define LN_favouriteDrink "favouriteDrink" +#define NID_favouriteDrink 462 +#define OBJ_favouriteDrink OBJ_pilotAttributeType,5L + +#define LN_roomNumber "roomNumber" +#define NID_roomNumber 463 +#define OBJ_roomNumber OBJ_pilotAttributeType,6L + +#define SN_photo "photo" +#define NID_photo 464 +#define OBJ_photo OBJ_pilotAttributeType,7L + +#define LN_userClass "userClass" +#define NID_userClass 465 +#define OBJ_userClass OBJ_pilotAttributeType,8L + +#define SN_host "host" +#define NID_host 466 +#define OBJ_host OBJ_pilotAttributeType,9L + +#define SN_manager "manager" +#define NID_manager 467 +#define OBJ_manager OBJ_pilotAttributeType,10L + +#define LN_documentIdentifier "documentIdentifier" +#define NID_documentIdentifier 468 +#define OBJ_documentIdentifier OBJ_pilotAttributeType,11L + +#define LN_documentTitle "documentTitle" +#define NID_documentTitle 469 +#define OBJ_documentTitle OBJ_pilotAttributeType,12L + +#define LN_documentVersion "documentVersion" +#define NID_documentVersion 470 +#define OBJ_documentVersion OBJ_pilotAttributeType,13L + +#define LN_documentAuthor "documentAuthor" +#define NID_documentAuthor 471 +#define OBJ_documentAuthor OBJ_pilotAttributeType,14L + +#define LN_documentLocation "documentLocation" +#define NID_documentLocation 472 +#define OBJ_documentLocation OBJ_pilotAttributeType,15L + +#define LN_homeTelephoneNumber "homeTelephoneNumber" +#define NID_homeTelephoneNumber 473 +#define OBJ_homeTelephoneNumber OBJ_pilotAttributeType,20L + +#define SN_secretary "secretary" +#define NID_secretary 474 +#define OBJ_secretary OBJ_pilotAttributeType,21L + +#define LN_otherMailbox "otherMailbox" +#define NID_otherMailbox 475 +#define OBJ_otherMailbox OBJ_pilotAttributeType,22L + +#define LN_lastModifiedTime "lastModifiedTime" +#define NID_lastModifiedTime 476 +#define OBJ_lastModifiedTime OBJ_pilotAttributeType,23L + +#define LN_lastModifiedBy "lastModifiedBy" +#define NID_lastModifiedBy 477 +#define OBJ_lastModifiedBy OBJ_pilotAttributeType,24L + +#define SN_domainComponent "DC" +#define LN_domainComponent "domainComponent" +#define NID_domainComponent 391 +#define OBJ_domainComponent OBJ_pilotAttributeType,25L + +#define LN_aRecord "aRecord" +#define NID_aRecord 478 +#define OBJ_aRecord OBJ_pilotAttributeType,26L + +#define LN_pilotAttributeType27 "pilotAttributeType27" +#define NID_pilotAttributeType27 479 +#define OBJ_pilotAttributeType27 OBJ_pilotAttributeType,27L + +#define LN_mXRecord "mXRecord" +#define NID_mXRecord 480 +#define OBJ_mXRecord OBJ_pilotAttributeType,28L + +#define LN_nSRecord "nSRecord" +#define NID_nSRecord 481 +#define OBJ_nSRecord OBJ_pilotAttributeType,29L + +#define LN_sOARecord "sOARecord" +#define NID_sOARecord 482 +#define OBJ_sOARecord OBJ_pilotAttributeType,30L + +#define LN_cNAMERecord "cNAMERecord" +#define NID_cNAMERecord 483 +#define OBJ_cNAMERecord OBJ_pilotAttributeType,31L + +#define LN_associatedDomain "associatedDomain" +#define NID_associatedDomain 484 +#define OBJ_associatedDomain OBJ_pilotAttributeType,37L + +#define LN_associatedName "associatedName" +#define NID_associatedName 485 +#define OBJ_associatedName OBJ_pilotAttributeType,38L + +#define LN_homePostalAddress "homePostalAddress" +#define NID_homePostalAddress 486 +#define OBJ_homePostalAddress OBJ_pilotAttributeType,39L + +#define LN_personalTitle "personalTitle" +#define NID_personalTitle 487 +#define OBJ_personalTitle OBJ_pilotAttributeType,40L + +#define LN_mobileTelephoneNumber "mobileTelephoneNumber" +#define NID_mobileTelephoneNumber 488 +#define OBJ_mobileTelephoneNumber OBJ_pilotAttributeType,41L + +#define LN_pagerTelephoneNumber "pagerTelephoneNumber" +#define NID_pagerTelephoneNumber 489 +#define OBJ_pagerTelephoneNumber OBJ_pilotAttributeType,42L + +#define LN_friendlyCountryName "friendlyCountryName" +#define NID_friendlyCountryName 490 +#define OBJ_friendlyCountryName OBJ_pilotAttributeType,43L + +#define LN_organizationalStatus "organizationalStatus" +#define NID_organizationalStatus 491 +#define OBJ_organizationalStatus OBJ_pilotAttributeType,45L + +#define LN_janetMailbox "janetMailbox" +#define NID_janetMailbox 492 +#define OBJ_janetMailbox OBJ_pilotAttributeType,46L + +#define LN_mailPreferenceOption "mailPreferenceOption" +#define NID_mailPreferenceOption 493 +#define OBJ_mailPreferenceOption OBJ_pilotAttributeType,47L + +#define LN_buildingName "buildingName" +#define NID_buildingName 494 +#define OBJ_buildingName OBJ_pilotAttributeType,48L + +#define LN_dSAQuality "dSAQuality" +#define NID_dSAQuality 495 +#define OBJ_dSAQuality OBJ_pilotAttributeType,49L + +#define LN_singleLevelQuality "singleLevelQuality" +#define NID_singleLevelQuality 496 +#define OBJ_singleLevelQuality OBJ_pilotAttributeType,50L + +#define LN_subtreeMinimumQuality "subtreeMinimumQuality" +#define NID_subtreeMinimumQuality 497 +#define OBJ_subtreeMinimumQuality OBJ_pilotAttributeType,51L + +#define LN_subtreeMaximumQuality "subtreeMaximumQuality" +#define NID_subtreeMaximumQuality 498 +#define OBJ_subtreeMaximumQuality OBJ_pilotAttributeType,52L + +#define LN_personalSignature "personalSignature" +#define NID_personalSignature 499 +#define OBJ_personalSignature OBJ_pilotAttributeType,53L + +#define LN_dITRedirect "dITRedirect" +#define NID_dITRedirect 500 +#define OBJ_dITRedirect OBJ_pilotAttributeType,54L + +#define SN_audio "audio" +#define NID_audio 501 +#define OBJ_audio OBJ_pilotAttributeType,55L + +#define LN_documentPublisher "documentPublisher" +#define NID_documentPublisher 502 +#define OBJ_documentPublisher OBJ_pilotAttributeType,56L + +#define SN_id_set "id-set" +#define LN_id_set "Secure Electronic Transactions" +#define NID_id_set 512 +#define OBJ_id_set OBJ_international_organizations,42L + +#define SN_set_ctype "set-ctype" +#define LN_set_ctype "content types" +#define NID_set_ctype 513 +#define OBJ_set_ctype OBJ_id_set,0L + +#define SN_set_msgExt "set-msgExt" +#define LN_set_msgExt "message extensions" +#define NID_set_msgExt 514 +#define OBJ_set_msgExt OBJ_id_set,1L + +#define SN_set_attr "set-attr" +#define NID_set_attr 515 +#define OBJ_set_attr OBJ_id_set,3L + +#define SN_set_policy "set-policy" +#define NID_set_policy 516 +#define OBJ_set_policy OBJ_id_set,5L + +#define SN_set_certExt "set-certExt" +#define LN_set_certExt "certificate extensions" +#define NID_set_certExt 517 +#define OBJ_set_certExt OBJ_id_set,7L + +#define SN_set_brand "set-brand" +#define NID_set_brand 518 +#define OBJ_set_brand OBJ_id_set,8L + +#define SN_setct_PANData "setct-PANData" +#define NID_setct_PANData 519 +#define OBJ_setct_PANData OBJ_set_ctype,0L + +#define SN_setct_PANToken "setct-PANToken" +#define NID_setct_PANToken 520 +#define OBJ_setct_PANToken OBJ_set_ctype,1L + +#define SN_setct_PANOnly "setct-PANOnly" +#define NID_setct_PANOnly 521 +#define OBJ_setct_PANOnly OBJ_set_ctype,2L + +#define SN_setct_OIData "setct-OIData" +#define NID_setct_OIData 522 +#define OBJ_setct_OIData OBJ_set_ctype,3L + +#define SN_setct_PI "setct-PI" +#define NID_setct_PI 523 +#define OBJ_setct_PI OBJ_set_ctype,4L + +#define SN_setct_PIData "setct-PIData" +#define NID_setct_PIData 524 +#define OBJ_setct_PIData OBJ_set_ctype,5L + +#define SN_setct_PIDataUnsigned "setct-PIDataUnsigned" +#define NID_setct_PIDataUnsigned 525 +#define OBJ_setct_PIDataUnsigned OBJ_set_ctype,6L + +#define SN_setct_HODInput "setct-HODInput" +#define NID_setct_HODInput 526 +#define OBJ_setct_HODInput OBJ_set_ctype,7L + +#define SN_setct_AuthResBaggage "setct-AuthResBaggage" +#define NID_setct_AuthResBaggage 527 +#define OBJ_setct_AuthResBaggage OBJ_set_ctype,8L + +#define SN_setct_AuthRevReqBaggage "setct-AuthRevReqBaggage" +#define NID_setct_AuthRevReqBaggage 528 +#define OBJ_setct_AuthRevReqBaggage OBJ_set_ctype,9L + +#define SN_setct_AuthRevResBaggage "setct-AuthRevResBaggage" +#define NID_setct_AuthRevResBaggage 529 +#define OBJ_setct_AuthRevResBaggage OBJ_set_ctype,10L + +#define SN_setct_CapTokenSeq "setct-CapTokenSeq" +#define NID_setct_CapTokenSeq 530 +#define OBJ_setct_CapTokenSeq OBJ_set_ctype,11L + +#define SN_setct_PInitResData "setct-PInitResData" +#define NID_setct_PInitResData 531 +#define OBJ_setct_PInitResData OBJ_set_ctype,12L + +#define SN_setct_PI_TBS "setct-PI-TBS" +#define NID_setct_PI_TBS 532 +#define OBJ_setct_PI_TBS OBJ_set_ctype,13L + +#define SN_setct_PResData "setct-PResData" +#define NID_setct_PResData 533 +#define OBJ_setct_PResData OBJ_set_ctype,14L + +#define SN_setct_AuthReqTBS "setct-AuthReqTBS" +#define NID_setct_AuthReqTBS 534 +#define OBJ_setct_AuthReqTBS OBJ_set_ctype,16L + +#define SN_setct_AuthResTBS "setct-AuthResTBS" +#define NID_setct_AuthResTBS 535 +#define OBJ_setct_AuthResTBS OBJ_set_ctype,17L + +#define SN_setct_AuthResTBSX "setct-AuthResTBSX" +#define NID_setct_AuthResTBSX 536 +#define OBJ_setct_AuthResTBSX OBJ_set_ctype,18L + +#define SN_setct_AuthTokenTBS "setct-AuthTokenTBS" +#define NID_setct_AuthTokenTBS 537 +#define OBJ_setct_AuthTokenTBS OBJ_set_ctype,19L + +#define SN_setct_CapTokenData "setct-CapTokenData" +#define NID_setct_CapTokenData 538 +#define OBJ_setct_CapTokenData OBJ_set_ctype,20L + +#define SN_setct_CapTokenTBS "setct-CapTokenTBS" +#define NID_setct_CapTokenTBS 539 +#define OBJ_setct_CapTokenTBS OBJ_set_ctype,21L + +#define SN_setct_AcqCardCodeMsg "setct-AcqCardCodeMsg" +#define NID_setct_AcqCardCodeMsg 540 +#define OBJ_setct_AcqCardCodeMsg OBJ_set_ctype,22L + +#define SN_setct_AuthRevReqTBS "setct-AuthRevReqTBS" +#define NID_setct_AuthRevReqTBS 541 +#define OBJ_setct_AuthRevReqTBS OBJ_set_ctype,23L + +#define SN_setct_AuthRevResData "setct-AuthRevResData" +#define NID_setct_AuthRevResData 542 +#define OBJ_setct_AuthRevResData OBJ_set_ctype,24L + +#define SN_setct_AuthRevResTBS "setct-AuthRevResTBS" +#define NID_setct_AuthRevResTBS 543 +#define OBJ_setct_AuthRevResTBS OBJ_set_ctype,25L + +#define SN_setct_CapReqTBS "setct-CapReqTBS" +#define NID_setct_CapReqTBS 544 +#define OBJ_setct_CapReqTBS OBJ_set_ctype,26L + +#define SN_setct_CapReqTBSX "setct-CapReqTBSX" +#define NID_setct_CapReqTBSX 545 +#define OBJ_setct_CapReqTBSX OBJ_set_ctype,27L + +#define SN_setct_CapResData "setct-CapResData" +#define NID_setct_CapResData 546 +#define OBJ_setct_CapResData OBJ_set_ctype,28L + +#define SN_setct_CapRevReqTBS "setct-CapRevReqTBS" +#define NID_setct_CapRevReqTBS 547 +#define OBJ_setct_CapRevReqTBS OBJ_set_ctype,29L + +#define SN_setct_CapRevReqTBSX "setct-CapRevReqTBSX" +#define NID_setct_CapRevReqTBSX 548 +#define OBJ_setct_CapRevReqTBSX OBJ_set_ctype,30L + +#define SN_setct_CapRevResData "setct-CapRevResData" +#define NID_setct_CapRevResData 549 +#define OBJ_setct_CapRevResData OBJ_set_ctype,31L + +#define SN_setct_CredReqTBS "setct-CredReqTBS" +#define NID_setct_CredReqTBS 550 +#define OBJ_setct_CredReqTBS OBJ_set_ctype,32L + +#define SN_setct_CredReqTBSX "setct-CredReqTBSX" +#define NID_setct_CredReqTBSX 551 +#define OBJ_setct_CredReqTBSX OBJ_set_ctype,33L + +#define SN_setct_CredResData "setct-CredResData" +#define NID_setct_CredResData 552 +#define OBJ_setct_CredResData OBJ_set_ctype,34L + +#define SN_setct_CredRevReqTBS "setct-CredRevReqTBS" +#define NID_setct_CredRevReqTBS 553 +#define OBJ_setct_CredRevReqTBS OBJ_set_ctype,35L + +#define SN_setct_CredRevReqTBSX "setct-CredRevReqTBSX" +#define NID_setct_CredRevReqTBSX 554 +#define OBJ_setct_CredRevReqTBSX OBJ_set_ctype,36L + +#define SN_setct_CredRevResData "setct-CredRevResData" +#define NID_setct_CredRevResData 555 +#define OBJ_setct_CredRevResData OBJ_set_ctype,37L + +#define SN_setct_PCertReqData "setct-PCertReqData" +#define NID_setct_PCertReqData 556 +#define OBJ_setct_PCertReqData OBJ_set_ctype,38L + +#define SN_setct_PCertResTBS "setct-PCertResTBS" +#define NID_setct_PCertResTBS 557 +#define OBJ_setct_PCertResTBS OBJ_set_ctype,39L + +#define SN_setct_BatchAdminReqData "setct-BatchAdminReqData" +#define NID_setct_BatchAdminReqData 558 +#define OBJ_setct_BatchAdminReqData OBJ_set_ctype,40L + +#define SN_setct_BatchAdminResData "setct-BatchAdminResData" +#define NID_setct_BatchAdminResData 559 +#define OBJ_setct_BatchAdminResData OBJ_set_ctype,41L + +#define SN_setct_CardCInitResTBS "setct-CardCInitResTBS" +#define NID_setct_CardCInitResTBS 560 +#define OBJ_setct_CardCInitResTBS OBJ_set_ctype,42L + +#define SN_setct_MeAqCInitResTBS "setct-MeAqCInitResTBS" +#define NID_setct_MeAqCInitResTBS 561 +#define OBJ_setct_MeAqCInitResTBS OBJ_set_ctype,43L + +#define SN_setct_RegFormResTBS "setct-RegFormResTBS" +#define NID_setct_RegFormResTBS 562 +#define OBJ_setct_RegFormResTBS OBJ_set_ctype,44L + +#define SN_setct_CertReqData "setct-CertReqData" +#define NID_setct_CertReqData 563 +#define OBJ_setct_CertReqData OBJ_set_ctype,45L + +#define SN_setct_CertReqTBS "setct-CertReqTBS" +#define NID_setct_CertReqTBS 564 +#define OBJ_setct_CertReqTBS OBJ_set_ctype,46L + +#define SN_setct_CertResData "setct-CertResData" +#define NID_setct_CertResData 565 +#define OBJ_setct_CertResData OBJ_set_ctype,47L + +#define SN_setct_CertInqReqTBS "setct-CertInqReqTBS" +#define NID_setct_CertInqReqTBS 566 +#define OBJ_setct_CertInqReqTBS OBJ_set_ctype,48L + +#define SN_setct_ErrorTBS "setct-ErrorTBS" +#define NID_setct_ErrorTBS 567 +#define OBJ_setct_ErrorTBS OBJ_set_ctype,49L + +#define SN_setct_PIDualSignedTBE "setct-PIDualSignedTBE" +#define NID_setct_PIDualSignedTBE 568 +#define OBJ_setct_PIDualSignedTBE OBJ_set_ctype,50L + +#define SN_setct_PIUnsignedTBE "setct-PIUnsignedTBE" +#define NID_setct_PIUnsignedTBE 569 +#define OBJ_setct_PIUnsignedTBE OBJ_set_ctype,51L + +#define SN_setct_AuthReqTBE "setct-AuthReqTBE" +#define NID_setct_AuthReqTBE 570 +#define OBJ_setct_AuthReqTBE OBJ_set_ctype,52L + +#define SN_setct_AuthResTBE "setct-AuthResTBE" +#define NID_setct_AuthResTBE 571 +#define OBJ_setct_AuthResTBE OBJ_set_ctype,53L + +#define SN_setct_AuthResTBEX "setct-AuthResTBEX" +#define NID_setct_AuthResTBEX 572 +#define OBJ_setct_AuthResTBEX OBJ_set_ctype,54L + +#define SN_setct_AuthTokenTBE "setct-AuthTokenTBE" +#define NID_setct_AuthTokenTBE 573 +#define OBJ_setct_AuthTokenTBE OBJ_set_ctype,55L + +#define SN_setct_CapTokenTBE "setct-CapTokenTBE" +#define NID_setct_CapTokenTBE 574 +#define OBJ_setct_CapTokenTBE OBJ_set_ctype,56L + +#define SN_setct_CapTokenTBEX "setct-CapTokenTBEX" +#define NID_setct_CapTokenTBEX 575 +#define OBJ_setct_CapTokenTBEX OBJ_set_ctype,57L + +#define SN_setct_AcqCardCodeMsgTBE "setct-AcqCardCodeMsgTBE" +#define NID_setct_AcqCardCodeMsgTBE 576 +#define OBJ_setct_AcqCardCodeMsgTBE OBJ_set_ctype,58L + +#define SN_setct_AuthRevReqTBE "setct-AuthRevReqTBE" +#define NID_setct_AuthRevReqTBE 577 +#define OBJ_setct_AuthRevReqTBE OBJ_set_ctype,59L + +#define SN_setct_AuthRevResTBE "setct-AuthRevResTBE" +#define NID_setct_AuthRevResTBE 578 +#define OBJ_setct_AuthRevResTBE OBJ_set_ctype,60L + +#define SN_setct_AuthRevResTBEB "setct-AuthRevResTBEB" +#define NID_setct_AuthRevResTBEB 579 +#define OBJ_setct_AuthRevResTBEB OBJ_set_ctype,61L + +#define SN_setct_CapReqTBE "setct-CapReqTBE" +#define NID_setct_CapReqTBE 580 +#define OBJ_setct_CapReqTBE OBJ_set_ctype,62L + +#define SN_setct_CapReqTBEX "setct-CapReqTBEX" +#define NID_setct_CapReqTBEX 581 +#define OBJ_setct_CapReqTBEX OBJ_set_ctype,63L + +#define SN_setct_CapResTBE "setct-CapResTBE" +#define NID_setct_CapResTBE 582 +#define OBJ_setct_CapResTBE OBJ_set_ctype,64L + +#define SN_setct_CapRevReqTBE "setct-CapRevReqTBE" +#define NID_setct_CapRevReqTBE 583 +#define OBJ_setct_CapRevReqTBE OBJ_set_ctype,65L + +#define SN_setct_CapRevReqTBEX "setct-CapRevReqTBEX" +#define NID_setct_CapRevReqTBEX 584 +#define OBJ_setct_CapRevReqTBEX OBJ_set_ctype,66L + +#define SN_setct_CapRevResTBE "setct-CapRevResTBE" +#define NID_setct_CapRevResTBE 585 +#define OBJ_setct_CapRevResTBE OBJ_set_ctype,67L + +#define SN_setct_CredReqTBE "setct-CredReqTBE" +#define NID_setct_CredReqTBE 586 +#define OBJ_setct_CredReqTBE OBJ_set_ctype,68L + +#define SN_setct_CredReqTBEX "setct-CredReqTBEX" +#define NID_setct_CredReqTBEX 587 +#define OBJ_setct_CredReqTBEX OBJ_set_ctype,69L + +#define SN_setct_CredResTBE "setct-CredResTBE" +#define NID_setct_CredResTBE 588 +#define OBJ_setct_CredResTBE OBJ_set_ctype,70L + +#define SN_setct_CredRevReqTBE "setct-CredRevReqTBE" +#define NID_setct_CredRevReqTBE 589 +#define OBJ_setct_CredRevReqTBE OBJ_set_ctype,71L + +#define SN_setct_CredRevReqTBEX "setct-CredRevReqTBEX" +#define NID_setct_CredRevReqTBEX 590 +#define OBJ_setct_CredRevReqTBEX OBJ_set_ctype,72L + +#define SN_setct_CredRevResTBE "setct-CredRevResTBE" +#define NID_setct_CredRevResTBE 591 +#define OBJ_setct_CredRevResTBE OBJ_set_ctype,73L + +#define SN_setct_BatchAdminReqTBE "setct-BatchAdminReqTBE" +#define NID_setct_BatchAdminReqTBE 592 +#define OBJ_setct_BatchAdminReqTBE OBJ_set_ctype,74L + +#define SN_setct_BatchAdminResTBE "setct-BatchAdminResTBE" +#define NID_setct_BatchAdminResTBE 593 +#define OBJ_setct_BatchAdminResTBE OBJ_set_ctype,75L + +#define SN_setct_RegFormReqTBE "setct-RegFormReqTBE" +#define NID_setct_RegFormReqTBE 594 +#define OBJ_setct_RegFormReqTBE OBJ_set_ctype,76L + +#define SN_setct_CertReqTBE "setct-CertReqTBE" +#define NID_setct_CertReqTBE 595 +#define OBJ_setct_CertReqTBE OBJ_set_ctype,77L + +#define SN_setct_CertReqTBEX "setct-CertReqTBEX" +#define NID_setct_CertReqTBEX 596 +#define OBJ_setct_CertReqTBEX OBJ_set_ctype,78L + +#define SN_setct_CertResTBE "setct-CertResTBE" +#define NID_setct_CertResTBE 597 +#define OBJ_setct_CertResTBE OBJ_set_ctype,79L + +#define SN_setct_CRLNotificationTBS "setct-CRLNotificationTBS" +#define NID_setct_CRLNotificationTBS 598 +#define OBJ_setct_CRLNotificationTBS OBJ_set_ctype,80L + +#define SN_setct_CRLNotificationResTBS "setct-CRLNotificationResTBS" +#define NID_setct_CRLNotificationResTBS 599 +#define OBJ_setct_CRLNotificationResTBS OBJ_set_ctype,81L + +#define SN_setct_BCIDistributionTBS "setct-BCIDistributionTBS" +#define NID_setct_BCIDistributionTBS 600 +#define OBJ_setct_BCIDistributionTBS OBJ_set_ctype,82L + +#define SN_setext_genCrypt "setext-genCrypt" +#define LN_setext_genCrypt "generic cryptogram" +#define NID_setext_genCrypt 601 +#define OBJ_setext_genCrypt OBJ_set_msgExt,1L + +#define SN_setext_miAuth "setext-miAuth" +#define LN_setext_miAuth "merchant initiated auth" +#define NID_setext_miAuth 602 +#define OBJ_setext_miAuth OBJ_set_msgExt,3L + +#define SN_setext_pinSecure "setext-pinSecure" +#define NID_setext_pinSecure 603 +#define OBJ_setext_pinSecure OBJ_set_msgExt,4L + +#define SN_setext_pinAny "setext-pinAny" +#define NID_setext_pinAny 604 +#define OBJ_setext_pinAny OBJ_set_msgExt,5L + +#define SN_setext_track2 "setext-track2" +#define NID_setext_track2 605 +#define OBJ_setext_track2 OBJ_set_msgExt,7L + +#define SN_setext_cv "setext-cv" +#define LN_setext_cv "additional verification" +#define NID_setext_cv 606 +#define OBJ_setext_cv OBJ_set_msgExt,8L + +#define SN_set_policy_root "set-policy-root" +#define NID_set_policy_root 607 +#define OBJ_set_policy_root OBJ_set_policy,0L + +#define SN_setCext_hashedRoot "setCext-hashedRoot" +#define NID_setCext_hashedRoot 608 +#define OBJ_setCext_hashedRoot OBJ_set_certExt,0L + +#define SN_setCext_certType "setCext-certType" +#define NID_setCext_certType 609 +#define OBJ_setCext_certType OBJ_set_certExt,1L + +#define SN_setCext_merchData "setCext-merchData" +#define NID_setCext_merchData 610 +#define OBJ_setCext_merchData OBJ_set_certExt,2L + +#define SN_setCext_cCertRequired "setCext-cCertRequired" +#define NID_setCext_cCertRequired 611 +#define OBJ_setCext_cCertRequired OBJ_set_certExt,3L + +#define SN_setCext_tunneling "setCext-tunneling" +#define NID_setCext_tunneling 612 +#define OBJ_setCext_tunneling OBJ_set_certExt,4L + +#define SN_setCext_setExt "setCext-setExt" +#define NID_setCext_setExt 613 +#define OBJ_setCext_setExt OBJ_set_certExt,5L + +#define SN_setCext_setQualf "setCext-setQualf" +#define NID_setCext_setQualf 614 +#define OBJ_setCext_setQualf OBJ_set_certExt,6L + +#define SN_setCext_PGWYcapabilities "setCext-PGWYcapabilities" +#define NID_setCext_PGWYcapabilities 615 +#define OBJ_setCext_PGWYcapabilities OBJ_set_certExt,7L + +#define SN_setCext_TokenIdentifier "setCext-TokenIdentifier" +#define NID_setCext_TokenIdentifier 616 +#define OBJ_setCext_TokenIdentifier OBJ_set_certExt,8L + +#define SN_setCext_Track2Data "setCext-Track2Data" +#define NID_setCext_Track2Data 617 +#define OBJ_setCext_Track2Data OBJ_set_certExt,9L + +#define SN_setCext_TokenType "setCext-TokenType" +#define NID_setCext_TokenType 618 +#define OBJ_setCext_TokenType OBJ_set_certExt,10L + +#define SN_setCext_IssuerCapabilities "setCext-IssuerCapabilities" +#define NID_setCext_IssuerCapabilities 619 +#define OBJ_setCext_IssuerCapabilities OBJ_set_certExt,11L + +#define SN_setAttr_Cert "setAttr-Cert" +#define NID_setAttr_Cert 620 +#define OBJ_setAttr_Cert OBJ_set_attr,0L + +#define SN_setAttr_PGWYcap "setAttr-PGWYcap" +#define LN_setAttr_PGWYcap "payment gateway capabilities" +#define NID_setAttr_PGWYcap 621 +#define OBJ_setAttr_PGWYcap OBJ_set_attr,1L + +#define SN_setAttr_TokenType "setAttr-TokenType" +#define NID_setAttr_TokenType 622 +#define OBJ_setAttr_TokenType OBJ_set_attr,2L + +#define SN_setAttr_IssCap "setAttr-IssCap" +#define LN_setAttr_IssCap "issuer capabilities" +#define NID_setAttr_IssCap 623 +#define OBJ_setAttr_IssCap OBJ_set_attr,3L + +#define SN_set_rootKeyThumb "set-rootKeyThumb" +#define NID_set_rootKeyThumb 624 +#define OBJ_set_rootKeyThumb OBJ_setAttr_Cert,0L + +#define SN_set_addPolicy "set-addPolicy" +#define NID_set_addPolicy 625 +#define OBJ_set_addPolicy OBJ_setAttr_Cert,1L + +#define SN_setAttr_Token_EMV "setAttr-Token-EMV" +#define NID_setAttr_Token_EMV 626 +#define OBJ_setAttr_Token_EMV OBJ_setAttr_TokenType,1L + +#define SN_setAttr_Token_B0Prime "setAttr-Token-B0Prime" +#define NID_setAttr_Token_B0Prime 627 +#define OBJ_setAttr_Token_B0Prime OBJ_setAttr_TokenType,2L + +#define SN_setAttr_IssCap_CVM "setAttr-IssCap-CVM" +#define NID_setAttr_IssCap_CVM 628 +#define OBJ_setAttr_IssCap_CVM OBJ_setAttr_IssCap,3L + +#define SN_setAttr_IssCap_T2 "setAttr-IssCap-T2" +#define NID_setAttr_IssCap_T2 629 +#define OBJ_setAttr_IssCap_T2 OBJ_setAttr_IssCap,4L + +#define SN_setAttr_IssCap_Sig "setAttr-IssCap-Sig" +#define NID_setAttr_IssCap_Sig 630 +#define OBJ_setAttr_IssCap_Sig OBJ_setAttr_IssCap,5L + +#define SN_setAttr_GenCryptgrm "setAttr-GenCryptgrm" +#define LN_setAttr_GenCryptgrm "generate cryptogram" +#define NID_setAttr_GenCryptgrm 631 +#define OBJ_setAttr_GenCryptgrm OBJ_setAttr_IssCap_CVM,1L + +#define SN_setAttr_T2Enc "setAttr-T2Enc" +#define LN_setAttr_T2Enc "encrypted track 2" +#define NID_setAttr_T2Enc 632 +#define OBJ_setAttr_T2Enc OBJ_setAttr_IssCap_T2,1L + +#define SN_setAttr_T2cleartxt "setAttr-T2cleartxt" +#define LN_setAttr_T2cleartxt "cleartext track 2" +#define NID_setAttr_T2cleartxt 633 +#define OBJ_setAttr_T2cleartxt OBJ_setAttr_IssCap_T2,2L + +#define SN_setAttr_TokICCsig "setAttr-TokICCsig" +#define LN_setAttr_TokICCsig "ICC or token signature" +#define NID_setAttr_TokICCsig 634 +#define OBJ_setAttr_TokICCsig OBJ_setAttr_IssCap_Sig,1L + +#define SN_setAttr_SecDevSig "setAttr-SecDevSig" +#define LN_setAttr_SecDevSig "secure device signature" +#define NID_setAttr_SecDevSig 635 +#define OBJ_setAttr_SecDevSig OBJ_setAttr_IssCap_Sig,2L + +#define SN_set_brand_IATA_ATA "set-brand-IATA-ATA" +#define NID_set_brand_IATA_ATA 636 +#define OBJ_set_brand_IATA_ATA OBJ_set_brand,1L + +#define SN_set_brand_Diners "set-brand-Diners" +#define NID_set_brand_Diners 637 +#define OBJ_set_brand_Diners OBJ_set_brand,30L + +#define SN_set_brand_AmericanExpress "set-brand-AmericanExpress" +#define NID_set_brand_AmericanExpress 638 +#define OBJ_set_brand_AmericanExpress OBJ_set_brand,34L + +#define SN_set_brand_JCB "set-brand-JCB" +#define NID_set_brand_JCB 639 +#define OBJ_set_brand_JCB OBJ_set_brand,35L + +#define SN_set_brand_Visa "set-brand-Visa" +#define NID_set_brand_Visa 640 +#define OBJ_set_brand_Visa OBJ_set_brand,4L + +#define SN_set_brand_MasterCard "set-brand-MasterCard" +#define NID_set_brand_MasterCard 641 +#define OBJ_set_brand_MasterCard OBJ_set_brand,5L + +#define SN_set_brand_Novus "set-brand-Novus" +#define NID_set_brand_Novus 642 +#define OBJ_set_brand_Novus OBJ_set_brand,6011L + +#define SN_des_cdmf "DES-CDMF" +#define LN_des_cdmf "des-cdmf" +#define NID_des_cdmf 643 +#define OBJ_des_cdmf OBJ_rsadsi,3L,10L + +#define SN_rsaOAEPEncryptionSET "rsaOAEPEncryptionSET" +#define NID_rsaOAEPEncryptionSET 644 +#define OBJ_rsaOAEPEncryptionSET OBJ_rsadsi,1L,1L,6L + +#define SN_ipsec3 "Oakley-EC2N-3" +#define LN_ipsec3 "ipsec3" +#define NID_ipsec3 749 + +#define SN_ipsec4 "Oakley-EC2N-4" +#define LN_ipsec4 "ipsec4" +#define NID_ipsec4 750 + +#define SN_whirlpool "whirlpool" +#define NID_whirlpool 804 +#define OBJ_whirlpool OBJ_iso,0L,10118L,3L,0L,55L + +#define SN_cryptopro "cryptopro" +#define NID_cryptopro 805 +#define OBJ_cryptopro OBJ_member_body,643L,2L,2L + +#define SN_cryptocom "cryptocom" +#define NID_cryptocom 806 +#define OBJ_cryptocom OBJ_member_body,643L,2L,9L + +#define SN_id_GostR3411_94_with_GostR3410_2001 "id-GostR3411-94-with-GostR3410-2001" +#define LN_id_GostR3411_94_with_GostR3410_2001 "GOST R 34.11-94 with GOST R 34.10-2001" +#define NID_id_GostR3411_94_with_GostR3410_2001 807 +#define OBJ_id_GostR3411_94_with_GostR3410_2001 OBJ_cryptopro,3L + +#define SN_id_GostR3411_94_with_GostR3410_94 "id-GostR3411-94-with-GostR3410-94" +#define LN_id_GostR3411_94_with_GostR3410_94 "GOST R 34.11-94 with GOST R 34.10-94" +#define NID_id_GostR3411_94_with_GostR3410_94 808 +#define OBJ_id_GostR3411_94_with_GostR3410_94 OBJ_cryptopro,4L + +#define SN_id_GostR3411_94 "md_gost94" +#define LN_id_GostR3411_94 "GOST R 34.11-94" +#define NID_id_GostR3411_94 809 +#define OBJ_id_GostR3411_94 OBJ_cryptopro,9L + +#define SN_id_HMACGostR3411_94 "id-HMACGostR3411-94" +#define LN_id_HMACGostR3411_94 "HMAC GOST 34.11-94" +#define NID_id_HMACGostR3411_94 810 +#define OBJ_id_HMACGostR3411_94 OBJ_cryptopro,10L + +#define SN_id_GostR3410_2001 "gost2001" +#define LN_id_GostR3410_2001 "GOST R 34.10-2001" +#define NID_id_GostR3410_2001 811 +#define OBJ_id_GostR3410_2001 OBJ_cryptopro,19L + +#define SN_id_GostR3410_94 "gost94" +#define LN_id_GostR3410_94 "GOST R 34.10-94" +#define NID_id_GostR3410_94 812 +#define OBJ_id_GostR3410_94 OBJ_cryptopro,20L + +#define SN_id_Gost28147_89 "gost89" +#define LN_id_Gost28147_89 "GOST 28147-89" +#define NID_id_Gost28147_89 813 +#define OBJ_id_Gost28147_89 OBJ_cryptopro,21L + +#define SN_gost89_cnt "gost89-cnt" +#define NID_gost89_cnt 814 + +#define SN_id_Gost28147_89_MAC "gost-mac" +#define LN_id_Gost28147_89_MAC "GOST 28147-89 MAC" +#define NID_id_Gost28147_89_MAC 815 +#define OBJ_id_Gost28147_89_MAC OBJ_cryptopro,22L + +#define SN_id_GostR3411_94_prf "prf-gostr3411-94" +#define LN_id_GostR3411_94_prf "GOST R 34.11-94 PRF" +#define NID_id_GostR3411_94_prf 816 +#define OBJ_id_GostR3411_94_prf OBJ_cryptopro,23L + +#define SN_id_GostR3410_2001DH "id-GostR3410-2001DH" +#define LN_id_GostR3410_2001DH "GOST R 34.10-2001 DH" +#define NID_id_GostR3410_2001DH 817 +#define OBJ_id_GostR3410_2001DH OBJ_cryptopro,98L + +#define SN_id_GostR3410_94DH "id-GostR3410-94DH" +#define LN_id_GostR3410_94DH "GOST R 34.10-94 DH" +#define NID_id_GostR3410_94DH 818 +#define OBJ_id_GostR3410_94DH OBJ_cryptopro,99L + +#define SN_id_Gost28147_89_CryptoPro_KeyMeshing "id-Gost28147-89-CryptoPro-KeyMeshing" +#define NID_id_Gost28147_89_CryptoPro_KeyMeshing 819 +#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing OBJ_cryptopro,14L,1L + +#define SN_id_Gost28147_89_None_KeyMeshing "id-Gost28147-89-None-KeyMeshing" +#define NID_id_Gost28147_89_None_KeyMeshing 820 +#define OBJ_id_Gost28147_89_None_KeyMeshing OBJ_cryptopro,14L,0L + +#define SN_id_GostR3411_94_TestParamSet "id-GostR3411-94-TestParamSet" +#define NID_id_GostR3411_94_TestParamSet 821 +#define OBJ_id_GostR3411_94_TestParamSet OBJ_cryptopro,30L,0L + +#define SN_id_GostR3411_94_CryptoProParamSet "id-GostR3411-94-CryptoProParamSet" +#define NID_id_GostR3411_94_CryptoProParamSet 822 +#define OBJ_id_GostR3411_94_CryptoProParamSet OBJ_cryptopro,30L,1L + +#define SN_id_Gost28147_89_TestParamSet "id-Gost28147-89-TestParamSet" +#define NID_id_Gost28147_89_TestParamSet 823 +#define OBJ_id_Gost28147_89_TestParamSet OBJ_cryptopro,31L,0L + +#define SN_id_Gost28147_89_CryptoPro_A_ParamSet "id-Gost28147-89-CryptoPro-A-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_A_ParamSet 824 +#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet OBJ_cryptopro,31L,1L + +#define SN_id_Gost28147_89_CryptoPro_B_ParamSet "id-Gost28147-89-CryptoPro-B-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_B_ParamSet 825 +#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet OBJ_cryptopro,31L,2L + +#define SN_id_Gost28147_89_CryptoPro_C_ParamSet "id-Gost28147-89-CryptoPro-C-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_C_ParamSet 826 +#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet OBJ_cryptopro,31L,3L + +#define SN_id_Gost28147_89_CryptoPro_D_ParamSet "id-Gost28147-89-CryptoPro-D-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_D_ParamSet 827 +#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet OBJ_cryptopro,31L,4L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 828 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet OBJ_cryptopro,31L,5L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 829 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet OBJ_cryptopro,31L,6L + +#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 830 +#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet OBJ_cryptopro,31L,7L + +#define SN_id_GostR3410_94_TestParamSet "id-GostR3410-94-TestParamSet" +#define NID_id_GostR3410_94_TestParamSet 831 +#define OBJ_id_GostR3410_94_TestParamSet OBJ_cryptopro,32L,0L + +#define SN_id_GostR3410_94_CryptoPro_A_ParamSet "id-GostR3410-94-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_A_ParamSet 832 +#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet OBJ_cryptopro,32L,2L + +#define SN_id_GostR3410_94_CryptoPro_B_ParamSet "id-GostR3410-94-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_B_ParamSet 833 +#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet OBJ_cryptopro,32L,3L + +#define SN_id_GostR3410_94_CryptoPro_C_ParamSet "id-GostR3410-94-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_C_ParamSet 834 +#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet OBJ_cryptopro,32L,4L + +#define SN_id_GostR3410_94_CryptoPro_D_ParamSet "id-GostR3410-94-CryptoPro-D-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_D_ParamSet 835 +#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet OBJ_cryptopro,32L,5L + +#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet "id-GostR3410-94-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet 836 +#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet OBJ_cryptopro,33L,1L + +#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet "id-GostR3410-94-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet 837 +#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet OBJ_cryptopro,33L,2L + +#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet "id-GostR3410-94-CryptoPro-XchC-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet 838 +#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet OBJ_cryptopro,33L,3L + +#define SN_id_GostR3410_2001_TestParamSet "id-GostR3410-2001-TestParamSet" +#define NID_id_GostR3410_2001_TestParamSet 839 +#define OBJ_id_GostR3410_2001_TestParamSet OBJ_cryptopro,35L,0L + +#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet "id-GostR3410-2001-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet 840 +#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet OBJ_cryptopro,35L,1L + +#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet "id-GostR3410-2001-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet 841 +#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet OBJ_cryptopro,35L,2L + +#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet "id-GostR3410-2001-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet 842 +#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet OBJ_cryptopro,35L,3L + +#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet "id-GostR3410-2001-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet 843 +#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet OBJ_cryptopro,36L,0L + +#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet "id-GostR3410-2001-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet 844 +#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet OBJ_cryptopro,36L,1L + +#define SN_id_GostR3410_94_a "id-GostR3410-94-a" +#define NID_id_GostR3410_94_a 845 +#define OBJ_id_GostR3410_94_a OBJ_id_GostR3410_94,1L + +#define SN_id_GostR3410_94_aBis "id-GostR3410-94-aBis" +#define NID_id_GostR3410_94_aBis 846 +#define OBJ_id_GostR3410_94_aBis OBJ_id_GostR3410_94,2L + +#define SN_id_GostR3410_94_b "id-GostR3410-94-b" +#define NID_id_GostR3410_94_b 847 +#define OBJ_id_GostR3410_94_b OBJ_id_GostR3410_94,3L + +#define SN_id_GostR3410_94_bBis "id-GostR3410-94-bBis" +#define NID_id_GostR3410_94_bBis 848 +#define OBJ_id_GostR3410_94_bBis OBJ_id_GostR3410_94,4L + +#define SN_id_Gost28147_89_cc "id-Gost28147-89-cc" +#define LN_id_Gost28147_89_cc "GOST 28147-89 Cryptocom ParamSet" +#define NID_id_Gost28147_89_cc 849 +#define OBJ_id_Gost28147_89_cc OBJ_cryptocom,1L,6L,1L + +#define SN_id_GostR3410_94_cc "gost94cc" +#define LN_id_GostR3410_94_cc "GOST 34.10-94 Cryptocom" +#define NID_id_GostR3410_94_cc 850 +#define OBJ_id_GostR3410_94_cc OBJ_cryptocom,1L,5L,3L + +#define SN_id_GostR3410_2001_cc "gost2001cc" +#define LN_id_GostR3410_2001_cc "GOST 34.10-2001 Cryptocom" +#define NID_id_GostR3410_2001_cc 851 +#define OBJ_id_GostR3410_2001_cc OBJ_cryptocom,1L,5L,4L + +#define SN_id_GostR3411_94_with_GostR3410_94_cc "id-GostR3411-94-with-GostR3410-94-cc" +#define LN_id_GostR3411_94_with_GostR3410_94_cc "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_94_cc 852 +#define OBJ_id_GostR3411_94_with_GostR3410_94_cc OBJ_cryptocom,1L,3L,3L + +#define SN_id_GostR3411_94_with_GostR3410_2001_cc "id-GostR3411-94-with-GostR3410-2001-cc" +#define LN_id_GostR3411_94_with_GostR3410_2001_cc "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_2001_cc 853 +#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc OBJ_cryptocom,1L,3L,4L + +#define SN_id_GostR3410_2001_ParamSet_cc "id-GostR3410-2001-ParamSet-cc" +#define LN_id_GostR3410_2001_ParamSet_cc "GOST R 3410-2001 Parameter Set Cryptocom" +#define NID_id_GostR3410_2001_ParamSet_cc 854 +#define OBJ_id_GostR3410_2001_ParamSet_cc OBJ_cryptocom,1L,8L,1L + +#define SN_camellia_128_cbc "CAMELLIA-128-CBC" +#define LN_camellia_128_cbc "camellia-128-cbc" +#define NID_camellia_128_cbc 751 +#define OBJ_camellia_128_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,2L + +#define SN_camellia_192_cbc "CAMELLIA-192-CBC" +#define LN_camellia_192_cbc "camellia-192-cbc" +#define NID_camellia_192_cbc 752 +#define OBJ_camellia_192_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,3L + +#define SN_camellia_256_cbc "CAMELLIA-256-CBC" +#define LN_camellia_256_cbc "camellia-256-cbc" +#define NID_camellia_256_cbc 753 +#define OBJ_camellia_256_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,4L + +#define OBJ_ntt_ds 0L,3L,4401L,5L + +#define OBJ_camellia OBJ_ntt_ds,3L,1L,9L + +#define SN_camellia_128_ecb "CAMELLIA-128-ECB" +#define LN_camellia_128_ecb "camellia-128-ecb" +#define NID_camellia_128_ecb 754 +#define OBJ_camellia_128_ecb OBJ_camellia,1L + +#define SN_camellia_128_ofb128 "CAMELLIA-128-OFB" +#define LN_camellia_128_ofb128 "camellia-128-ofb" +#define NID_camellia_128_ofb128 766 +#define OBJ_camellia_128_ofb128 OBJ_camellia,3L + +#define SN_camellia_128_cfb128 "CAMELLIA-128-CFB" +#define LN_camellia_128_cfb128 "camellia-128-cfb" +#define NID_camellia_128_cfb128 757 +#define OBJ_camellia_128_cfb128 OBJ_camellia,4L + +#define SN_camellia_192_ecb "CAMELLIA-192-ECB" +#define LN_camellia_192_ecb "camellia-192-ecb" +#define NID_camellia_192_ecb 755 +#define OBJ_camellia_192_ecb OBJ_camellia,21L + +#define SN_camellia_192_ofb128 "CAMELLIA-192-OFB" +#define LN_camellia_192_ofb128 "camellia-192-ofb" +#define NID_camellia_192_ofb128 767 +#define OBJ_camellia_192_ofb128 OBJ_camellia,23L + +#define SN_camellia_192_cfb128 "CAMELLIA-192-CFB" +#define LN_camellia_192_cfb128 "camellia-192-cfb" +#define NID_camellia_192_cfb128 758 +#define OBJ_camellia_192_cfb128 OBJ_camellia,24L + +#define SN_camellia_256_ecb "CAMELLIA-256-ECB" +#define LN_camellia_256_ecb "camellia-256-ecb" +#define NID_camellia_256_ecb 756 +#define OBJ_camellia_256_ecb OBJ_camellia,41L + +#define SN_camellia_256_ofb128 "CAMELLIA-256-OFB" +#define LN_camellia_256_ofb128 "camellia-256-ofb" +#define NID_camellia_256_ofb128 768 +#define OBJ_camellia_256_ofb128 OBJ_camellia,43L + +#define SN_camellia_256_cfb128 "CAMELLIA-256-CFB" +#define LN_camellia_256_cfb128 "camellia-256-cfb" +#define NID_camellia_256_cfb128 759 +#define OBJ_camellia_256_cfb128 OBJ_camellia,44L + +#define SN_camellia_128_cfb1 "CAMELLIA-128-CFB1" +#define LN_camellia_128_cfb1 "camellia-128-cfb1" +#define NID_camellia_128_cfb1 760 + +#define SN_camellia_192_cfb1 "CAMELLIA-192-CFB1" +#define LN_camellia_192_cfb1 "camellia-192-cfb1" +#define NID_camellia_192_cfb1 761 + +#define SN_camellia_256_cfb1 "CAMELLIA-256-CFB1" +#define LN_camellia_256_cfb1 "camellia-256-cfb1" +#define NID_camellia_256_cfb1 762 + +#define SN_camellia_128_cfb8 "CAMELLIA-128-CFB8" +#define LN_camellia_128_cfb8 "camellia-128-cfb8" +#define NID_camellia_128_cfb8 763 + +#define SN_camellia_192_cfb8 "CAMELLIA-192-CFB8" +#define LN_camellia_192_cfb8 "camellia-192-cfb8" +#define NID_camellia_192_cfb8 764 + +#define SN_camellia_256_cfb8 "CAMELLIA-256-CFB8" +#define LN_camellia_256_cfb8 "camellia-256-cfb8" +#define NID_camellia_256_cfb8 765 + +#define SN_kisa "KISA" +#define LN_kisa "kisa" +#define NID_kisa 773 +#define OBJ_kisa OBJ_member_body,410L,200004L + +#define SN_seed_ecb "SEED-ECB" +#define LN_seed_ecb "seed-ecb" +#define NID_seed_ecb 776 +#define OBJ_seed_ecb OBJ_kisa,1L,3L + +#define SN_seed_cbc "SEED-CBC" +#define LN_seed_cbc "seed-cbc" +#define NID_seed_cbc 777 +#define OBJ_seed_cbc OBJ_kisa,1L,4L + +#define SN_seed_cfb128 "SEED-CFB" +#define LN_seed_cfb128 "seed-cfb" +#define NID_seed_cfb128 779 +#define OBJ_seed_cfb128 OBJ_kisa,1L,5L + +#define SN_seed_ofb128 "SEED-OFB" +#define LN_seed_ofb128 "seed-ofb" +#define NID_seed_ofb128 778 +#define OBJ_seed_ofb128 OBJ_kisa,1L,6L + +#define SN_hmac "HMAC" +#define LN_hmac "hmac" +#define NID_hmac 855 + diff --git a/extra_lib/include/openssl/objects.h b/extra_lib/include/openssl/objects.h new file mode 100644 index 0000000..bd0ee52 --- /dev/null +++ b/extra_lib/include/openssl/objects.h @@ -0,0 +1,1138 @@ +/* crypto/objects/objects.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_OBJECTS_H +#define HEADER_OBJECTS_H + +#define USE_OBJ_MAC + +#ifdef USE_OBJ_MAC +#include +#else +#define SN_undef "UNDEF" +#define LN_undef "undefined" +#define NID_undef 0 +#define OBJ_undef 0L + +#define SN_Algorithm "Algorithm" +#define LN_algorithm "algorithm" +#define NID_algorithm 38 +#define OBJ_algorithm 1L,3L,14L,3L,2L + +#define LN_rsadsi "rsadsi" +#define NID_rsadsi 1 +#define OBJ_rsadsi 1L,2L,840L,113549L + +#define LN_pkcs "pkcs" +#define NID_pkcs 2 +#define OBJ_pkcs OBJ_rsadsi,1L + +#define SN_md2 "MD2" +#define LN_md2 "md2" +#define NID_md2 3 +#define OBJ_md2 OBJ_rsadsi,2L,2L + +#define SN_md5 "MD5" +#define LN_md5 "md5" +#define NID_md5 4 +#define OBJ_md5 OBJ_rsadsi,2L,5L + +#define SN_rc4 "RC4" +#define LN_rc4 "rc4" +#define NID_rc4 5 +#define OBJ_rc4 OBJ_rsadsi,3L,4L + +#define LN_rsaEncryption "rsaEncryption" +#define NID_rsaEncryption 6 +#define OBJ_rsaEncryption OBJ_pkcs,1L,1L + +#define SN_md2WithRSAEncryption "RSA-MD2" +#define LN_md2WithRSAEncryption "md2WithRSAEncryption" +#define NID_md2WithRSAEncryption 7 +#define OBJ_md2WithRSAEncryption OBJ_pkcs,1L,2L + +#define SN_md5WithRSAEncryption "RSA-MD5" +#define LN_md5WithRSAEncryption "md5WithRSAEncryption" +#define NID_md5WithRSAEncryption 8 +#define OBJ_md5WithRSAEncryption OBJ_pkcs,1L,4L + +#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" +#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" +#define NID_pbeWithMD2AndDES_CBC 9 +#define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs,5L,1L + +#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" +#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" +#define NID_pbeWithMD5AndDES_CBC 10 +#define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs,5L,3L + +#define LN_X500 "X500" +#define NID_X500 11 +#define OBJ_X500 2L,5L + +#define LN_X509 "X509" +#define NID_X509 12 +#define OBJ_X509 OBJ_X500,4L + +#define SN_commonName "CN" +#define LN_commonName "commonName" +#define NID_commonName 13 +#define OBJ_commonName OBJ_X509,3L + +#define SN_countryName "C" +#define LN_countryName "countryName" +#define NID_countryName 14 +#define OBJ_countryName OBJ_X509,6L + +#define SN_localityName "L" +#define LN_localityName "localityName" +#define NID_localityName 15 +#define OBJ_localityName OBJ_X509,7L + +/* Postal Address? PA */ + +/* should be "ST" (rfc1327) but MS uses 'S' */ +#define SN_stateOrProvinceName "ST" +#define LN_stateOrProvinceName "stateOrProvinceName" +#define NID_stateOrProvinceName 16 +#define OBJ_stateOrProvinceName OBJ_X509,8L + +#define SN_organizationName "O" +#define LN_organizationName "organizationName" +#define NID_organizationName 17 +#define OBJ_organizationName OBJ_X509,10L + +#define SN_organizationalUnitName "OU" +#define LN_organizationalUnitName "organizationalUnitName" +#define NID_organizationalUnitName 18 +#define OBJ_organizationalUnitName OBJ_X509,11L + +#define SN_rsa "RSA" +#define LN_rsa "rsa" +#define NID_rsa 19 +#define OBJ_rsa OBJ_X500,8L,1L,1L + +#define LN_pkcs7 "pkcs7" +#define NID_pkcs7 20 +#define OBJ_pkcs7 OBJ_pkcs,7L + +#define LN_pkcs7_data "pkcs7-data" +#define NID_pkcs7_data 21 +#define OBJ_pkcs7_data OBJ_pkcs7,1L + +#define LN_pkcs7_signed "pkcs7-signedData" +#define NID_pkcs7_signed 22 +#define OBJ_pkcs7_signed OBJ_pkcs7,2L + +#define LN_pkcs7_enveloped "pkcs7-envelopedData" +#define NID_pkcs7_enveloped 23 +#define OBJ_pkcs7_enveloped OBJ_pkcs7,3L + +#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" +#define NID_pkcs7_signedAndEnveloped 24 +#define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L + +#define LN_pkcs7_digest "pkcs7-digestData" +#define NID_pkcs7_digest 25 +#define OBJ_pkcs7_digest OBJ_pkcs7,5L + +#define LN_pkcs7_encrypted "pkcs7-encryptedData" +#define NID_pkcs7_encrypted 26 +#define OBJ_pkcs7_encrypted OBJ_pkcs7,6L + +#define LN_pkcs3 "pkcs3" +#define NID_pkcs3 27 +#define OBJ_pkcs3 OBJ_pkcs,3L + +#define LN_dhKeyAgreement "dhKeyAgreement" +#define NID_dhKeyAgreement 28 +#define OBJ_dhKeyAgreement OBJ_pkcs3,1L + +#define SN_des_ecb "DES-ECB" +#define LN_des_ecb "des-ecb" +#define NID_des_ecb 29 +#define OBJ_des_ecb OBJ_algorithm,6L + +#define SN_des_cfb64 "DES-CFB" +#define LN_des_cfb64 "des-cfb" +#define NID_des_cfb64 30 +/* IV + num */ +#define OBJ_des_cfb64 OBJ_algorithm,9L + +#define SN_des_cbc "DES-CBC" +#define LN_des_cbc "des-cbc" +#define NID_des_cbc 31 +/* IV */ +#define OBJ_des_cbc OBJ_algorithm,7L + +#define SN_des_ede "DES-EDE" +#define LN_des_ede "des-ede" +#define NID_des_ede 32 +/* ?? */ +#define OBJ_des_ede OBJ_algorithm,17L + +#define SN_des_ede3 "DES-EDE3" +#define LN_des_ede3 "des-ede3" +#define NID_des_ede3 33 + +#define SN_idea_cbc "IDEA-CBC" +#define LN_idea_cbc "idea-cbc" +#define NID_idea_cbc 34 +#define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L + +#define SN_idea_cfb64 "IDEA-CFB" +#define LN_idea_cfb64 "idea-cfb" +#define NID_idea_cfb64 35 + +#define SN_idea_ecb "IDEA-ECB" +#define LN_idea_ecb "idea-ecb" +#define NID_idea_ecb 36 + +#define SN_rc2_cbc "RC2-CBC" +#define LN_rc2_cbc "rc2-cbc" +#define NID_rc2_cbc 37 +#define OBJ_rc2_cbc OBJ_rsadsi,3L,2L + +#define SN_rc2_ecb "RC2-ECB" +#define LN_rc2_ecb "rc2-ecb" +#define NID_rc2_ecb 38 + +#define SN_rc2_cfb64 "RC2-CFB" +#define LN_rc2_cfb64 "rc2-cfb" +#define NID_rc2_cfb64 39 + +#define SN_rc2_ofb64 "RC2-OFB" +#define LN_rc2_ofb64 "rc2-ofb" +#define NID_rc2_ofb64 40 + +#define SN_sha "SHA" +#define LN_sha "sha" +#define NID_sha 41 +#define OBJ_sha OBJ_algorithm,18L + +#define SN_shaWithRSAEncryption "RSA-SHA" +#define LN_shaWithRSAEncryption "shaWithRSAEncryption" +#define NID_shaWithRSAEncryption 42 +#define OBJ_shaWithRSAEncryption OBJ_algorithm,15L + +#define SN_des_ede_cbc "DES-EDE-CBC" +#define LN_des_ede_cbc "des-ede-cbc" +#define NID_des_ede_cbc 43 + +#define SN_des_ede3_cbc "DES-EDE3-CBC" +#define LN_des_ede3_cbc "des-ede3-cbc" +#define NID_des_ede3_cbc 44 +#define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L + +#define SN_des_ofb64 "DES-OFB" +#define LN_des_ofb64 "des-ofb" +#define NID_des_ofb64 45 +#define OBJ_des_ofb64 OBJ_algorithm,8L + +#define SN_idea_ofb64 "IDEA-OFB" +#define LN_idea_ofb64 "idea-ofb" +#define NID_idea_ofb64 46 + +#define LN_pkcs9 "pkcs9" +#define NID_pkcs9 47 +#define OBJ_pkcs9 OBJ_pkcs,9L + +#define SN_pkcs9_emailAddress "Email" +#define LN_pkcs9_emailAddress "emailAddress" +#define NID_pkcs9_emailAddress 48 +#define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L + +#define LN_pkcs9_unstructuredName "unstructuredName" +#define NID_pkcs9_unstructuredName 49 +#define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L + +#define LN_pkcs9_contentType "contentType" +#define NID_pkcs9_contentType 50 +#define OBJ_pkcs9_contentType OBJ_pkcs9,3L + +#define LN_pkcs9_messageDigest "messageDigest" +#define NID_pkcs9_messageDigest 51 +#define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L + +#define LN_pkcs9_signingTime "signingTime" +#define NID_pkcs9_signingTime 52 +#define OBJ_pkcs9_signingTime OBJ_pkcs9,5L + +#define LN_pkcs9_countersignature "countersignature" +#define NID_pkcs9_countersignature 53 +#define OBJ_pkcs9_countersignature OBJ_pkcs9,6L + +#define LN_pkcs9_challengePassword "challengePassword" +#define NID_pkcs9_challengePassword 54 +#define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L + +#define LN_pkcs9_unstructuredAddress "unstructuredAddress" +#define NID_pkcs9_unstructuredAddress 55 +#define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L + +#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" +#define NID_pkcs9_extCertAttributes 56 +#define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L + +#define SN_netscape "Netscape" +#define LN_netscape "Netscape Communications Corp." +#define NID_netscape 57 +#define OBJ_netscape 2L,16L,840L,1L,113730L + +#define SN_netscape_cert_extension "nsCertExt" +#define LN_netscape_cert_extension "Netscape Certificate Extension" +#define NID_netscape_cert_extension 58 +#define OBJ_netscape_cert_extension OBJ_netscape,1L + +#define SN_netscape_data_type "nsDataType" +#define LN_netscape_data_type "Netscape Data Type" +#define NID_netscape_data_type 59 +#define OBJ_netscape_data_type OBJ_netscape,2L + +#define SN_des_ede_cfb64 "DES-EDE-CFB" +#define LN_des_ede_cfb64 "des-ede-cfb" +#define NID_des_ede_cfb64 60 + +#define SN_des_ede3_cfb64 "DES-EDE3-CFB" +#define LN_des_ede3_cfb64 "des-ede3-cfb" +#define NID_des_ede3_cfb64 61 + +#define SN_des_ede_ofb64 "DES-EDE-OFB" +#define LN_des_ede_ofb64 "des-ede-ofb" +#define NID_des_ede_ofb64 62 + +#define SN_des_ede3_ofb64 "DES-EDE3-OFB" +#define LN_des_ede3_ofb64 "des-ede3-ofb" +#define NID_des_ede3_ofb64 63 + +/* I'm not sure about the object ID */ +#define SN_sha1 "SHA1" +#define LN_sha1 "sha1" +#define NID_sha1 64 +#define OBJ_sha1 OBJ_algorithm,26L +/* 28 Jun 1996 - eay */ +/* #define OBJ_sha1 1L,3L,14L,2L,26L,05L <- wrong */ + +#define SN_sha1WithRSAEncryption "RSA-SHA1" +#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" +#define NID_sha1WithRSAEncryption 65 +#define OBJ_sha1WithRSAEncryption OBJ_pkcs,1L,5L + +#define SN_dsaWithSHA "DSA-SHA" +#define LN_dsaWithSHA "dsaWithSHA" +#define NID_dsaWithSHA 66 +#define OBJ_dsaWithSHA OBJ_algorithm,13L + +#define SN_dsa_2 "DSA-old" +#define LN_dsa_2 "dsaEncryption-old" +#define NID_dsa_2 67 +#define OBJ_dsa_2 OBJ_algorithm,12L + +/* proposed by microsoft to RSA */ +#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" +#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" +#define NID_pbeWithSHA1AndRC2_CBC 68 +#define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs,5L,11L + +/* proposed by microsoft to RSA as pbeWithSHA1AndRC4: it is now + * defined explicitly in PKCS#5 v2.0 as id-PBKDF2 which is something + * completely different. + */ +#define LN_id_pbkdf2 "PBKDF2" +#define NID_id_pbkdf2 69 +#define OBJ_id_pbkdf2 OBJ_pkcs,5L,12L + +#define SN_dsaWithSHA1_2 "DSA-SHA1-old" +#define LN_dsaWithSHA1_2 "dsaWithSHA1-old" +#define NID_dsaWithSHA1_2 70 +/* Got this one from 'sdn706r20.pdf' which is actually an NSA document :-) */ +#define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L + +#define SN_netscape_cert_type "nsCertType" +#define LN_netscape_cert_type "Netscape Cert Type" +#define NID_netscape_cert_type 71 +#define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L + +#define SN_netscape_base_url "nsBaseUrl" +#define LN_netscape_base_url "Netscape Base Url" +#define NID_netscape_base_url 72 +#define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L + +#define SN_netscape_revocation_url "nsRevocationUrl" +#define LN_netscape_revocation_url "Netscape Revocation Url" +#define NID_netscape_revocation_url 73 +#define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L + +#define SN_netscape_ca_revocation_url "nsCaRevocationUrl" +#define LN_netscape_ca_revocation_url "Netscape CA Revocation Url" +#define NID_netscape_ca_revocation_url 74 +#define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L + +#define SN_netscape_renewal_url "nsRenewalUrl" +#define LN_netscape_renewal_url "Netscape Renewal Url" +#define NID_netscape_renewal_url 75 +#define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L + +#define SN_netscape_ca_policy_url "nsCaPolicyUrl" +#define LN_netscape_ca_policy_url "Netscape CA Policy Url" +#define NID_netscape_ca_policy_url 76 +#define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L + +#define SN_netscape_ssl_server_name "nsSslServerName" +#define LN_netscape_ssl_server_name "Netscape SSL Server Name" +#define NID_netscape_ssl_server_name 77 +#define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L + +#define SN_netscape_comment "nsComment" +#define LN_netscape_comment "Netscape Comment" +#define NID_netscape_comment 78 +#define OBJ_netscape_comment OBJ_netscape_cert_extension,13L + +#define SN_netscape_cert_sequence "nsCertSequence" +#define LN_netscape_cert_sequence "Netscape Certificate Sequence" +#define NID_netscape_cert_sequence 79 +#define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L + +#define SN_desx_cbc "DESX-CBC" +#define LN_desx_cbc "desx-cbc" +#define NID_desx_cbc 80 + +#define SN_id_ce "id-ce" +#define NID_id_ce 81 +#define OBJ_id_ce 2L,5L,29L + +#define SN_subject_key_identifier "subjectKeyIdentifier" +#define LN_subject_key_identifier "X509v3 Subject Key Identifier" +#define NID_subject_key_identifier 82 +#define OBJ_subject_key_identifier OBJ_id_ce,14L + +#define SN_key_usage "keyUsage" +#define LN_key_usage "X509v3 Key Usage" +#define NID_key_usage 83 +#define OBJ_key_usage OBJ_id_ce,15L + +#define SN_private_key_usage_period "privateKeyUsagePeriod" +#define LN_private_key_usage_period "X509v3 Private Key Usage Period" +#define NID_private_key_usage_period 84 +#define OBJ_private_key_usage_period OBJ_id_ce,16L + +#define SN_subject_alt_name "subjectAltName" +#define LN_subject_alt_name "X509v3 Subject Alternative Name" +#define NID_subject_alt_name 85 +#define OBJ_subject_alt_name OBJ_id_ce,17L + +#define SN_issuer_alt_name "issuerAltName" +#define LN_issuer_alt_name "X509v3 Issuer Alternative Name" +#define NID_issuer_alt_name 86 +#define OBJ_issuer_alt_name OBJ_id_ce,18L + +#define SN_basic_constraints "basicConstraints" +#define LN_basic_constraints "X509v3 Basic Constraints" +#define NID_basic_constraints 87 +#define OBJ_basic_constraints OBJ_id_ce,19L + +#define SN_crl_number "crlNumber" +#define LN_crl_number "X509v3 CRL Number" +#define NID_crl_number 88 +#define OBJ_crl_number OBJ_id_ce,20L + +#define SN_certificate_policies "certificatePolicies" +#define LN_certificate_policies "X509v3 Certificate Policies" +#define NID_certificate_policies 89 +#define OBJ_certificate_policies OBJ_id_ce,32L + +#define SN_authority_key_identifier "authorityKeyIdentifier" +#define LN_authority_key_identifier "X509v3 Authority Key Identifier" +#define NID_authority_key_identifier 90 +#define OBJ_authority_key_identifier OBJ_id_ce,35L + +#define SN_bf_cbc "BF-CBC" +#define LN_bf_cbc "bf-cbc" +#define NID_bf_cbc 91 +#define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L + +#define SN_bf_ecb "BF-ECB" +#define LN_bf_ecb "bf-ecb" +#define NID_bf_ecb 92 + +#define SN_bf_cfb64 "BF-CFB" +#define LN_bf_cfb64 "bf-cfb" +#define NID_bf_cfb64 93 + +#define SN_bf_ofb64 "BF-OFB" +#define LN_bf_ofb64 "bf-ofb" +#define NID_bf_ofb64 94 + +#define SN_mdc2 "MDC2" +#define LN_mdc2 "mdc2" +#define NID_mdc2 95 +#define OBJ_mdc2 2L,5L,8L,3L,101L +/* An alternative? 1L,3L,14L,3L,2L,19L */ + +#define SN_mdc2WithRSA "RSA-MDC2" +#define LN_mdc2WithRSA "mdc2withRSA" +#define NID_mdc2WithRSA 96 +#define OBJ_mdc2WithRSA 2L,5L,8L,3L,100L + +#define SN_rc4_40 "RC4-40" +#define LN_rc4_40 "rc4-40" +#define NID_rc4_40 97 + +#define SN_rc2_40_cbc "RC2-40-CBC" +#define LN_rc2_40_cbc "rc2-40-cbc" +#define NID_rc2_40_cbc 98 + +#define SN_givenName "G" +#define LN_givenName "givenName" +#define NID_givenName 99 +#define OBJ_givenName OBJ_X509,42L + +#define SN_surname "S" +#define LN_surname "surname" +#define NID_surname 100 +#define OBJ_surname OBJ_X509,4L + +#define SN_initials "I" +#define LN_initials "initials" +#define NID_initials 101 +#define OBJ_initials OBJ_X509,43L + +#define SN_uniqueIdentifier "UID" +#define LN_uniqueIdentifier "uniqueIdentifier" +#define NID_uniqueIdentifier 102 +#define OBJ_uniqueIdentifier OBJ_X509,45L + +#define SN_crl_distribution_points "crlDistributionPoints" +#define LN_crl_distribution_points "X509v3 CRL Distribution Points" +#define NID_crl_distribution_points 103 +#define OBJ_crl_distribution_points OBJ_id_ce,31L + +#define SN_md5WithRSA "RSA-NP-MD5" +#define LN_md5WithRSA "md5WithRSA" +#define NID_md5WithRSA 104 +#define OBJ_md5WithRSA OBJ_algorithm,3L + +#define SN_serialNumber "SN" +#define LN_serialNumber "serialNumber" +#define NID_serialNumber 105 +#define OBJ_serialNumber OBJ_X509,5L + +#define SN_title "T" +#define LN_title "title" +#define NID_title 106 +#define OBJ_title OBJ_X509,12L + +#define SN_description "D" +#define LN_description "description" +#define NID_description 107 +#define OBJ_description OBJ_X509,13L + +/* CAST5 is CAST-128, I'm just sticking with the documentation */ +#define SN_cast5_cbc "CAST5-CBC" +#define LN_cast5_cbc "cast5-cbc" +#define NID_cast5_cbc 108 +#define OBJ_cast5_cbc 1L,2L,840L,113533L,7L,66L,10L + +#define SN_cast5_ecb "CAST5-ECB" +#define LN_cast5_ecb "cast5-ecb" +#define NID_cast5_ecb 109 + +#define SN_cast5_cfb64 "CAST5-CFB" +#define LN_cast5_cfb64 "cast5-cfb" +#define NID_cast5_cfb64 110 + +#define SN_cast5_ofb64 "CAST5-OFB" +#define LN_cast5_ofb64 "cast5-ofb" +#define NID_cast5_ofb64 111 + +#define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC" +#define NID_pbeWithMD5AndCast5_CBC 112 +#define OBJ_pbeWithMD5AndCast5_CBC 1L,2L,840L,113533L,7L,66L,12L + +/* This is one sun will soon be using :-( + * id-dsa-with-sha1 ID ::= { + * iso(1) member-body(2) us(840) x9-57 (10040) x9cm(4) 3 } + */ +#define SN_dsaWithSHA1 "DSA-SHA1" +#define LN_dsaWithSHA1 "dsaWithSHA1" +#define NID_dsaWithSHA1 113 +#define OBJ_dsaWithSHA1 1L,2L,840L,10040L,4L,3L + +#define NID_md5_sha1 114 +#define SN_md5_sha1 "MD5-SHA1" +#define LN_md5_sha1 "md5-sha1" + +#define SN_sha1WithRSA "RSA-SHA1-2" +#define LN_sha1WithRSA "sha1WithRSA" +#define NID_sha1WithRSA 115 +#define OBJ_sha1WithRSA OBJ_algorithm,29L + +#define SN_dsa "DSA" +#define LN_dsa "dsaEncryption" +#define NID_dsa 116 +#define OBJ_dsa 1L,2L,840L,10040L,4L,1L + +#define SN_ripemd160 "RIPEMD160" +#define LN_ripemd160 "ripemd160" +#define NID_ripemd160 117 +#define OBJ_ripemd160 1L,3L,36L,3L,2L,1L + +/* The name should actually be rsaSignatureWithripemd160, but I'm going + * to continue using the convention I'm using with the other ciphers */ +#define SN_ripemd160WithRSA "RSA-RIPEMD160" +#define LN_ripemd160WithRSA "ripemd160WithRSA" +#define NID_ripemd160WithRSA 119 +#define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L + +/* Taken from rfc2040 + * RC5_CBC_Parameters ::= SEQUENCE { + * version INTEGER (v1_0(16)), + * rounds INTEGER (8..127), + * blockSizeInBits INTEGER (64, 128), + * iv OCTET STRING OPTIONAL + * } + */ +#define SN_rc5_cbc "RC5-CBC" +#define LN_rc5_cbc "rc5-cbc" +#define NID_rc5_cbc 120 +#define OBJ_rc5_cbc OBJ_rsadsi,3L,8L + +#define SN_rc5_ecb "RC5-ECB" +#define LN_rc5_ecb "rc5-ecb" +#define NID_rc5_ecb 121 + +#define SN_rc5_cfb64 "RC5-CFB" +#define LN_rc5_cfb64 "rc5-cfb" +#define NID_rc5_cfb64 122 + +#define SN_rc5_ofb64 "RC5-OFB" +#define LN_rc5_ofb64 "rc5-ofb" +#define NID_rc5_ofb64 123 + +#define SN_rle_compression "RLE" +#define LN_rle_compression "run length compression" +#define NID_rle_compression 124 +#define OBJ_rle_compression 1L,1L,1L,1L,666L,1L + +#define SN_zlib_compression "ZLIB" +#define LN_zlib_compression "zlib compression" +#define NID_zlib_compression 125 +#define OBJ_zlib_compression 1L,1L,1L,1L,666L,2L + +#define SN_ext_key_usage "extendedKeyUsage" +#define LN_ext_key_usage "X509v3 Extended Key Usage" +#define NID_ext_key_usage 126 +#define OBJ_ext_key_usage OBJ_id_ce,37 + +#define SN_id_pkix "PKIX" +#define NID_id_pkix 127 +#define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L + +#define SN_id_kp "id-kp" +#define NID_id_kp 128 +#define OBJ_id_kp OBJ_id_pkix,3L + +/* PKIX extended key usage OIDs */ + +#define SN_server_auth "serverAuth" +#define LN_server_auth "TLS Web Server Authentication" +#define NID_server_auth 129 +#define OBJ_server_auth OBJ_id_kp,1L + +#define SN_client_auth "clientAuth" +#define LN_client_auth "TLS Web Client Authentication" +#define NID_client_auth 130 +#define OBJ_client_auth OBJ_id_kp,2L + +#define SN_code_sign "codeSigning" +#define LN_code_sign "Code Signing" +#define NID_code_sign 131 +#define OBJ_code_sign OBJ_id_kp,3L + +#define SN_email_protect "emailProtection" +#define LN_email_protect "E-mail Protection" +#define NID_email_protect 132 +#define OBJ_email_protect OBJ_id_kp,4L + +#define SN_time_stamp "timeStamping" +#define LN_time_stamp "Time Stamping" +#define NID_time_stamp 133 +#define OBJ_time_stamp OBJ_id_kp,8L + +/* Additional extended key usage OIDs: Microsoft */ + +#define SN_ms_code_ind "msCodeInd" +#define LN_ms_code_ind "Microsoft Individual Code Signing" +#define NID_ms_code_ind 134 +#define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L + +#define SN_ms_code_com "msCodeCom" +#define LN_ms_code_com "Microsoft Commercial Code Signing" +#define NID_ms_code_com 135 +#define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L + +#define SN_ms_ctl_sign "msCTLSign" +#define LN_ms_ctl_sign "Microsoft Trust List Signing" +#define NID_ms_ctl_sign 136 +#define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L + +#define SN_ms_sgc "msSGC" +#define LN_ms_sgc "Microsoft Server Gated Crypto" +#define NID_ms_sgc 137 +#define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L + +#define SN_ms_efs "msEFS" +#define LN_ms_efs "Microsoft Encrypted File System" +#define NID_ms_efs 138 +#define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L + +/* Additional usage: Netscape */ + +#define SN_ns_sgc "nsSGC" +#define LN_ns_sgc "Netscape Server Gated Crypto" +#define NID_ns_sgc 139 +#define OBJ_ns_sgc OBJ_netscape,4L,1L + +#define SN_delta_crl "deltaCRL" +#define LN_delta_crl "X509v3 Delta CRL Indicator" +#define NID_delta_crl 140 +#define OBJ_delta_crl OBJ_id_ce,27L + +#define SN_crl_reason "CRLReason" +#define LN_crl_reason "CRL Reason Code" +#define NID_crl_reason 141 +#define OBJ_crl_reason OBJ_id_ce,21L + +#define SN_invalidity_date "invalidityDate" +#define LN_invalidity_date "Invalidity Date" +#define NID_invalidity_date 142 +#define OBJ_invalidity_date OBJ_id_ce,24L + +#define SN_sxnet "SXNetID" +#define LN_sxnet "Strong Extranet ID" +#define NID_sxnet 143 +#define OBJ_sxnet 1L,3L,101L,1L,4L,1L + +/* PKCS12 and related OBJECT IDENTIFIERS */ + +#define OBJ_pkcs12 OBJ_pkcs,12L +#define OBJ_pkcs12_pbeids OBJ_pkcs12, 1 + +#define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" +#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" +#define NID_pbe_WithSHA1And128BitRC4 144 +#define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids, 1L + +#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" +#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" +#define NID_pbe_WithSHA1And40BitRC4 145 +#define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids, 2L + +#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES" +#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146 +#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids, 3L + +#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES" +#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147 +#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids, 4L + +#define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128" +#define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC" +#define NID_pbe_WithSHA1And128BitRC2_CBC 148 +#define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids, 5L + +#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40" +#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC" +#define NID_pbe_WithSHA1And40BitRC2_CBC 149 +#define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids, 6L + +#define OBJ_pkcs12_Version1 OBJ_pkcs12, 10L + +#define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1, 1L + +#define LN_keyBag "keyBag" +#define NID_keyBag 150 +#define OBJ_keyBag OBJ_pkcs12_BagIds, 1L + +#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" +#define NID_pkcs8ShroudedKeyBag 151 +#define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds, 2L + +#define LN_certBag "certBag" +#define NID_certBag 152 +#define OBJ_certBag OBJ_pkcs12_BagIds, 3L + +#define LN_crlBag "crlBag" +#define NID_crlBag 153 +#define OBJ_crlBag OBJ_pkcs12_BagIds, 4L + +#define LN_secretBag "secretBag" +#define NID_secretBag 154 +#define OBJ_secretBag OBJ_pkcs12_BagIds, 5L + +#define LN_safeContentsBag "safeContentsBag" +#define NID_safeContentsBag 155 +#define OBJ_safeContentsBag OBJ_pkcs12_BagIds, 6L + +#define LN_friendlyName "friendlyName" +#define NID_friendlyName 156 +#define OBJ_friendlyName OBJ_pkcs9, 20L + +#define LN_localKeyID "localKeyID" +#define NID_localKeyID 157 +#define OBJ_localKeyID OBJ_pkcs9, 21L + +#define OBJ_certTypes OBJ_pkcs9, 22L + +#define LN_x509Certificate "x509Certificate" +#define NID_x509Certificate 158 +#define OBJ_x509Certificate OBJ_certTypes, 1L + +#define LN_sdsiCertificate "sdsiCertificate" +#define NID_sdsiCertificate 159 +#define OBJ_sdsiCertificate OBJ_certTypes, 2L + +#define OBJ_crlTypes OBJ_pkcs9, 23L + +#define LN_x509Crl "x509Crl" +#define NID_x509Crl 160 +#define OBJ_x509Crl OBJ_crlTypes, 1L + +/* PKCS#5 v2 OIDs */ + +#define LN_pbes2 "PBES2" +#define NID_pbes2 161 +#define OBJ_pbes2 OBJ_pkcs,5L,13L + +#define LN_pbmac1 "PBMAC1" +#define NID_pbmac1 162 +#define OBJ_pbmac1 OBJ_pkcs,5L,14L + +#define LN_hmacWithSHA1 "hmacWithSHA1" +#define NID_hmacWithSHA1 163 +#define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L + +/* Policy Qualifier Ids */ + +#define LN_id_qt_cps "Policy Qualifier CPS" +#define SN_id_qt_cps "id-qt-cps" +#define NID_id_qt_cps 164 +#define OBJ_id_qt_cps OBJ_id_pkix,2L,1L + +#define LN_id_qt_unotice "Policy Qualifier User Notice" +#define SN_id_qt_unotice "id-qt-unotice" +#define NID_id_qt_unotice 165 +#define OBJ_id_qt_unotice OBJ_id_pkix,2L,2L + +#define SN_rc2_64_cbc "RC2-64-CBC" +#define LN_rc2_64_cbc "rc2-64-cbc" +#define NID_rc2_64_cbc 166 + +#define SN_SMIMECapabilities "SMIME-CAPS" +#define LN_SMIMECapabilities "S/MIME Capabilities" +#define NID_SMIMECapabilities 167 +#define OBJ_SMIMECapabilities OBJ_pkcs9,15L + +#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" +#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" +#define NID_pbeWithMD2AndRC2_CBC 168 +#define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs,5L,4L + +#define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64" +#define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC" +#define NID_pbeWithMD5AndRC2_CBC 169 +#define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs,5L,6L + +#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" +#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" +#define NID_pbeWithSHA1AndDES_CBC 170 +#define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs,5L,10L + +/* Extension request OIDs */ + +#define LN_ms_ext_req "Microsoft Extension Request" +#define SN_ms_ext_req "msExtReq" +#define NID_ms_ext_req 171 +#define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L + +#define LN_ext_req "Extension Request" +#define SN_ext_req "extReq" +#define NID_ext_req 172 +#define OBJ_ext_req OBJ_pkcs9,14L + +#define SN_name "name" +#define LN_name "name" +#define NID_name 173 +#define OBJ_name OBJ_X509,41L + +#define SN_dnQualifier "dnQualifier" +#define LN_dnQualifier "dnQualifier" +#define NID_dnQualifier 174 +#define OBJ_dnQualifier OBJ_X509,46L + +#define SN_id_pe "id-pe" +#define NID_id_pe 175 +#define OBJ_id_pe OBJ_id_pkix,1L + +#define SN_id_ad "id-ad" +#define NID_id_ad 176 +#define OBJ_id_ad OBJ_id_pkix,48L + +#define SN_info_access "authorityInfoAccess" +#define LN_info_access "Authority Information Access" +#define NID_info_access 177 +#define OBJ_info_access OBJ_id_pe,1L + +#define SN_ad_OCSP "OCSP" +#define LN_ad_OCSP "OCSP" +#define NID_ad_OCSP 178 +#define OBJ_ad_OCSP OBJ_id_ad,1L + +#define SN_ad_ca_issuers "caIssuers" +#define LN_ad_ca_issuers "CA Issuers" +#define NID_ad_ca_issuers 179 +#define OBJ_ad_ca_issuers OBJ_id_ad,2L + +#define SN_OCSP_sign "OCSPSigning" +#define LN_OCSP_sign "OCSP Signing" +#define NID_OCSP_sign 180 +#define OBJ_OCSP_sign OBJ_id_kp,9L +#endif /* USE_OBJ_MAC */ + +#include +#include + +#define OBJ_NAME_TYPE_UNDEF 0x00 +#define OBJ_NAME_TYPE_MD_METH 0x01 +#define OBJ_NAME_TYPE_CIPHER_METH 0x02 +#define OBJ_NAME_TYPE_PKEY_METH 0x03 +#define OBJ_NAME_TYPE_COMP_METH 0x04 +#define OBJ_NAME_TYPE_NUM 0x05 + +#define OBJ_NAME_ALIAS 0x8000 + +#define OBJ_BSEARCH_VALUE_ON_NOMATCH 0x01 +#define OBJ_BSEARCH_FIRST_VALUE_ON_MATCH 0x02 + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct obj_name_st + { + int type; + int alias; + const char *name; + const char *data; + } OBJ_NAME; + +#define OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c) + + +int OBJ_NAME_init(void); +int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *), + int (*cmp_func)(const char *, const char *), + void (*free_func)(const char *, int, const char *)); +const char *OBJ_NAME_get(const char *name,int type); +int OBJ_NAME_add(const char *name,int type,const char *data); +int OBJ_NAME_remove(const char *name,int type); +void OBJ_NAME_cleanup(int type); /* -1 for everything */ +void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg), + void *arg); +void OBJ_NAME_do_all_sorted(int type,void (*fn)(const OBJ_NAME *,void *arg), + void *arg); + +ASN1_OBJECT * OBJ_dup(const ASN1_OBJECT *o); +ASN1_OBJECT * OBJ_nid2obj(int n); +const char * OBJ_nid2ln(int n); +const char * OBJ_nid2sn(int n); +int OBJ_obj2nid(const ASN1_OBJECT *o); +ASN1_OBJECT * OBJ_txt2obj(const char *s, int no_name); +int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name); +int OBJ_txt2nid(const char *s); +int OBJ_ln2nid(const char *s); +int OBJ_sn2nid(const char *s); +int OBJ_cmp(const ASN1_OBJECT *a,const ASN1_OBJECT *b); +const void * OBJ_bsearch_(const void *key,const void *base,int num,int size, + int (*cmp)(const void *, const void *)); +const void * OBJ_bsearch_ex_(const void *key,const void *base,int num, + int size, + int (*cmp)(const void *, const void *), + int flags); + +#define _DECLARE_OBJ_BSEARCH_CMP_FN(scope, type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *, const void *); \ + static int nm##_cmp(type1 const *, type2 const *); \ + scope type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) + +#define DECLARE_OBJ_BSEARCH_CMP_FN(type1, type2, cmp) \ + _DECLARE_OBJ_BSEARCH_CMP_FN(static, type1, type2, cmp) +#define DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ + type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) + +/* + * Unsolved problem: if a type is actually a pointer type, like + * nid_triple is, then its impossible to get a const where you need + * it. Consider: + * + * typedef int nid_triple[3]; + * const void *a_; + * const nid_triple const *a = a_; + * + * The assignement discards a const because what you really want is: + * + * const int const * const *a = a_; + * + * But if you do that, you lose the fact that a is an array of 3 ints, + * which breaks comparison functions. + * + * Thus we end up having to cast, sadly, or unpack the + * declarations. Or, as I finally did in this case, delcare nid_triple + * to be a struct, which it should have been in the first place. + * + * Ben, August 2008. + * + * Also, strictly speaking not all types need be const, but handling + * the non-constness means a lot of complication, and in practice + * comparison routines do always not touch their arguments. + */ + +#define IMPLEMENT_OBJ_BSEARCH_CMP_FN(type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ + { \ + type1 const *a = a_; \ + type2 const *b = b_; \ + return nm##_cmp(a,b); \ + } \ + static type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ + { \ + return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ + nm##_cmp_BSEARCH_CMP_FN); \ + } \ + extern void dummy_prototype(void) + +#define IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ + { \ + type1 const *a = a_; \ + type2 const *b = b_; \ + return nm##_cmp(a,b); \ + } \ + type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ + { \ + return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ + nm##_cmp_BSEARCH_CMP_FN); \ + } \ + extern void dummy_prototype(void) + +#define OBJ_bsearch(type1,key,type2,base,num,cmp) \ + ((type2 *)OBJ_bsearch_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ + num,sizeof(type2), \ + ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ + (void)CHECKED_PTR_OF(type2,cmp##_type_2), \ + cmp##_BSEARCH_CMP_FN))) + +#define OBJ_bsearch_ex(type1,key,type2,base,num,cmp,flags) \ + ((type2 *)OBJ_bsearch_ex_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ + num,sizeof(type2), \ + ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ + (void)type_2=CHECKED_PTR_OF(type2,cmp##_type_2), \ + cmp##_BSEARCH_CMP_FN)),flags) + +int OBJ_new_nid(int num); +int OBJ_add_object(const ASN1_OBJECT *obj); +int OBJ_create(const char *oid,const char *sn,const char *ln); +void OBJ_cleanup(void ); +int OBJ_create_objects(BIO *in); + +int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid); +int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid); +int OBJ_add_sigid(int signid, int dig_id, int pkey_id); +void OBJ_sigid_free(void); + +extern int obj_cleanup_defer; +void check_defer(int nid); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_OBJ_strings(void); + +/* Error codes for the OBJ functions. */ + +/* Function codes. */ +#define OBJ_F_OBJ_ADD_OBJECT 105 +#define OBJ_F_OBJ_CREATE 100 +#define OBJ_F_OBJ_DUP 101 +#define OBJ_F_OBJ_NAME_NEW_INDEX 106 +#define OBJ_F_OBJ_NID2LN 102 +#define OBJ_F_OBJ_NID2OBJ 103 +#define OBJ_F_OBJ_NID2SN 104 + +/* Reason codes. */ +#define OBJ_R_MALLOC_FAILURE 100 +#define OBJ_R_UNKNOWN_NID 101 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/opensslconf.h b/extra_lib/include/openssl/opensslconf.h new file mode 100644 index 0000000..8268e9a --- /dev/null +++ b/extra_lib/include/openssl/opensslconf.h @@ -0,0 +1,223 @@ +/* opensslconf.h */ +/* WARNING: Generated automatically from opensslconf.h.in by Configure. */ + +/* OpenSSL was configured with the following options: */ +#ifndef OPENSSL_SYSNAME_WIN32 +# define OPENSSL_SYSNAME_WIN32 +#endif +#ifndef OPENSSL_DOING_MAKEDEPEND + + +#ifndef OPENSSL_NO_GMP +# define OPENSSL_NO_GMP +#endif +#ifndef OPENSSL_NO_JPAKE +# define OPENSSL_NO_JPAKE +#endif +#ifndef OPENSSL_NO_KRB5 +# define OPENSSL_NO_KRB5 +#endif +#ifndef OPENSSL_NO_MD2 +# define OPENSSL_NO_MD2 +#endif +#ifndef OPENSSL_NO_RC5 +# define OPENSSL_NO_RC5 +#endif +#ifndef OPENSSL_NO_RFC3779 +# define OPENSSL_NO_RFC3779 +#endif +#ifndef OPENSSL_NO_STORE +# define OPENSSL_NO_STORE +#endif + +#endif /* OPENSSL_DOING_MAKEDEPEND */ + +#ifndef OPENSSL_THREADS +# define OPENSSL_THREADS +#endif + +/* The OPENSSL_NO_* macros are also defined as NO_* if the application + asks for it. This is a transient feature that is provided for those + who haven't had the time to do the appropriate changes in their + applications. */ +#ifdef OPENSSL_ALGORITHM_DEFINES +# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP) +# define NO_GMP +# endif +# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE) +# define NO_JPAKE +# endif +# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5) +# define NO_KRB5 +# endif +# if defined(OPENSSL_NO_MD2) && !defined(NO_MD2) +# define NO_MD2 +# endif +# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5) +# define NO_RC5 +# endif +# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779) +# define NO_RFC3779 +# endif +# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE) +# define NO_STORE +# endif +#endif + +#define OPENSSL_CPUID_OBJ + +/* crypto/opensslconf.h.in */ + +/* Generate 80386 code? */ +#undef I386_ONLY + +#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */ +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define ENGINESDIR "c:cygwinhomeAdministrateurbuildslavefull-windows_xp_32buildgpac_extra_libs/lib/engines" +#define OPENSSLDIR "c:cygwinhomeAdministrateurbuildslavefull-windows_xp_32buildgpac_extra_libs/c:cygwinhomeAdministrateurbuildslavefull-windows_xp_32buildgpac_extra_libs/ssl" +#endif +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION +#define OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#undef RC4_CHUNK +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned long +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#define BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +#undef SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#define THIRTY_TWO_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#define RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#undef BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependancies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very mucy CPU dependant */ +#ifndef DES_UNROLL +#undef DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ diff --git a/extra_lib/include/openssl/opensslv.h b/extra_lib/include/openssl/opensslv.h new file mode 100644 index 0000000..e7fca83 --- /dev/null +++ b/extra_lib/include/openssl/opensslv.h @@ -0,0 +1,89 @@ +#ifndef HEADER_OPENSSLV_H +#define HEADER_OPENSSLV_H + +/* Numeric release version identifier: + * MNNFFPPS: major minor fix patch status + * The status nibble has one of the values 0 for development, 1 to e for betas + * 1 to 14, and f for release. The patch level is exactly that. + * For example: + * 0.9.3-dev 0x00903000 + * 0.9.3-beta1 0x00903001 + * 0.9.3-beta2-dev 0x00903002 + * 0.9.3-beta2 0x00903002 (same as ...beta2-dev) + * 0.9.3 0x0090300f + * 0.9.3a 0x0090301f + * 0.9.4 0x0090400f + * 1.2.3z 0x102031af + * + * For continuity reasons (because 0.9.5 is already out, and is coded + * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level + * part is slightly different, by setting the highest bit. This means + * that 0.9.5a looks like this: 0x0090581f. At 0.9.6, we can start + * with 0x0090600S... + * + * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.) + * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for + * major minor fix final patch/beta) + */ +#define OPENSSL_VERSION_NUMBER 0x1000004fL +#ifdef OPENSSL_FIPS +#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.0d-fips 8 Feb 2011" +#else +#define OPENSSL_VERSION_TEXT "OpenSSL 1.0.0d 8 Feb 2011" +#endif +#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT + + +/* The macros below are to be used for shared library (.so, .dll, ...) + * versioning. That kind of versioning works a bit differently between + * operating systems. The most usual scheme is to set a major and a minor + * number, and have the runtime loader check that the major number is equal + * to what it was at application link time, while the minor number has to + * be greater or equal to what it was at application link time. With this + * scheme, the version number is usually part of the file name, like this: + * + * libcrypto.so.0.9 + * + * Some unixen also make a softlink with the major verson number only: + * + * libcrypto.so.0 + * + * On Tru64 and IRIX 6.x it works a little bit differently. There, the + * shared library version is stored in the file, and is actually a series + * of versions, separated by colons. The rightmost version present in the + * library when linking an application is stored in the application to be + * matched at run time. When the application is run, a check is done to + * see if the library version stored in the application matches any of the + * versions in the version string of the library itself. + * This version string can be constructed in any way, depending on what + * kind of matching is desired. However, to implement the same scheme as + * the one used in the other unixen, all compatible versions, from lowest + * to highest, should be part of the string. Consecutive builds would + * give the following versions strings: + * + * 3.0 + * 3.0:3.1 + * 3.0:3.1:3.2 + * 4.0 + * 4.0:4.1 + * + * Notice how version 4 is completely incompatible with version, and + * therefore give the breach you can see. + * + * There may be other schemes as well that I haven't yet discovered. + * + * So, here's the way it works here: first of all, the library version + * number doesn't need at all to match the overall OpenSSL version. + * However, it's nice and more understandable if it actually does. + * The current library version is stored in the macro SHLIB_VERSION_NUMBER, + * which is just a piece of text in the format "M.m.e" (Major, minor, edit). + * For the sake of Tru64, IRIX, and any other OS that behaves in similar ways, + * we need to keep a history of version numbers, which is done in the + * macro SHLIB_VERSION_HISTORY. The numbers are separated by colons and + * should only keep the versions that are binary compatible with the current. + */ +#define SHLIB_VERSION_HISTORY "" +#define SHLIB_VERSION_NUMBER "1.0.0" + + +#endif /* HEADER_OPENSSLV_H */ diff --git a/extra_lib/include/openssl/ossl_typ.h b/extra_lib/include/openssl/ossl_typ.h new file mode 100644 index 0000000..12bd701 --- /dev/null +++ b/extra_lib/include/openssl/ossl_typ.h @@ -0,0 +1,200 @@ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_OPENSSL_TYPES_H +#define HEADER_OPENSSL_TYPES_H + +#include + +#ifdef NO_ASN1_TYPEDEFS +#define ASN1_INTEGER ASN1_STRING +#define ASN1_ENUMERATED ASN1_STRING +#define ASN1_BIT_STRING ASN1_STRING +#define ASN1_OCTET_STRING ASN1_STRING +#define ASN1_PRINTABLESTRING ASN1_STRING +#define ASN1_T61STRING ASN1_STRING +#define ASN1_IA5STRING ASN1_STRING +#define ASN1_UTCTIME ASN1_STRING +#define ASN1_GENERALIZEDTIME ASN1_STRING +#define ASN1_TIME ASN1_STRING +#define ASN1_GENERALSTRING ASN1_STRING +#define ASN1_UNIVERSALSTRING ASN1_STRING +#define ASN1_BMPSTRING ASN1_STRING +#define ASN1_VISIBLESTRING ASN1_STRING +#define ASN1_UTF8STRING ASN1_STRING +#define ASN1_BOOLEAN int +#define ASN1_NULL int +#else +typedef struct asn1_string_st ASN1_INTEGER; +typedef struct asn1_string_st ASN1_ENUMERATED; +typedef struct asn1_string_st ASN1_BIT_STRING; +typedef struct asn1_string_st ASN1_OCTET_STRING; +typedef struct asn1_string_st ASN1_PRINTABLESTRING; +typedef struct asn1_string_st ASN1_T61STRING; +typedef struct asn1_string_st ASN1_IA5STRING; +typedef struct asn1_string_st ASN1_GENERALSTRING; +typedef struct asn1_string_st ASN1_UNIVERSALSTRING; +typedef struct asn1_string_st ASN1_BMPSTRING; +typedef struct asn1_string_st ASN1_UTCTIME; +typedef struct asn1_string_st ASN1_TIME; +typedef struct asn1_string_st ASN1_GENERALIZEDTIME; +typedef struct asn1_string_st ASN1_VISIBLESTRING; +typedef struct asn1_string_st ASN1_UTF8STRING; +typedef int ASN1_BOOLEAN; +typedef int ASN1_NULL; +#endif + +typedef struct asn1_pctx_st ASN1_PCTX; + +#ifdef OPENSSL_SYS_WIN32 +#undef X509_NAME +#undef X509_EXTENSIONS +#undef X509_CERT_PAIR +#undef PKCS7_ISSUER_AND_SERIAL +#undef OCSP_REQUEST +#undef OCSP_RESPONSE +#endif + +#ifdef BIGNUM +#undef BIGNUM +#endif +typedef struct bignum_st BIGNUM; +typedef struct bignum_ctx BN_CTX; +typedef struct bn_blinding_st BN_BLINDING; +typedef struct bn_mont_ctx_st BN_MONT_CTX; +typedef struct bn_recp_ctx_st BN_RECP_CTX; +typedef struct bn_gencb_st BN_GENCB; + +typedef struct buf_mem_st BUF_MEM; + +typedef struct evp_cipher_st EVP_CIPHER; +typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX; +typedef struct env_md_st EVP_MD; +typedef struct env_md_ctx_st EVP_MD_CTX; +typedef struct evp_pkey_st EVP_PKEY; + +typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; + +typedef struct evp_pkey_method_st EVP_PKEY_METHOD; +typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; + +typedef struct dh_st DH; +typedef struct dh_method DH_METHOD; + +typedef struct dsa_st DSA; +typedef struct dsa_method DSA_METHOD; + +typedef struct rsa_st RSA; +typedef struct rsa_meth_st RSA_METHOD; + +typedef struct rand_meth_st RAND_METHOD; + +typedef struct ecdh_method ECDH_METHOD; +typedef struct ecdsa_method ECDSA_METHOD; + +typedef struct x509_st X509; +typedef struct X509_algor_st X509_ALGOR; +typedef struct X509_crl_st X509_CRL; +typedef struct x509_crl_method_st X509_CRL_METHOD; +typedef struct x509_revoked_st X509_REVOKED; +typedef struct X509_name_st X509_NAME; +typedef struct X509_pubkey_st X509_PUBKEY; +typedef struct x509_store_st X509_STORE; +typedef struct x509_store_ctx_st X509_STORE_CTX; + +typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO; + +typedef struct v3_ext_ctx X509V3_CTX; +typedef struct conf_st CONF; + +typedef struct store_st STORE; +typedef struct store_method_st STORE_METHOD; + +typedef struct ui_st UI; +typedef struct ui_method_st UI_METHOD; + +typedef struct st_ERR_FNS ERR_FNS; + +typedef struct engine_st ENGINE; +typedef struct ssl_st SSL; +typedef struct ssl_ctx_st SSL_CTX; + +typedef struct X509_POLICY_NODE_st X509_POLICY_NODE; +typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL; +typedef struct X509_POLICY_TREE_st X509_POLICY_TREE; +typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE; + +typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID; +typedef struct DIST_POINT_st DIST_POINT; +typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT; +typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS; + + /* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */ +#define DECLARE_PKCS12_STACK_OF(type) /* Nothing */ +#define IMPLEMENT_PKCS12_STACK_OF(type) /* Nothing */ + +typedef struct crypto_ex_data_st CRYPTO_EX_DATA; +/* Callback types for crypto.h */ +typedef int CRYPTO_EX_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d, + int idx, long argl, void *argp); + +typedef struct ocsp_req_ctx_st OCSP_REQ_CTX; +typedef struct ocsp_response_st OCSP_RESPONSE; +typedef struct ocsp_responder_id_st OCSP_RESPID; + +#endif /* def HEADER_OPENSSL_TYPES_H */ diff --git a/extra_lib/include/openssl/pem.h b/extra_lib/include/openssl/pem.h new file mode 100644 index 0000000..8a6abab --- /dev/null +++ b/extra_lib/include/openssl/pem.h @@ -0,0 +1,641 @@ +/* crypto/pem/pem.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_PEM_H +#define HEADER_PEM_H + +#include +#ifndef OPENSSL_NO_BIO +#include +#endif +#ifndef OPENSSL_NO_STACK +#include +#endif +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define PEM_BUFSIZE 1024 + +#define PEM_OBJ_UNDEF 0 +#define PEM_OBJ_X509 1 +#define PEM_OBJ_X509_REQ 2 +#define PEM_OBJ_CRL 3 +#define PEM_OBJ_SSL_SESSION 4 +#define PEM_OBJ_PRIV_KEY 10 +#define PEM_OBJ_PRIV_RSA 11 +#define PEM_OBJ_PRIV_DSA 12 +#define PEM_OBJ_PRIV_DH 13 +#define PEM_OBJ_PUB_RSA 14 +#define PEM_OBJ_PUB_DSA 15 +#define PEM_OBJ_PUB_DH 16 +#define PEM_OBJ_DHPARAMS 17 +#define PEM_OBJ_DSAPARAMS 18 +#define PEM_OBJ_PRIV_RSA_PUBLIC 19 +#define PEM_OBJ_PRIV_ECDSA 20 +#define PEM_OBJ_PUB_ECDSA 21 +#define PEM_OBJ_ECPARAMETERS 22 + +#define PEM_ERROR 30 +#define PEM_DEK_DES_CBC 40 +#define PEM_DEK_IDEA_CBC 45 +#define PEM_DEK_DES_EDE 50 +#define PEM_DEK_DES_ECB 60 +#define PEM_DEK_RSA 70 +#define PEM_DEK_RSA_MD2 80 +#define PEM_DEK_RSA_MD5 90 + +#define PEM_MD_MD2 NID_md2 +#define PEM_MD_MD5 NID_md5 +#define PEM_MD_SHA NID_sha +#define PEM_MD_MD2_RSA NID_md2WithRSAEncryption +#define PEM_MD_MD5_RSA NID_md5WithRSAEncryption +#define PEM_MD_SHA_RSA NID_sha1WithRSAEncryption + +#define PEM_STRING_X509_OLD "X509 CERTIFICATE" +#define PEM_STRING_X509 "CERTIFICATE" +#define PEM_STRING_X509_PAIR "CERTIFICATE PAIR" +#define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE" +#define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST" +#define PEM_STRING_X509_REQ "CERTIFICATE REQUEST" +#define PEM_STRING_X509_CRL "X509 CRL" +#define PEM_STRING_EVP_PKEY "ANY PRIVATE KEY" +#define PEM_STRING_PUBLIC "PUBLIC KEY" +#define PEM_STRING_RSA "RSA PRIVATE KEY" +#define PEM_STRING_RSA_PUBLIC "RSA PUBLIC KEY" +#define PEM_STRING_DSA "DSA PRIVATE KEY" +#define PEM_STRING_DSA_PUBLIC "DSA PUBLIC KEY" +#define PEM_STRING_PKCS7 "PKCS7" +#define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA" +#define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY" +#define PEM_STRING_PKCS8INF "PRIVATE KEY" +#define PEM_STRING_DHPARAMS "DH PARAMETERS" +#define PEM_STRING_SSL_SESSION "SSL SESSION PARAMETERS" +#define PEM_STRING_DSAPARAMS "DSA PARAMETERS" +#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY" +#define PEM_STRING_ECPARAMETERS "EC PARAMETERS" +#define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" +#define PEM_STRING_PARAMETERS "PARAMETERS" +#define PEM_STRING_CMS "CMS" + + /* Note that this structure is initialised by PEM_SealInit and cleaned up + by PEM_SealFinal (at least for now) */ +typedef struct PEM_Encode_Seal_st + { + EVP_ENCODE_CTX encode; + EVP_MD_CTX md; + EVP_CIPHER_CTX cipher; + } PEM_ENCODE_SEAL_CTX; + +/* enc_type is one off */ +#define PEM_TYPE_ENCRYPTED 10 +#define PEM_TYPE_MIC_ONLY 20 +#define PEM_TYPE_MIC_CLEAR 30 +#define PEM_TYPE_CLEAR 40 + +typedef struct pem_recip_st + { + char *name; + X509_NAME *dn; + + int cipher; + int key_enc; + /* char iv[8]; unused and wrong size */ + } PEM_USER; + +typedef struct pem_ctx_st + { + int type; /* what type of object */ + + struct { + int version; + int mode; + } proc_type; + + char *domain; + + struct { + int cipher; + /* unused, and wrong size + unsigned char iv[8]; */ + } DEK_info; + + PEM_USER *originator; + + int num_recipient; + PEM_USER **recipient; + + /* XXX(ben): don#t think this is used! + STACK *x509_chain; / * certificate chain */ + EVP_MD *md; /* signature type */ + + int md_enc; /* is the md encrypted or not? */ + int md_len; /* length of md_data */ + char *md_data; /* message digest, could be pkey encrypted */ + + EVP_CIPHER *dec; /* date encryption cipher */ + int key_len; /* key length */ + unsigned char *key; /* key */ + /* unused, and wrong size + unsigned char iv[8]; */ + + + int data_enc; /* is the data encrypted */ + int data_len; + unsigned char *data; + } PEM_CTX; + +/* These macros make the PEM_read/PEM_write functions easier to maintain and + * write. Now they are all implemented with either: + * IMPLEMENT_PEM_rw(...) or IMPLEMENT_PEM_rw_cb(...) + */ + +#ifdef OPENSSL_NO_FP_API + +#define IMPLEMENT_PEM_read_fp(name, type, str, asn1) /**/ +#define IMPLEMENT_PEM_write_fp(name, type, str, asn1) /**/ +#define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) /**/ +#define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) /**/ +#define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) /**/ + +#else + +#define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \ +type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \ +} + +#define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x) \ +{ \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \ +} + +#define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, const type *x) \ +{ \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \ +} + +#define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ + } + +#define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ + } + +#endif + +#define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ +type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \ +} + +#define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x) \ +{ \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \ +} + +#define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, const type *x) \ +{ \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \ +} + +#define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \ + } + +#define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \ + } + +#define IMPLEMENT_PEM_write(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp(name, type, str, asn1) + +#define IMPLEMENT_PEM_write_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) + +#define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) + +#define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) + +#define IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_read_fp(name, type, str, asn1) + +#define IMPLEMENT_PEM_rw(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write(name, type, str, asn1) + +#define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_const(name, type, str, asn1) + +#define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb(name, type, str, asn1) + +/* These are the same except they are for the declarations */ + +#if defined(OPENSSL_NO_FP_API) + +#define DECLARE_PEM_read_fp(name, type) /**/ +#define DECLARE_PEM_write_fp(name, type) /**/ +#define DECLARE_PEM_write_cb_fp(name, type) /**/ + +#else + +#define DECLARE_PEM_read_fp(name, type) \ + type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u); + +#define DECLARE_PEM_write_fp(name, type) \ + int PEM_write_##name(FILE *fp, type *x); + +#define DECLARE_PEM_write_fp_const(name, type) \ + int PEM_write_##name(FILE *fp, const type *x); + +#define DECLARE_PEM_write_cb_fp(name, type) \ + int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + +#endif + +#ifndef OPENSSL_NO_BIO +#define DECLARE_PEM_read_bio(name, type) \ + type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u); + +#define DECLARE_PEM_write_bio(name, type) \ + int PEM_write_bio_##name(BIO *bp, type *x); + +#define DECLARE_PEM_write_bio_const(name, type) \ + int PEM_write_bio_##name(BIO *bp, const type *x); + +#define DECLARE_PEM_write_cb_bio(name, type) \ + int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + +#else + +#define DECLARE_PEM_read_bio(name, type) /**/ +#define DECLARE_PEM_write_bio(name, type) /**/ +#define DECLARE_PEM_write_bio_const(name, type) /**/ +#define DECLARE_PEM_write_cb_bio(name, type) /**/ + +#endif + +#define DECLARE_PEM_write(name, type) \ + DECLARE_PEM_write_bio(name, type) \ + DECLARE_PEM_write_fp(name, type) + +#define DECLARE_PEM_write_const(name, type) \ + DECLARE_PEM_write_bio_const(name, type) \ + DECLARE_PEM_write_fp_const(name, type) + +#define DECLARE_PEM_write_cb(name, type) \ + DECLARE_PEM_write_cb_bio(name, type) \ + DECLARE_PEM_write_cb_fp(name, type) + +#define DECLARE_PEM_read(name, type) \ + DECLARE_PEM_read_bio(name, type) \ + DECLARE_PEM_read_fp(name, type) + +#define DECLARE_PEM_rw(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write(name, type) + +#define DECLARE_PEM_rw_const(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_const(name, type) + +#define DECLARE_PEM_rw_cb(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_cb(name, type) + +#if 1 +/* "userdata": new with OpenSSL 0.9.4 */ +typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata); +#else +/* OpenSSL 0.9.3, 0.9.3a */ +typedef int pem_password_cb(char *buf, int size, int rwflag); +#endif + +int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher); +int PEM_do_header (EVP_CIPHER_INFO *cipher, unsigned char *data,long *len, + pem_password_cb *callback,void *u); + +#ifndef OPENSSL_NO_BIO +int PEM_read_bio(BIO *bp, char **name, char **header, + unsigned char **data,long *len); +int PEM_write_bio(BIO *bp,const char *name,char *hdr,unsigned char *data, + long len); +int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp, + pem_password_cb *cb, void *u); +void * PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, + void **x, pem_password_cb *cb, void *u); +int PEM_ASN1_write_bio(i2d_of_void *i2d,const char *name,BIO *bp, void *x, + const EVP_CIPHER *enc,unsigned char *kstr,int klen, + pem_password_cb *cb, void *u); + +STACK_OF(X509_INFO) * PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); +int PEM_X509_INFO_write_bio(BIO *bp,X509_INFO *xi, EVP_CIPHER *enc, + unsigned char *kstr, int klen, pem_password_cb *cd, void *u); +#endif + +int PEM_read(FILE *fp, char **name, char **header, + unsigned char **data,long *len); +int PEM_write(FILE *fp,char *name,char *hdr,unsigned char *data,long len); +void * PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, + pem_password_cb *cb, void *u); +int PEM_ASN1_write(i2d_of_void *i2d,const char *name,FILE *fp, + void *x,const EVP_CIPHER *enc,unsigned char *kstr, + int klen,pem_password_cb *callback, void *u); +STACK_OF(X509_INFO) * PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u); + +int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, + EVP_MD *md_type, unsigned char **ek, int *ekl, + unsigned char *iv, EVP_PKEY **pubk, int npubk); +void PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl, + unsigned char *in, int inl); +int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig,int *sigl, + unsigned char *out, int *outl, EVP_PKEY *priv); + +void PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type); +void PEM_SignUpdate(EVP_MD_CTX *ctx,unsigned char *d,unsigned int cnt); +int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + unsigned int *siglen, EVP_PKEY *pkey); + +int PEM_def_callback(char *buf, int num, int w, void *key); +void PEM_proc_type(char *buf, int type); +void PEM_dek_info(char *buf, const char *type, int len, char *str); + + +#include + +DECLARE_PEM_rw(X509, X509) + +DECLARE_PEM_rw(X509_AUX, X509) + +DECLARE_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR) + +DECLARE_PEM_rw(X509_REQ, X509_REQ) +DECLARE_PEM_write(X509_REQ_NEW, X509_REQ) + +DECLARE_PEM_rw(X509_CRL, X509_CRL) + +DECLARE_PEM_rw(PKCS7, PKCS7) + +DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE) + +DECLARE_PEM_rw(PKCS8, X509_SIG) + +DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) + +#ifndef OPENSSL_NO_RSA + +DECLARE_PEM_rw_cb(RSAPrivateKey, RSA) + +DECLARE_PEM_rw_const(RSAPublicKey, RSA) +DECLARE_PEM_rw(RSA_PUBKEY, RSA) + +#endif + +#ifndef OPENSSL_NO_DSA + +DECLARE_PEM_rw_cb(DSAPrivateKey, DSA) + +DECLARE_PEM_rw(DSA_PUBKEY, DSA) + +DECLARE_PEM_rw_const(DSAparams, DSA) + +#endif + +#ifndef OPENSSL_NO_EC +DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP) +DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY) +DECLARE_PEM_rw(EC_PUBKEY, EC_KEY) +#endif + +#ifndef OPENSSL_NO_DH + +DECLARE_PEM_rw_const(DHparams, DH) + +#endif + +DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY) + +DECLARE_PEM_rw(PUBKEY, EVP_PKEY) + +int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *, + char *, int, pem_password_cb *, void *); +int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u); + +int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); + +EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u); + +int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc, + char *kstr,int klen, pem_password_cb *cd, void *u); + +EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x); +int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x); + + +EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PrivateKey_bio(BIO *in); +EVP_PKEY *b2i_PublicKey_bio(BIO *in); +int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk); +int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk); +#ifndef OPENSSL_NO_RC4 +EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u); +int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, + pem_password_cb *cb, void *u); +#endif + + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_PEM_strings(void); + +/* Error codes for the PEM functions. */ + +/* Function codes. */ +#define PEM_F_B2I_DSS 127 +#define PEM_F_B2I_PVK_BIO 128 +#define PEM_F_B2I_RSA 129 +#define PEM_F_CHECK_BITLEN_DSA 130 +#define PEM_F_CHECK_BITLEN_RSA 131 +#define PEM_F_D2I_PKCS8PRIVATEKEY_BIO 120 +#define PEM_F_D2I_PKCS8PRIVATEKEY_FP 121 +#define PEM_F_DO_B2I 132 +#define PEM_F_DO_B2I_BIO 133 +#define PEM_F_DO_BLOB_HEADER 134 +#define PEM_F_DO_PK8PKEY 126 +#define PEM_F_DO_PK8PKEY_FP 125 +#define PEM_F_DO_PVK_BODY 135 +#define PEM_F_DO_PVK_HEADER 136 +#define PEM_F_I2B_PVK 137 +#define PEM_F_I2B_PVK_BIO 138 +#define PEM_F_LOAD_IV 101 +#define PEM_F_PEM_ASN1_READ 102 +#define PEM_F_PEM_ASN1_READ_BIO 103 +#define PEM_F_PEM_ASN1_WRITE 104 +#define PEM_F_PEM_ASN1_WRITE_BIO 105 +#define PEM_F_PEM_DEF_CALLBACK 100 +#define PEM_F_PEM_DO_HEADER 106 +#define PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY 118 +#define PEM_F_PEM_GET_EVP_CIPHER_INFO 107 +#define PEM_F_PEM_PK8PKEY 119 +#define PEM_F_PEM_READ 108 +#define PEM_F_PEM_READ_BIO 109 +#define PEM_F_PEM_READ_BIO_PARAMETERS 140 +#define PEM_F_PEM_READ_BIO_PRIVATEKEY 123 +#define PEM_F_PEM_READ_PRIVATEKEY 124 +#define PEM_F_PEM_SEALFINAL 110 +#define PEM_F_PEM_SEALINIT 111 +#define PEM_F_PEM_SIGNFINAL 112 +#define PEM_F_PEM_WRITE 113 +#define PEM_F_PEM_WRITE_BIO 114 +#define PEM_F_PEM_WRITE_PRIVATEKEY 139 +#define PEM_F_PEM_X509_INFO_READ 115 +#define PEM_F_PEM_X509_INFO_READ_BIO 116 +#define PEM_F_PEM_X509_INFO_WRITE_BIO 117 + +/* Reason codes. */ +#define PEM_R_BAD_BASE64_DECODE 100 +#define PEM_R_BAD_DECRYPT 101 +#define PEM_R_BAD_END_LINE 102 +#define PEM_R_BAD_IV_CHARS 103 +#define PEM_R_BAD_MAGIC_NUMBER 116 +#define PEM_R_BAD_PASSWORD_READ 104 +#define PEM_R_BAD_VERSION_NUMBER 117 +#define PEM_R_BIO_WRITE_FAILURE 118 +#define PEM_R_CIPHER_IS_NULL 127 +#define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 115 +#define PEM_R_EXPECTING_PRIVATE_KEY_BLOB 119 +#define PEM_R_EXPECTING_PUBLIC_KEY_BLOB 120 +#define PEM_R_INCONSISTENT_HEADER 121 +#define PEM_R_KEYBLOB_HEADER_PARSE_ERROR 122 +#define PEM_R_KEYBLOB_TOO_SHORT 123 +#define PEM_R_NOT_DEK_INFO 105 +#define PEM_R_NOT_ENCRYPTED 106 +#define PEM_R_NOT_PROC_TYPE 107 +#define PEM_R_NO_START_LINE 108 +#define PEM_R_PROBLEMS_GETTING_PASSWORD 109 +#define PEM_R_PUBLIC_KEY_NO_RSA 110 +#define PEM_R_PVK_DATA_TOO_SHORT 124 +#define PEM_R_PVK_TOO_SHORT 125 +#define PEM_R_READ_KEY 111 +#define PEM_R_SHORT_HEADER 112 +#define PEM_R_UNSUPPORTED_CIPHER 113 +#define PEM_R_UNSUPPORTED_ENCRYPTION 114 +#define PEM_R_UNSUPPORTED_KEY_COMPONENTS 126 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/pem2.h b/extra_lib/include/openssl/pem2.h new file mode 100644 index 0000000..f31790d --- /dev/null +++ b/extra_lib/include/openssl/pem2.h @@ -0,0 +1,70 @@ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * This header only exists to break a circular dependency between pem and err + * Ben 30 Jan 1999. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HEADER_PEM_H +void ERR_load_PEM_strings(void); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/extra_lib/include/openssl/pkcs7.h b/extra_lib/include/openssl/pkcs7.h new file mode 100644 index 0000000..e4d4431 --- /dev/null +++ b/extra_lib/include/openssl/pkcs7.h @@ -0,0 +1,499 @@ +/* crypto/pkcs7/pkcs7.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_PKCS7_H +#define HEADER_PKCS7_H + +#include +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSSL_SYS_WIN32 +/* Under Win32 thes are defined in wincrypt.h */ +#undef PKCS7_ISSUER_AND_SERIAL +#undef PKCS7_SIGNER_INFO +#endif + +/* +Encryption_ID DES-CBC +Digest_ID MD5 +Digest_Encryption_ID rsaEncryption +Key_Encryption_ID rsaEncryption +*/ + +typedef struct pkcs7_issuer_and_serial_st + { + X509_NAME *issuer; + ASN1_INTEGER *serial; + } PKCS7_ISSUER_AND_SERIAL; + +typedef struct pkcs7_signer_info_st + { + ASN1_INTEGER *version; /* version 1 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *digest_alg; + STACK_OF(X509_ATTRIBUTE) *auth_attr; /* [ 0 ] */ + X509_ALGOR *digest_enc_alg; + ASN1_OCTET_STRING *enc_digest; + STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */ + + /* The private key to sign with */ + EVP_PKEY *pkey; + } PKCS7_SIGNER_INFO; + +DECLARE_STACK_OF(PKCS7_SIGNER_INFO) +DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO) + +typedef struct pkcs7_recip_info_st + { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *key_enc_algor; + ASN1_OCTET_STRING *enc_key; + X509 *cert; /* get the pub-key from this */ + } PKCS7_RECIP_INFO; + +DECLARE_STACK_OF(PKCS7_RECIP_INFO) +DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO) + +typedef struct pkcs7_signed_st + { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + + struct pkcs7_st *contents; + } PKCS7_SIGNED; +/* The above structure is very very similar to PKCS7_SIGN_ENVELOPE. + * How about merging the two */ + +typedef struct pkcs7_enc_content_st + { + ASN1_OBJECT *content_type; + X509_ALGOR *algorithm; + ASN1_OCTET_STRING *enc_data; /* [ 0 ] */ + const EVP_CIPHER *cipher; + } PKCS7_ENC_CONTENT; + +typedef struct pkcs7_enveloped_st + { + ASN1_INTEGER *version; /* version 0 */ + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; + PKCS7_ENC_CONTENT *enc_data; + } PKCS7_ENVELOPE; + +typedef struct pkcs7_signedandenveloped_st + { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + + PKCS7_ENC_CONTENT *enc_data; + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; + } PKCS7_SIGN_ENVELOPE; + +typedef struct pkcs7_digest_st + { + ASN1_INTEGER *version; /* version 0 */ + X509_ALGOR *md; /* md used */ + struct pkcs7_st *contents; + ASN1_OCTET_STRING *digest; + } PKCS7_DIGEST; + +typedef struct pkcs7_encrypted_st + { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ENC_CONTENT *enc_data; + } PKCS7_ENCRYPT; + +typedef struct pkcs7_st + { + /* The following is non NULL if it contains ASN1 encoding of + * this structure */ + unsigned char *asn1; + long length; + +#define PKCS7_S_HEADER 0 +#define PKCS7_S_BODY 1 +#define PKCS7_S_TAIL 2 + int state; /* used during processing */ + + int detached; + + ASN1_OBJECT *type; + /* content as defined by the type */ + /* all encryption/message digests are applied to the 'contents', + * leaving out the 'type' field. */ + union { + char *ptr; + + /* NID_pkcs7_data */ + ASN1_OCTET_STRING *data; + + /* NID_pkcs7_signed */ + PKCS7_SIGNED *sign; + + /* NID_pkcs7_enveloped */ + PKCS7_ENVELOPE *enveloped; + + /* NID_pkcs7_signedAndEnveloped */ + PKCS7_SIGN_ENVELOPE *signed_and_enveloped; + + /* NID_pkcs7_digest */ + PKCS7_DIGEST *digest; + + /* NID_pkcs7_encrypted */ + PKCS7_ENCRYPT *encrypted; + + /* Anything else */ + ASN1_TYPE *other; + } d; + } PKCS7; + +DECLARE_STACK_OF(PKCS7) +DECLARE_ASN1_SET_OF(PKCS7) +DECLARE_PKCS12_STACK_OF(PKCS7) + +#define PKCS7_OP_SET_DETACHED_SIGNATURE 1 +#define PKCS7_OP_GET_DETACHED_SIGNATURE 2 + +#define PKCS7_get_signed_attributes(si) ((si)->auth_attr) +#define PKCS7_get_attributes(si) ((si)->unauth_attr) + +#define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed) +#define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) +#define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped) +#define PKCS7_type_is_signedAndEnveloped(a) \ + (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped) +#define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data) +#define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest) +#define PKCS7_type_is_encrypted(a) \ + (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) + +#define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest) + +#define PKCS7_set_detached(p,v) \ + PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL) +#define PKCS7_get_detached(p) \ + PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL) + +#define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7)) + +/* S/MIME related flags */ + +#define PKCS7_TEXT 0x1 +#define PKCS7_NOCERTS 0x2 +#define PKCS7_NOSIGS 0x4 +#define PKCS7_NOCHAIN 0x8 +#define PKCS7_NOINTERN 0x10 +#define PKCS7_NOVERIFY 0x20 +#define PKCS7_DETACHED 0x40 +#define PKCS7_BINARY 0x80 +#define PKCS7_NOATTR 0x100 +#define PKCS7_NOSMIMECAP 0x200 +#define PKCS7_NOOLDMIMETYPE 0x400 +#define PKCS7_CRLFEOL 0x800 +#define PKCS7_STREAM 0x1000 +#define PKCS7_NOCRL 0x2000 +#define PKCS7_PARTIAL 0x4000 +#define PKCS7_REUSE_DIGEST 0x8000 + +/* Flags: for compatibility with older code */ + +#define SMIME_TEXT PKCS7_TEXT +#define SMIME_NOCERTS PKCS7_NOCERTS +#define SMIME_NOSIGS PKCS7_NOSIGS +#define SMIME_NOCHAIN PKCS7_NOCHAIN +#define SMIME_NOINTERN PKCS7_NOINTERN +#define SMIME_NOVERIFY PKCS7_NOVERIFY +#define SMIME_DETACHED PKCS7_DETACHED +#define SMIME_BINARY PKCS7_BINARY +#define SMIME_NOATTR PKCS7_NOATTR + +DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) + +int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,const EVP_MD *type, + unsigned char *md,unsigned int *len); +#ifndef OPENSSL_NO_FP_API +PKCS7 *d2i_PKCS7_fp(FILE *fp,PKCS7 **p7); +int i2d_PKCS7_fp(FILE *fp,PKCS7 *p7); +#endif +PKCS7 *PKCS7_dup(PKCS7 *p7); +PKCS7 *d2i_PKCS7_bio(BIO *bp,PKCS7 **p7); +int i2d_PKCS7_bio(BIO *bp,PKCS7 *p7); +int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); +int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); + +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE) +DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT) +DECLARE_ASN1_FUNCTIONS(PKCS7) + +DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN) +DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY) + +DECLARE_ASN1_NDEF_FUNCTION(PKCS7) +DECLARE_ASN1_PRINT_FUNCTION(PKCS7) + +long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg); + +int PKCS7_set_type(PKCS7 *p7, int type); +int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other); +int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data); +int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, + const EVP_MD *dgst); +int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si); +int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i); +int PKCS7_add_certificate(PKCS7 *p7, X509 *x509); +int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509); +int PKCS7_content_new(PKCS7 *p7, int nid); +int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, + BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, + X509 *x509); + +BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio); +int PKCS7_dataFinal(PKCS7 *p7, BIO *bio); +BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert); + + +PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, + EVP_PKEY *pkey, const EVP_MD *dgst); +X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md); +STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7); + +PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509); +void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, + X509_ALGOR **pdig, X509_ALGOR **psig); +void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc); +int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri); +int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509); +int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher); +int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7); + +PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx); +ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si,int nid,int type, + void *data); +int PKCS7_add_attribute (PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, + void *value); +ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid); +ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid); +int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,STACK_OF(X509_ATTRIBUTE) *sk); + + +PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, int flags); + +PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, + X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md, + int flags); + +int PKCS7_final(PKCS7 *p7, BIO *data, int flags); +int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, + BIO *indata, BIO *out, int flags); +STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags); +PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, + int flags); +int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags); + +int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, + STACK_OF(X509_ALGOR) *cap); +STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si); +int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg); + +int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid); +int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t); +int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, + const unsigned char *md, int mdlen); + +int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags); +PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont); + +BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7); + + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_PKCS7_strings(void); + +/* Error codes for the PKCS7 functions. */ + +/* Function codes. */ +#define PKCS7_F_B64_READ_PKCS7 120 +#define PKCS7_F_B64_WRITE_PKCS7 121 +#define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB 136 +#define PKCS7_F_I2D_PKCS7_BIO_STREAM 140 +#define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME 135 +#define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118 +#define PKCS7_F_PKCS7_ADD_CERTIFICATE 100 +#define PKCS7_F_PKCS7_ADD_CRL 101 +#define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102 +#define PKCS7_F_PKCS7_ADD_SIGNATURE 131 +#define PKCS7_F_PKCS7_ADD_SIGNER 103 +#define PKCS7_F_PKCS7_BIO_ADD_DIGEST 125 +#define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST 138 +#define PKCS7_F_PKCS7_CTRL 104 +#define PKCS7_F_PKCS7_DATADECODE 112 +#define PKCS7_F_PKCS7_DATAFINAL 128 +#define PKCS7_F_PKCS7_DATAINIT 105 +#define PKCS7_F_PKCS7_DATASIGN 106 +#define PKCS7_F_PKCS7_DATAVERIFY 107 +#define PKCS7_F_PKCS7_DECRYPT 114 +#define PKCS7_F_PKCS7_DECRYPT_RINFO 133 +#define PKCS7_F_PKCS7_ENCODE_RINFO 132 +#define PKCS7_F_PKCS7_ENCRYPT 115 +#define PKCS7_F_PKCS7_FINAL 134 +#define PKCS7_F_PKCS7_FIND_DIGEST 127 +#define PKCS7_F_PKCS7_GET0_SIGNERS 124 +#define PKCS7_F_PKCS7_RECIP_INFO_SET 130 +#define PKCS7_F_PKCS7_SET_CIPHER 108 +#define PKCS7_F_PKCS7_SET_CONTENT 109 +#define PKCS7_F_PKCS7_SET_DIGEST 126 +#define PKCS7_F_PKCS7_SET_TYPE 110 +#define PKCS7_F_PKCS7_SIGN 116 +#define PKCS7_F_PKCS7_SIGNATUREVERIFY 113 +#define PKCS7_F_PKCS7_SIGNER_INFO_SET 129 +#define PKCS7_F_PKCS7_SIGNER_INFO_SIGN 139 +#define PKCS7_F_PKCS7_SIGN_ADD_SIGNER 137 +#define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119 +#define PKCS7_F_PKCS7_VERIFY 117 +#define PKCS7_F_SMIME_READ_PKCS7 122 +#define PKCS7_F_SMIME_TEXT 123 + +/* Reason codes. */ +#define PKCS7_R_CERTIFICATE_VERIFY_ERROR 117 +#define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144 +#define PKCS7_R_CIPHER_NOT_INITIALIZED 116 +#define PKCS7_R_CONTENT_AND_DATA_PRESENT 118 +#define PKCS7_R_CTRL_ERROR 152 +#define PKCS7_R_DECODE_ERROR 130 +#define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100 +#define PKCS7_R_DECRYPT_ERROR 119 +#define PKCS7_R_DIGEST_FAILURE 101 +#define PKCS7_R_ENCRYPTION_CTRL_FAILURE 149 +#define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150 +#define PKCS7_R_ERROR_ADDING_RECIPIENT 120 +#define PKCS7_R_ERROR_SETTING_CIPHER 121 +#define PKCS7_R_INVALID_MIME_TYPE 131 +#define PKCS7_R_INVALID_NULL_POINTER 143 +#define PKCS7_R_MIME_NO_CONTENT_TYPE 132 +#define PKCS7_R_MIME_PARSE_ERROR 133 +#define PKCS7_R_MIME_SIG_PARSE_ERROR 134 +#define PKCS7_R_MISSING_CERIPEND_INFO 103 +#define PKCS7_R_NO_CONTENT 122 +#define PKCS7_R_NO_CONTENT_TYPE 135 +#define PKCS7_R_NO_DEFAULT_DIGEST 151 +#define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND 154 +#define PKCS7_R_NO_MULTIPART_BODY_FAILURE 136 +#define PKCS7_R_NO_MULTIPART_BOUNDARY 137 +#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115 +#define PKCS7_R_NO_RECIPIENT_MATCHES_KEY 146 +#define PKCS7_R_NO_SIGNATURES_ON_DATA 123 +#define PKCS7_R_NO_SIGNERS 142 +#define PKCS7_R_NO_SIG_CONTENT_TYPE 138 +#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104 +#define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124 +#define PKCS7_R_PKCS7_ADD_SIGNER_ERROR 153 +#define PKCS7_R_PKCS7_DATAFINAL 126 +#define PKCS7_R_PKCS7_DATAFINAL_ERROR 125 +#define PKCS7_R_PKCS7_DATASIGN 145 +#define PKCS7_R_PKCS7_PARSE_ERROR 139 +#define PKCS7_R_PKCS7_SIG_PARSE_ERROR 140 +#define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127 +#define PKCS7_R_SIGNATURE_FAILURE 105 +#define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128 +#define PKCS7_R_SIGNING_CTRL_FAILURE 147 +#define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 148 +#define PKCS7_R_SIG_INVALID_MIME_TYPE 141 +#define PKCS7_R_SMIME_TEXT_ERROR 129 +#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106 +#define PKCS7_R_UNABLE_TO_FIND_MEM_BIO 107 +#define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST 108 +#define PKCS7_R_UNKNOWN_DIGEST_TYPE 109 +#define PKCS7_R_UNKNOWN_OPERATION 110 +#define PKCS7_R_UNSUPPORTED_CIPHER_TYPE 111 +#define PKCS7_R_UNSUPPORTED_CONTENT_TYPE 112 +#define PKCS7_R_WRONG_CONTENT_TYPE 113 +#define PKCS7_R_WRONG_PKCS7_TYPE 114 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/pqueue.h b/extra_lib/include/openssl/pqueue.h new file mode 100644 index 0000000..87fc903 --- /dev/null +++ b/extra_lib/include/openssl/pqueue.h @@ -0,0 +1,94 @@ +/* crypto/pqueue/pqueue.h */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_PQUEUE_H +#define HEADER_PQUEUE_H + +#include +#include +#include + +typedef struct _pqueue *pqueue; + +typedef struct _pitem + { + unsigned char priority[8]; /* 64-bit value in big-endian encoding */ + void *data; + struct _pitem *next; + } pitem; + +typedef struct _pitem *piterator; + +pitem *pitem_new(unsigned char *prio64be, void *data); +void pitem_free(pitem *item); + +pqueue pqueue_new(void); +void pqueue_free(pqueue pq); + +pitem *pqueue_insert(pqueue pq, pitem *item); +pitem *pqueue_peek(pqueue pq); +pitem *pqueue_pop(pqueue pq); +pitem *pqueue_find(pqueue pq, unsigned char *prio64be); +pitem *pqueue_iterator(pqueue pq); +pitem *pqueue_next(piterator *iter); + +void pqueue_print(pqueue pq); +int pqueue_size(pqueue pq); + +#endif /* ! HEADER_PQUEUE_H */ diff --git a/extra_lib/include/openssl/rand.h b/extra_lib/include/openssl/rand.h new file mode 100644 index 0000000..ac6c021 --- /dev/null +++ b/extra_lib/include/openssl/rand.h @@ -0,0 +1,140 @@ +/* crypto/rand/rand.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RAND_H +#define HEADER_RAND_H + +#include +#include +#include + +#if defined(OPENSSL_SYS_WINDOWS) +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(OPENSSL_FIPS) +#define FIPS_RAND_SIZE_T size_t +#endif + +/* Already defined in ossl_typ.h */ +/* typedef struct rand_meth_st RAND_METHOD; */ + +struct rand_meth_st + { + void (*seed)(const void *buf, int num); + int (*bytes)(unsigned char *buf, int num); + void (*cleanup)(void); + void (*add)(const void *buf, int num, double entropy); + int (*pseudorand)(unsigned char *buf, int num); + int (*status)(void); + }; + +#ifdef BN_DEBUG +extern int rand_predictable; +#endif + +int RAND_set_rand_method(const RAND_METHOD *meth); +const RAND_METHOD *RAND_get_rand_method(void); +#ifndef OPENSSL_NO_ENGINE +int RAND_set_rand_engine(ENGINE *engine); +#endif +RAND_METHOD *RAND_SSLeay(void); +void RAND_cleanup(void ); +int RAND_bytes(unsigned char *buf,int num); +int RAND_pseudo_bytes(unsigned char *buf,int num); +void RAND_seed(const void *buf,int num); +void RAND_add(const void *buf,int num,double entropy); +int RAND_load_file(const char *file,long max_bytes); +int RAND_write_file(const char *file); +const char *RAND_file_name(char *file,size_t num); +int RAND_status(void); +int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes); +int RAND_egd(const char *path); +int RAND_egd_bytes(const char *path,int bytes); +int RAND_poll(void); + +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) + +void RAND_screen(void); +int RAND_event(UINT, WPARAM, LPARAM); + +#endif + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_RAND_strings(void); + +/* Error codes for the RAND functions. */ + +/* Function codes. */ +#define RAND_F_RAND_GET_RAND_METHOD 101 +#define RAND_F_SSLEAY_RAND_BYTES 100 + +/* Reason codes. */ +#define RAND_R_PRNG_NOT_SEEDED 100 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/rsa.h b/extra_lib/include/openssl/rsa.h new file mode 100644 index 0000000..cf74343 --- /dev/null +++ b/extra_lib/include/openssl/rsa.h @@ -0,0 +1,503 @@ +/* crypto/rsa/rsa.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RSA_H +#define HEADER_RSA_H + +#include + +#ifndef OPENSSL_NO_BIO +#include +#endif +#include +#include +#ifndef OPENSSL_NO_DEPRECATED +#include +#endif + +#ifdef OPENSSL_NO_RSA +#error RSA is disabled. +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Declared already in ossl_typ.h */ +/* typedef struct rsa_st RSA; */ +/* typedef struct rsa_meth_st RSA_METHOD; */ + +struct rsa_meth_st + { + const char *name; + int (*rsa_pub_enc)(int flen,const unsigned char *from, + unsigned char *to, + RSA *rsa,int padding); + int (*rsa_pub_dec)(int flen,const unsigned char *from, + unsigned char *to, + RSA *rsa,int padding); + int (*rsa_priv_enc)(int flen,const unsigned char *from, + unsigned char *to, + RSA *rsa,int padding); + int (*rsa_priv_dec)(int flen,const unsigned char *from, + unsigned char *to, + RSA *rsa,int padding); + int (*rsa_mod_exp)(BIGNUM *r0,const BIGNUM *I,RSA *rsa,BN_CTX *ctx); /* Can be null */ + int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); /* Can be null */ + int (*init)(RSA *rsa); /* called at new */ + int (*finish)(RSA *rsa); /* called at free */ + int flags; /* RSA_METHOD_FLAG_* things */ + char *app_data; /* may be needed! */ +/* New sign and verify functions: some libraries don't allow arbitrary data + * to be signed/verified: this allows them to be used. Note: for this to work + * the RSA_public_decrypt() and RSA_private_encrypt() should *NOT* be used + * RSA_sign(), RSA_verify() should be used instead. Note: for backwards + * compatibility this functionality is only enabled if the RSA_FLAG_SIGN_VER + * option is set in 'flags'. + */ + int (*rsa_sign)(int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, const RSA *rsa); + int (*rsa_verify)(int dtype, + const unsigned char *m, unsigned int m_length, + const unsigned char *sigbuf, unsigned int siglen, + const RSA *rsa); +/* If this callback is NULL, the builtin software RSA key-gen will be used. This + * is for behavioural compatibility whilst the code gets rewired, but one day + * it would be nice to assume there are no such things as "builtin software" + * implementations. */ + int (*rsa_keygen)(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); + }; + +struct rsa_st + { + /* The first parameter is used to pickup errors where + * this is passed instead of aEVP_PKEY, it is set to 0 */ + int pad; + long version; + const RSA_METHOD *meth; + /* functional reference if 'meth' is ENGINE-provided */ + ENGINE *engine; + BIGNUM *n; + BIGNUM *e; + BIGNUM *d; + BIGNUM *p; + BIGNUM *q; + BIGNUM *dmp1; + BIGNUM *dmq1; + BIGNUM *iqmp; + /* be careful using this if the RSA structure is shared */ + CRYPTO_EX_DATA ex_data; + int references; + int flags; + + /* Used to cache montgomery values */ + BN_MONT_CTX *_method_mod_n; + BN_MONT_CTX *_method_mod_p; + BN_MONT_CTX *_method_mod_q; + + /* all BIGNUM values are actually in the following data, if it is not + * NULL */ + char *bignum_data; + BN_BLINDING *blinding; + BN_BLINDING *mt_blinding; + }; + +#ifndef OPENSSL_RSA_MAX_MODULUS_BITS +# define OPENSSL_RSA_MAX_MODULUS_BITS 16384 +#endif + +#ifndef OPENSSL_RSA_SMALL_MODULUS_BITS +# define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 +#endif +#ifndef OPENSSL_RSA_MAX_PUBEXP_BITS +# define OPENSSL_RSA_MAX_PUBEXP_BITS 64 /* exponent limit enforced for "large" modulus only */ +#endif + +#define RSA_3 0x3L +#define RSA_F4 0x10001L + +#define RSA_METHOD_FLAG_NO_CHECK 0x0001 /* don't check pub/private match */ + +#define RSA_FLAG_CACHE_PUBLIC 0x0002 +#define RSA_FLAG_CACHE_PRIVATE 0x0004 +#define RSA_FLAG_BLINDING 0x0008 +#define RSA_FLAG_THREAD_SAFE 0x0010 +/* This flag means the private key operations will be handled by rsa_mod_exp + * and that they do not depend on the private key components being present: + * for example a key stored in external hardware. Without this flag bn_mod_exp + * gets called when private key components are absent. + */ +#define RSA_FLAG_EXT_PKEY 0x0020 + +/* This flag in the RSA_METHOD enables the new rsa_sign, rsa_verify functions. + */ +#define RSA_FLAG_SIGN_VER 0x0040 + +#define RSA_FLAG_NO_BLINDING 0x0080 /* new with 0.9.6j and 0.9.7b; the built-in + * RSA implementation now uses blinding by + * default (ignoring RSA_FLAG_BLINDING), + * but other engines might not need it + */ +#define RSA_FLAG_NO_CONSTTIME 0x0100 /* new with 0.9.8f; the built-in RSA + * implementation now uses constant time + * operations by default in private key operations, + * e.g., constant time modular exponentiation, + * modular inverse without leaking branches, + * division without leaking branches. This + * flag disables these constant time + * operations and results in faster RSA + * private key operations. + */ +#ifndef OPENSSL_NO_DEPRECATED +#define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME /* deprecated name for the flag*/ + /* new with 0.9.7h; the built-in RSA + * implementation now uses constant time + * modular exponentiation for secret exponents + * by default. This flag causes the + * faster variable sliding window method to + * be used for all exponents. + */ +#endif + + +#define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \ + pad, NULL) + +#define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \ + (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, \ + len, NULL) + +#define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL) + +#define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp) + +#define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1) +#define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 2) + +#define EVP_PKEY_CTRL_RSA_KEYGEN_BITS (EVP_PKEY_ALG_CTRL + 3) +#define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 4) + +#define RSA_PKCS1_PADDING 1 +#define RSA_SSLV23_PADDING 2 +#define RSA_NO_PADDING 3 +#define RSA_PKCS1_OAEP_PADDING 4 +#define RSA_X931_PADDING 5 +/* EVP_PKEY_ only */ +#define RSA_PKCS1_PSS_PADDING 6 + +#define RSA_PKCS1_PADDING_SIZE 11 + +#define RSA_set_app_data(s,arg) RSA_set_ex_data(s,0,arg) +#define RSA_get_app_data(s) RSA_get_ex_data(s,0) + +RSA * RSA_new(void); +RSA * RSA_new_method(ENGINE *engine); +int RSA_size(const RSA *); + +/* Deprecated version */ +#ifndef OPENSSL_NO_DEPRECATED +RSA * RSA_generate_key(int bits, unsigned long e,void + (*callback)(int,int,void *),void *cb_arg); +#endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* New version */ +int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); + +int RSA_check_key(const RSA *); + /* next 4 return -1 on error */ +int RSA_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa,int padding); +int RSA_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa,int padding); +int RSA_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa,int padding); +int RSA_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa,int padding); +void RSA_free (RSA *r); +/* "up" the RSA object's reference count */ +int RSA_up_ref(RSA *r); + +int RSA_flags(const RSA *r); + +void RSA_set_default_method(const RSA_METHOD *meth); +const RSA_METHOD *RSA_get_default_method(void); +const RSA_METHOD *RSA_get_method(const RSA *rsa); +int RSA_set_method(RSA *rsa, const RSA_METHOD *meth); + +/* This function needs the memory locking malloc callbacks to be installed */ +int RSA_memory_lock(RSA *r); + +/* these are the actual SSLeay RSA functions */ +const RSA_METHOD *RSA_PKCS1_SSLeay(void); + +const RSA_METHOD *RSA_null_method(void); + +DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey) + +#ifndef OPENSSL_NO_FP_API +int RSA_print_fp(FILE *fp, const RSA *r,int offset); +#endif + +#ifndef OPENSSL_NO_BIO +int RSA_print(BIO *bp, const RSA *r,int offset); +#endif + +#ifndef OPENSSL_NO_RC4 +int i2d_RSA_NET(const RSA *a, unsigned char **pp, + int (*cb)(char *buf, int len, const char *prompt, int verify), + int sgckey); +RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length, + int (*cb)(char *buf, int len, const char *prompt, int verify), + int sgckey); + +int i2d_Netscape_RSA(const RSA *a, unsigned char **pp, + int (*cb)(char *buf, int len, const char *prompt, + int verify)); +RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, + int (*cb)(char *buf, int len, const char *prompt, + int verify)); +#endif + +/* The following 2 functions sign and verify a X509_SIG ASN1 object + * inside PKCS#1 padded RSA encryption */ +int RSA_sign(int type, const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, RSA *rsa); +int RSA_verify(int type, const unsigned char *m, unsigned int m_length, + const unsigned char *sigbuf, unsigned int siglen, RSA *rsa); + +/* The following 2 function sign and verify a ASN1_OCTET_STRING + * object inside PKCS#1 padded RSA encryption */ +int RSA_sign_ASN1_OCTET_STRING(int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, RSA *rsa); +int RSA_verify_ASN1_OCTET_STRING(int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigbuf, unsigned int siglen, RSA *rsa); + +int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); +void RSA_blinding_off(RSA *rsa); +BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx); + +int RSA_padding_add_PKCS1_type_1(unsigned char *to,int tlen, + const unsigned char *f,int fl); +int RSA_padding_check_PKCS1_type_1(unsigned char *to,int tlen, + const unsigned char *f,int fl,int rsa_len); +int RSA_padding_add_PKCS1_type_2(unsigned char *to,int tlen, + const unsigned char *f,int fl); +int RSA_padding_check_PKCS1_type_2(unsigned char *to,int tlen, + const unsigned char *f,int fl,int rsa_len); +int PKCS1_MGF1(unsigned char *mask, long len, + const unsigned char *seed, long seedlen, const EVP_MD *dgst); +int RSA_padding_add_PKCS1_OAEP(unsigned char *to,int tlen, + const unsigned char *f,int fl, + const unsigned char *p,int pl); +int RSA_padding_check_PKCS1_OAEP(unsigned char *to,int tlen, + const unsigned char *f,int fl,int rsa_len, + const unsigned char *p,int pl); +int RSA_padding_add_SSLv23(unsigned char *to,int tlen, + const unsigned char *f,int fl); +int RSA_padding_check_SSLv23(unsigned char *to,int tlen, + const unsigned char *f,int fl,int rsa_len); +int RSA_padding_add_none(unsigned char *to,int tlen, + const unsigned char *f,int fl); +int RSA_padding_check_none(unsigned char *to,int tlen, + const unsigned char *f,int fl,int rsa_len); +int RSA_padding_add_X931(unsigned char *to,int tlen, + const unsigned char *f,int fl); +int RSA_padding_check_X931(unsigned char *to,int tlen, + const unsigned char *f,int fl,int rsa_len); +int RSA_X931_hash_id(int nid); + +int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const unsigned char *EM, int sLen); +int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, + const EVP_MD *Hash, int sLen); + +int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int RSA_set_ex_data(RSA *r,int idx,void *arg); +void *RSA_get_ex_data(const RSA *r, int idx); + +RSA *RSAPublicKey_dup(RSA *rsa); +RSA *RSAPrivateKey_dup(RSA *rsa); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_RSA_strings(void); + +/* Error codes for the RSA functions. */ + +/* Function codes. */ +#define RSA_F_CHECK_PADDING_MD 140 +#define RSA_F_DO_RSA_PRINT 146 +#define RSA_F_INT_RSA_VERIFY 145 +#define RSA_F_MEMORY_LOCK 100 +#define RSA_F_OLD_RSA_PRIV_DECODE 147 +#define RSA_F_PKEY_RSA_CTRL 143 +#define RSA_F_PKEY_RSA_CTRL_STR 144 +#define RSA_F_PKEY_RSA_SIGN 142 +#define RSA_F_PKEY_RSA_VERIFYRECOVER 141 +#define RSA_F_RSA_BUILTIN_KEYGEN 129 +#define RSA_F_RSA_CHECK_KEY 123 +#define RSA_F_RSA_EAY_PRIVATE_DECRYPT 101 +#define RSA_F_RSA_EAY_PRIVATE_ENCRYPT 102 +#define RSA_F_RSA_EAY_PUBLIC_DECRYPT 103 +#define RSA_F_RSA_EAY_PUBLIC_ENCRYPT 104 +#define RSA_F_RSA_GENERATE_KEY 105 +#define RSA_F_RSA_MEMORY_LOCK 130 +#define RSA_F_RSA_NEW_METHOD 106 +#define RSA_F_RSA_NULL 124 +#define RSA_F_RSA_NULL_MOD_EXP 131 +#define RSA_F_RSA_NULL_PRIVATE_DECRYPT 132 +#define RSA_F_RSA_NULL_PRIVATE_ENCRYPT 133 +#define RSA_F_RSA_NULL_PUBLIC_DECRYPT 134 +#define RSA_F_RSA_NULL_PUBLIC_ENCRYPT 135 +#define RSA_F_RSA_PADDING_ADD_NONE 107 +#define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP 121 +#define RSA_F_RSA_PADDING_ADD_PKCS1_PSS 125 +#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1 108 +#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2 109 +#define RSA_F_RSA_PADDING_ADD_SSLV23 110 +#define RSA_F_RSA_PADDING_ADD_X931 127 +#define RSA_F_RSA_PADDING_CHECK_NONE 111 +#define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP 122 +#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1 112 +#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2 113 +#define RSA_F_RSA_PADDING_CHECK_SSLV23 114 +#define RSA_F_RSA_PADDING_CHECK_X931 128 +#define RSA_F_RSA_PRINT 115 +#define RSA_F_RSA_PRINT_FP 116 +#define RSA_F_RSA_PRIV_DECODE 137 +#define RSA_F_RSA_PRIV_ENCODE 138 +#define RSA_F_RSA_PUB_DECODE 139 +#define RSA_F_RSA_SETUP_BLINDING 136 +#define RSA_F_RSA_SIGN 117 +#define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 +#define RSA_F_RSA_VERIFY 119 +#define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING 120 +#define RSA_F_RSA_VERIFY_PKCS1_PSS 126 + +/* Reason codes. */ +#define RSA_R_ALGORITHM_MISMATCH 100 +#define RSA_R_BAD_E_VALUE 101 +#define RSA_R_BAD_FIXED_HEADER_DECRYPT 102 +#define RSA_R_BAD_PAD_BYTE_COUNT 103 +#define RSA_R_BAD_SIGNATURE 104 +#define RSA_R_BLOCK_TYPE_IS_NOT_01 106 +#define RSA_R_BLOCK_TYPE_IS_NOT_02 107 +#define RSA_R_DATA_GREATER_THAN_MOD_LEN 108 +#define RSA_R_DATA_TOO_LARGE 109 +#define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 110 +#define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 132 +#define RSA_R_DATA_TOO_SMALL 111 +#define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 122 +#define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 112 +#define RSA_R_DMP1_NOT_CONGRUENT_TO_D 124 +#define RSA_R_DMQ1_NOT_CONGRUENT_TO_D 125 +#define RSA_R_D_E_NOT_CONGRUENT_TO_1 123 +#define RSA_R_FIRST_OCTET_INVALID 133 +#define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 144 +#define RSA_R_INVALID_DIGEST_LENGTH 143 +#define RSA_R_INVALID_HEADER 137 +#define RSA_R_INVALID_KEYBITS 145 +#define RSA_R_INVALID_MESSAGE_LENGTH 131 +#define RSA_R_INVALID_PADDING 138 +#define RSA_R_INVALID_PADDING_MODE 141 +#define RSA_R_INVALID_PSS_SALTLEN 146 +#define RSA_R_INVALID_TRAILER 139 +#define RSA_R_INVALID_X931_DIGEST 142 +#define RSA_R_IQMP_NOT_INVERSE_OF_Q 126 +#define RSA_R_KEY_SIZE_TOO_SMALL 120 +#define RSA_R_LAST_OCTET_INVALID 134 +#define RSA_R_MODULUS_TOO_LARGE 105 +#define RSA_R_NO_PUBLIC_EXPONENT 140 +#define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 +#define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 +#define RSA_R_OAEP_DECODING_ERROR 121 +#define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148 +#define RSA_R_PADDING_CHECK_FAILED 114 +#define RSA_R_P_NOT_PRIME 128 +#define RSA_R_Q_NOT_PRIME 129 +#define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED 130 +#define RSA_R_SLEN_CHECK_FAILED 136 +#define RSA_R_SLEN_RECOVERY_FAILED 135 +#define RSA_R_SSLV3_ROLLBACK_ATTACK 115 +#define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116 +#define RSA_R_UNKNOWN_ALGORITHM_TYPE 117 +#define RSA_R_UNKNOWN_PADDING_TYPE 118 +#define RSA_R_VALUE_MISSING 147 +#define RSA_R_WRONG_SIGNATURE_LENGTH 119 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/safestack.h b/extra_lib/include/openssl/safestack.h new file mode 100644 index 0000000..39914bd --- /dev/null +++ b/extra_lib/include/openssl/safestack.h @@ -0,0 +1,2575 @@ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_SAFESTACK_H +#define HEADER_SAFESTACK_H + +#include + +#ifndef CHECKED_PTR_OF +#define CHECKED_PTR_OF(type, p) \ + ((void*) (1 ? p : (type*)0)) +#endif + +/* In C++ we get problems because an explicit cast is needed from (void *) + * we use CHECKED_STACK_OF to ensure the correct type is passed in the macros + * below. + */ + +#define CHECKED_STACK_OF(type, p) \ + ((_STACK*) (1 ? p : (STACK_OF(type)*)0)) + +#define CHECKED_SK_FREE_FUNC(type, p) \ + ((void (*)(void *)) ((1 ? p : (void (*)(type *))0))) + +#define CHECKED_SK_FREE_FUNC2(type, p) \ + ((void (*)(void *)) ((1 ? p : (void (*)(type))0))) + +#define CHECKED_SK_CMP_FUNC(type, p) \ + ((int (*)(const void *, const void *)) \ + ((1 ? p : (int (*)(const type * const *, const type * const *))0))) + +#define STACK_OF(type) struct stack_st_##type +#define PREDECLARE_STACK_OF(type) STACK_OF(type); + +#define DECLARE_STACK_OF(type) \ +STACK_OF(type) \ + { \ + _STACK stack; \ + }; +#define DECLARE_SPECIAL_STACK_OF(type, type2) \ +STACK_OF(type) \ + { \ + _STACK stack; \ + }; + +#define IMPLEMENT_STACK_OF(type) /* nada (obsolete in new safestack approach)*/ + + +/* Strings are special: normally an lhash entry will point to a single + * (somewhat) mutable object. In the case of strings: + * + * a) Instead of a single char, there is an array of chars, NUL-terminated. + * b) The string may have be immutable. + * + * So, they need their own declarations. Especially important for + * type-checking tools, such as Deputy. + * +o * In practice, however, it appears to be hard to have a const + * string. For now, I'm settling for dealing with the fact it is a + * string at all. + */ +typedef char *OPENSSL_STRING; + +typedef const char *OPENSSL_CSTRING; + +/* Confusingly, LHASH_OF(STRING) deals with char ** throughout, but + * STACK_OF(STRING) is really more like STACK_OF(char), only, as + * mentioned above, instead of a single char each entry is a + * NUL-terminated array of chars. So, we have to implement STRING + * specially for STACK_OF. This is dealt with in the autogenerated + * macros below. + */ + +DECLARE_SPECIAL_STACK_OF(OPENSSL_STRING, char) + +/* Similarly, we sometimes use a block of characters, NOT + * nul-terminated. These should also be distinguished from "normal" + * stacks. */ + +typedef void *OPENSSL_BLOCK; +DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void) + +/* SKM_sk_... stack macros are internal to safestack.h: + * never use them directly, use sk__... instead */ +#define SKM_sk_new(type, cmp) \ + ((STACK_OF(type) *)sk_new(CHECKED_SK_CMP_FUNC(type, cmp))) +#define SKM_sk_new_null(type) \ + ((STACK_OF(type) *)sk_new_null()) +#define SKM_sk_free(type, st) \ + sk_free(CHECKED_STACK_OF(type, st)) +#define SKM_sk_num(type, st) \ + sk_num(CHECKED_STACK_OF(type, st)) +#define SKM_sk_value(type, st,i) \ + ((type *)sk_value(CHECKED_STACK_OF(type, st), i)) +#define SKM_sk_set(type, st,i,val) \ + sk_set(CHECKED_STACK_OF(type, st), i, CHECKED_PTR_OF(type, val)) +#define SKM_sk_zero(type, st) \ + sk_zero(CHECKED_STACK_OF(type, st)) +#define SKM_sk_push(type, st, val) \ + sk_push(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +#define SKM_sk_unshift(type, st, val) \ + sk_unshift(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +#define SKM_sk_find(type, st, val) \ + sk_find(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +#define SKM_sk_find_ex(type, st, val) \ + sk_find_ex(CHECKED_STACK_OF(type, st), \ + CHECKED_PTR_OF(type, val)) +#define SKM_sk_delete(type, st, i) \ + (type *)sk_delete(CHECKED_STACK_OF(type, st), i) +#define SKM_sk_delete_ptr(type, st, ptr) \ + (type *)sk_delete_ptr(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, ptr)) +#define SKM_sk_insert(type, st,val, i) \ + sk_insert(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val), i) +#define SKM_sk_set_cmp_func(type, st, cmp) \ + ((int (*)(const type * const *,const type * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(type, st), CHECKED_SK_CMP_FUNC(type, cmp))) +#define SKM_sk_dup(type, st) \ + (STACK_OF(type) *)sk_dup(CHECKED_STACK_OF(type, st)) +#define SKM_sk_pop_free(type, st, free_func) \ + sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func)) +#define SKM_sk_shift(type, st) \ + (type *)sk_shift(CHECKED_STACK_OF(type, st)) +#define SKM_sk_pop(type, st) \ + (type *)sk_pop(CHECKED_STACK_OF(type, st)) +#define SKM_sk_sort(type, st) \ + sk_sort(CHECKED_STACK_OF(type, st)) +#define SKM_sk_is_sorted(type, st) \ + sk_is_sorted(CHECKED_STACK_OF(type, st)) + +#define SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + (STACK_OF(type) *)d2i_ASN1_SET( \ + (STACK_OF(OPENSSL_BLOCK) **)CHECKED_PTR_OF(STACK_OF(type)*, st), \ + pp, length, \ + CHECKED_D2I_OF(type, d2i_func), \ + CHECKED_SK_FREE_FUNC(type, free_func), \ + ex_tag, ex_class) + +#define SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \ + i2d_ASN1_SET((STACK_OF(OPENSSL_BLOCK) *)CHECKED_STACK_OF(type, st), pp, \ + CHECKED_I2D_OF(type, i2d_func), \ + ex_tag, ex_class, is_set) + +#define SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \ + ASN1_seq_pack(CHECKED_PTR_OF(STACK_OF(type), st), \ + CHECKED_I2D_OF(type, i2d_func), buf, len) + +#define SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \ + (STACK_OF(type) *)ASN1_seq_unpack(buf, len, CHECKED_D2I_OF(type, d2i_func), CHECKED_SK_FREE_FUNC(type, free_func)) + +#define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \ + (STACK_OF(type) *)PKCS12_decrypt_d2i(algor, \ + CHECKED_D2I_OF(type, d2i_func), \ + CHECKED_SK_FREE_FUNC(type, free_func), \ + pass, passlen, oct, seq) + +/* This block of defines is updated by util/mkstack.pl, please do not touch! */ +#define sk_ACCESS_DESCRIPTION_new(cmp) SKM_sk_new(ACCESS_DESCRIPTION, (cmp)) +#define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION) +#define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st)) +#define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st)) +#define sk_ACCESS_DESCRIPTION_value(st, i) SKM_sk_value(ACCESS_DESCRIPTION, (st), (i)) +#define sk_ACCESS_DESCRIPTION_set(st, i, val) SKM_sk_set(ACCESS_DESCRIPTION, (st), (i), (val)) +#define sk_ACCESS_DESCRIPTION_zero(st) SKM_sk_zero(ACCESS_DESCRIPTION, (st)) +#define sk_ACCESS_DESCRIPTION_push(st, val) SKM_sk_push(ACCESS_DESCRIPTION, (st), (val)) +#define sk_ACCESS_DESCRIPTION_unshift(st, val) SKM_sk_unshift(ACCESS_DESCRIPTION, (st), (val)) +#define sk_ACCESS_DESCRIPTION_find(st, val) SKM_sk_find(ACCESS_DESCRIPTION, (st), (val)) +#define sk_ACCESS_DESCRIPTION_find_ex(st, val) SKM_sk_find_ex(ACCESS_DESCRIPTION, (st), (val)) +#define sk_ACCESS_DESCRIPTION_delete(st, i) SKM_sk_delete(ACCESS_DESCRIPTION, (st), (i)) +#define sk_ACCESS_DESCRIPTION_delete_ptr(st, ptr) SKM_sk_delete_ptr(ACCESS_DESCRIPTION, (st), (ptr)) +#define sk_ACCESS_DESCRIPTION_insert(st, val, i) SKM_sk_insert(ACCESS_DESCRIPTION, (st), (val), (i)) +#define sk_ACCESS_DESCRIPTION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ACCESS_DESCRIPTION, (st), (cmp)) +#define sk_ACCESS_DESCRIPTION_dup(st) SKM_sk_dup(ACCESS_DESCRIPTION, st) +#define sk_ACCESS_DESCRIPTION_pop_free(st, free_func) SKM_sk_pop_free(ACCESS_DESCRIPTION, (st), (free_func)) +#define sk_ACCESS_DESCRIPTION_shift(st) SKM_sk_shift(ACCESS_DESCRIPTION, (st)) +#define sk_ACCESS_DESCRIPTION_pop(st) SKM_sk_pop(ACCESS_DESCRIPTION, (st)) +#define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st)) +#define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st)) + +#define sk_ASIdOrRange_new(cmp) SKM_sk_new(ASIdOrRange, (cmp)) +#define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange) +#define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st)) +#define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st)) +#define sk_ASIdOrRange_value(st, i) SKM_sk_value(ASIdOrRange, (st), (i)) +#define sk_ASIdOrRange_set(st, i, val) SKM_sk_set(ASIdOrRange, (st), (i), (val)) +#define sk_ASIdOrRange_zero(st) SKM_sk_zero(ASIdOrRange, (st)) +#define sk_ASIdOrRange_push(st, val) SKM_sk_push(ASIdOrRange, (st), (val)) +#define sk_ASIdOrRange_unshift(st, val) SKM_sk_unshift(ASIdOrRange, (st), (val)) +#define sk_ASIdOrRange_find(st, val) SKM_sk_find(ASIdOrRange, (st), (val)) +#define sk_ASIdOrRange_find_ex(st, val) SKM_sk_find_ex(ASIdOrRange, (st), (val)) +#define sk_ASIdOrRange_delete(st, i) SKM_sk_delete(ASIdOrRange, (st), (i)) +#define sk_ASIdOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASIdOrRange, (st), (ptr)) +#define sk_ASIdOrRange_insert(st, val, i) SKM_sk_insert(ASIdOrRange, (st), (val), (i)) +#define sk_ASIdOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASIdOrRange, (st), (cmp)) +#define sk_ASIdOrRange_dup(st) SKM_sk_dup(ASIdOrRange, st) +#define sk_ASIdOrRange_pop_free(st, free_func) SKM_sk_pop_free(ASIdOrRange, (st), (free_func)) +#define sk_ASIdOrRange_shift(st) SKM_sk_shift(ASIdOrRange, (st)) +#define sk_ASIdOrRange_pop(st) SKM_sk_pop(ASIdOrRange, (st)) +#define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st)) +#define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st)) + +#define sk_ASN1_GENERALSTRING_new(cmp) SKM_sk_new(ASN1_GENERALSTRING, (cmp)) +#define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING) +#define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st)) +#define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st)) +#define sk_ASN1_GENERALSTRING_value(st, i) SKM_sk_value(ASN1_GENERALSTRING, (st), (i)) +#define sk_ASN1_GENERALSTRING_set(st, i, val) SKM_sk_set(ASN1_GENERALSTRING, (st), (i), (val)) +#define sk_ASN1_GENERALSTRING_zero(st) SKM_sk_zero(ASN1_GENERALSTRING, (st)) +#define sk_ASN1_GENERALSTRING_push(st, val) SKM_sk_push(ASN1_GENERALSTRING, (st), (val)) +#define sk_ASN1_GENERALSTRING_unshift(st, val) SKM_sk_unshift(ASN1_GENERALSTRING, (st), (val)) +#define sk_ASN1_GENERALSTRING_find(st, val) SKM_sk_find(ASN1_GENERALSTRING, (st), (val)) +#define sk_ASN1_GENERALSTRING_find_ex(st, val) SKM_sk_find_ex(ASN1_GENERALSTRING, (st), (val)) +#define sk_ASN1_GENERALSTRING_delete(st, i) SKM_sk_delete(ASN1_GENERALSTRING, (st), (i)) +#define sk_ASN1_GENERALSTRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_GENERALSTRING, (st), (ptr)) +#define sk_ASN1_GENERALSTRING_insert(st, val, i) SKM_sk_insert(ASN1_GENERALSTRING, (st), (val), (i)) +#define sk_ASN1_GENERALSTRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_GENERALSTRING, (st), (cmp)) +#define sk_ASN1_GENERALSTRING_dup(st) SKM_sk_dup(ASN1_GENERALSTRING, st) +#define sk_ASN1_GENERALSTRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_GENERALSTRING, (st), (free_func)) +#define sk_ASN1_GENERALSTRING_shift(st) SKM_sk_shift(ASN1_GENERALSTRING, (st)) +#define sk_ASN1_GENERALSTRING_pop(st) SKM_sk_pop(ASN1_GENERALSTRING, (st)) +#define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st)) +#define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st)) + +#define sk_ASN1_INTEGER_new(cmp) SKM_sk_new(ASN1_INTEGER, (cmp)) +#define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER) +#define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st)) +#define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st)) +#define sk_ASN1_INTEGER_value(st, i) SKM_sk_value(ASN1_INTEGER, (st), (i)) +#define sk_ASN1_INTEGER_set(st, i, val) SKM_sk_set(ASN1_INTEGER, (st), (i), (val)) +#define sk_ASN1_INTEGER_zero(st) SKM_sk_zero(ASN1_INTEGER, (st)) +#define sk_ASN1_INTEGER_push(st, val) SKM_sk_push(ASN1_INTEGER, (st), (val)) +#define sk_ASN1_INTEGER_unshift(st, val) SKM_sk_unshift(ASN1_INTEGER, (st), (val)) +#define sk_ASN1_INTEGER_find(st, val) SKM_sk_find(ASN1_INTEGER, (st), (val)) +#define sk_ASN1_INTEGER_find_ex(st, val) SKM_sk_find_ex(ASN1_INTEGER, (st), (val)) +#define sk_ASN1_INTEGER_delete(st, i) SKM_sk_delete(ASN1_INTEGER, (st), (i)) +#define sk_ASN1_INTEGER_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_INTEGER, (st), (ptr)) +#define sk_ASN1_INTEGER_insert(st, val, i) SKM_sk_insert(ASN1_INTEGER, (st), (val), (i)) +#define sk_ASN1_INTEGER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_INTEGER, (st), (cmp)) +#define sk_ASN1_INTEGER_dup(st) SKM_sk_dup(ASN1_INTEGER, st) +#define sk_ASN1_INTEGER_pop_free(st, free_func) SKM_sk_pop_free(ASN1_INTEGER, (st), (free_func)) +#define sk_ASN1_INTEGER_shift(st) SKM_sk_shift(ASN1_INTEGER, (st)) +#define sk_ASN1_INTEGER_pop(st) SKM_sk_pop(ASN1_INTEGER, (st)) +#define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st)) +#define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st)) + +#define sk_ASN1_OBJECT_new(cmp) SKM_sk_new(ASN1_OBJECT, (cmp)) +#define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT) +#define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st)) +#define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st)) +#define sk_ASN1_OBJECT_value(st, i) SKM_sk_value(ASN1_OBJECT, (st), (i)) +#define sk_ASN1_OBJECT_set(st, i, val) SKM_sk_set(ASN1_OBJECT, (st), (i), (val)) +#define sk_ASN1_OBJECT_zero(st) SKM_sk_zero(ASN1_OBJECT, (st)) +#define sk_ASN1_OBJECT_push(st, val) SKM_sk_push(ASN1_OBJECT, (st), (val)) +#define sk_ASN1_OBJECT_unshift(st, val) SKM_sk_unshift(ASN1_OBJECT, (st), (val)) +#define sk_ASN1_OBJECT_find(st, val) SKM_sk_find(ASN1_OBJECT, (st), (val)) +#define sk_ASN1_OBJECT_find_ex(st, val) SKM_sk_find_ex(ASN1_OBJECT, (st), (val)) +#define sk_ASN1_OBJECT_delete(st, i) SKM_sk_delete(ASN1_OBJECT, (st), (i)) +#define sk_ASN1_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_OBJECT, (st), (ptr)) +#define sk_ASN1_OBJECT_insert(st, val, i) SKM_sk_insert(ASN1_OBJECT, (st), (val), (i)) +#define sk_ASN1_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_OBJECT, (st), (cmp)) +#define sk_ASN1_OBJECT_dup(st) SKM_sk_dup(ASN1_OBJECT, st) +#define sk_ASN1_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(ASN1_OBJECT, (st), (free_func)) +#define sk_ASN1_OBJECT_shift(st) SKM_sk_shift(ASN1_OBJECT, (st)) +#define sk_ASN1_OBJECT_pop(st) SKM_sk_pop(ASN1_OBJECT, (st)) +#define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st)) +#define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st)) + +#define sk_ASN1_STRING_TABLE_new(cmp) SKM_sk_new(ASN1_STRING_TABLE, (cmp)) +#define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE) +#define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st)) +#define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st)) +#define sk_ASN1_STRING_TABLE_value(st, i) SKM_sk_value(ASN1_STRING_TABLE, (st), (i)) +#define sk_ASN1_STRING_TABLE_set(st, i, val) SKM_sk_set(ASN1_STRING_TABLE, (st), (i), (val)) +#define sk_ASN1_STRING_TABLE_zero(st) SKM_sk_zero(ASN1_STRING_TABLE, (st)) +#define sk_ASN1_STRING_TABLE_push(st, val) SKM_sk_push(ASN1_STRING_TABLE, (st), (val)) +#define sk_ASN1_STRING_TABLE_unshift(st, val) SKM_sk_unshift(ASN1_STRING_TABLE, (st), (val)) +#define sk_ASN1_STRING_TABLE_find(st, val) SKM_sk_find(ASN1_STRING_TABLE, (st), (val)) +#define sk_ASN1_STRING_TABLE_find_ex(st, val) SKM_sk_find_ex(ASN1_STRING_TABLE, (st), (val)) +#define sk_ASN1_STRING_TABLE_delete(st, i) SKM_sk_delete(ASN1_STRING_TABLE, (st), (i)) +#define sk_ASN1_STRING_TABLE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_STRING_TABLE, (st), (ptr)) +#define sk_ASN1_STRING_TABLE_insert(st, val, i) SKM_sk_insert(ASN1_STRING_TABLE, (st), (val), (i)) +#define sk_ASN1_STRING_TABLE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_STRING_TABLE, (st), (cmp)) +#define sk_ASN1_STRING_TABLE_dup(st) SKM_sk_dup(ASN1_STRING_TABLE, st) +#define sk_ASN1_STRING_TABLE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_STRING_TABLE, (st), (free_func)) +#define sk_ASN1_STRING_TABLE_shift(st) SKM_sk_shift(ASN1_STRING_TABLE, (st)) +#define sk_ASN1_STRING_TABLE_pop(st) SKM_sk_pop(ASN1_STRING_TABLE, (st)) +#define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st)) +#define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st)) + +#define sk_ASN1_TYPE_new(cmp) SKM_sk_new(ASN1_TYPE, (cmp)) +#define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE) +#define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st)) +#define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st)) +#define sk_ASN1_TYPE_value(st, i) SKM_sk_value(ASN1_TYPE, (st), (i)) +#define sk_ASN1_TYPE_set(st, i, val) SKM_sk_set(ASN1_TYPE, (st), (i), (val)) +#define sk_ASN1_TYPE_zero(st) SKM_sk_zero(ASN1_TYPE, (st)) +#define sk_ASN1_TYPE_push(st, val) SKM_sk_push(ASN1_TYPE, (st), (val)) +#define sk_ASN1_TYPE_unshift(st, val) SKM_sk_unshift(ASN1_TYPE, (st), (val)) +#define sk_ASN1_TYPE_find(st, val) SKM_sk_find(ASN1_TYPE, (st), (val)) +#define sk_ASN1_TYPE_find_ex(st, val) SKM_sk_find_ex(ASN1_TYPE, (st), (val)) +#define sk_ASN1_TYPE_delete(st, i) SKM_sk_delete(ASN1_TYPE, (st), (i)) +#define sk_ASN1_TYPE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_TYPE, (st), (ptr)) +#define sk_ASN1_TYPE_insert(st, val, i) SKM_sk_insert(ASN1_TYPE, (st), (val), (i)) +#define sk_ASN1_TYPE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_TYPE, (st), (cmp)) +#define sk_ASN1_TYPE_dup(st) SKM_sk_dup(ASN1_TYPE, st) +#define sk_ASN1_TYPE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_TYPE, (st), (free_func)) +#define sk_ASN1_TYPE_shift(st) SKM_sk_shift(ASN1_TYPE, (st)) +#define sk_ASN1_TYPE_pop(st) SKM_sk_pop(ASN1_TYPE, (st)) +#define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st)) +#define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st)) + +#define sk_ASN1_UTF8STRING_new(cmp) SKM_sk_new(ASN1_UTF8STRING, (cmp)) +#define sk_ASN1_UTF8STRING_new_null() SKM_sk_new_null(ASN1_UTF8STRING) +#define sk_ASN1_UTF8STRING_free(st) SKM_sk_free(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_num(st) SKM_sk_num(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_value(st, i) SKM_sk_value(ASN1_UTF8STRING, (st), (i)) +#define sk_ASN1_UTF8STRING_set(st, i, val) SKM_sk_set(ASN1_UTF8STRING, (st), (i), (val)) +#define sk_ASN1_UTF8STRING_zero(st) SKM_sk_zero(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_push(st, val) SKM_sk_push(ASN1_UTF8STRING, (st), (val)) +#define sk_ASN1_UTF8STRING_unshift(st, val) SKM_sk_unshift(ASN1_UTF8STRING, (st), (val)) +#define sk_ASN1_UTF8STRING_find(st, val) SKM_sk_find(ASN1_UTF8STRING, (st), (val)) +#define sk_ASN1_UTF8STRING_find_ex(st, val) SKM_sk_find_ex(ASN1_UTF8STRING, (st), (val)) +#define sk_ASN1_UTF8STRING_delete(st, i) SKM_sk_delete(ASN1_UTF8STRING, (st), (i)) +#define sk_ASN1_UTF8STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_UTF8STRING, (st), (ptr)) +#define sk_ASN1_UTF8STRING_insert(st, val, i) SKM_sk_insert(ASN1_UTF8STRING, (st), (val), (i)) +#define sk_ASN1_UTF8STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_UTF8STRING, (st), (cmp)) +#define sk_ASN1_UTF8STRING_dup(st) SKM_sk_dup(ASN1_UTF8STRING, st) +#define sk_ASN1_UTF8STRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_UTF8STRING, (st), (free_func)) +#define sk_ASN1_UTF8STRING_shift(st) SKM_sk_shift(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_pop(st) SKM_sk_pop(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_sort(st) SKM_sk_sort(ASN1_UTF8STRING, (st)) +#define sk_ASN1_UTF8STRING_is_sorted(st) SKM_sk_is_sorted(ASN1_UTF8STRING, (st)) + +#define sk_ASN1_VALUE_new(cmp) SKM_sk_new(ASN1_VALUE, (cmp)) +#define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE) +#define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st)) +#define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st)) +#define sk_ASN1_VALUE_value(st, i) SKM_sk_value(ASN1_VALUE, (st), (i)) +#define sk_ASN1_VALUE_set(st, i, val) SKM_sk_set(ASN1_VALUE, (st), (i), (val)) +#define sk_ASN1_VALUE_zero(st) SKM_sk_zero(ASN1_VALUE, (st)) +#define sk_ASN1_VALUE_push(st, val) SKM_sk_push(ASN1_VALUE, (st), (val)) +#define sk_ASN1_VALUE_unshift(st, val) SKM_sk_unshift(ASN1_VALUE, (st), (val)) +#define sk_ASN1_VALUE_find(st, val) SKM_sk_find(ASN1_VALUE, (st), (val)) +#define sk_ASN1_VALUE_find_ex(st, val) SKM_sk_find_ex(ASN1_VALUE, (st), (val)) +#define sk_ASN1_VALUE_delete(st, i) SKM_sk_delete(ASN1_VALUE, (st), (i)) +#define sk_ASN1_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_VALUE, (st), (ptr)) +#define sk_ASN1_VALUE_insert(st, val, i) SKM_sk_insert(ASN1_VALUE, (st), (val), (i)) +#define sk_ASN1_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_VALUE, (st), (cmp)) +#define sk_ASN1_VALUE_dup(st) SKM_sk_dup(ASN1_VALUE, st) +#define sk_ASN1_VALUE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_VALUE, (st), (free_func)) +#define sk_ASN1_VALUE_shift(st) SKM_sk_shift(ASN1_VALUE, (st)) +#define sk_ASN1_VALUE_pop(st) SKM_sk_pop(ASN1_VALUE, (st)) +#define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st)) +#define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st)) + +#define sk_BIO_new(cmp) SKM_sk_new(BIO, (cmp)) +#define sk_BIO_new_null() SKM_sk_new_null(BIO) +#define sk_BIO_free(st) SKM_sk_free(BIO, (st)) +#define sk_BIO_num(st) SKM_sk_num(BIO, (st)) +#define sk_BIO_value(st, i) SKM_sk_value(BIO, (st), (i)) +#define sk_BIO_set(st, i, val) SKM_sk_set(BIO, (st), (i), (val)) +#define sk_BIO_zero(st) SKM_sk_zero(BIO, (st)) +#define sk_BIO_push(st, val) SKM_sk_push(BIO, (st), (val)) +#define sk_BIO_unshift(st, val) SKM_sk_unshift(BIO, (st), (val)) +#define sk_BIO_find(st, val) SKM_sk_find(BIO, (st), (val)) +#define sk_BIO_find_ex(st, val) SKM_sk_find_ex(BIO, (st), (val)) +#define sk_BIO_delete(st, i) SKM_sk_delete(BIO, (st), (i)) +#define sk_BIO_delete_ptr(st, ptr) SKM_sk_delete_ptr(BIO, (st), (ptr)) +#define sk_BIO_insert(st, val, i) SKM_sk_insert(BIO, (st), (val), (i)) +#define sk_BIO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BIO, (st), (cmp)) +#define sk_BIO_dup(st) SKM_sk_dup(BIO, st) +#define sk_BIO_pop_free(st, free_func) SKM_sk_pop_free(BIO, (st), (free_func)) +#define sk_BIO_shift(st) SKM_sk_shift(BIO, (st)) +#define sk_BIO_pop(st) SKM_sk_pop(BIO, (st)) +#define sk_BIO_sort(st) SKM_sk_sort(BIO, (st)) +#define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st)) + +#define sk_BY_DIR_ENTRY_new(cmp) SKM_sk_new(BY_DIR_ENTRY, (cmp)) +#define sk_BY_DIR_ENTRY_new_null() SKM_sk_new_null(BY_DIR_ENTRY) +#define sk_BY_DIR_ENTRY_free(st) SKM_sk_free(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_num(st) SKM_sk_num(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_value(st, i) SKM_sk_value(BY_DIR_ENTRY, (st), (i)) +#define sk_BY_DIR_ENTRY_set(st, i, val) SKM_sk_set(BY_DIR_ENTRY, (st), (i), (val)) +#define sk_BY_DIR_ENTRY_zero(st) SKM_sk_zero(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_push(st, val) SKM_sk_push(BY_DIR_ENTRY, (st), (val)) +#define sk_BY_DIR_ENTRY_unshift(st, val) SKM_sk_unshift(BY_DIR_ENTRY, (st), (val)) +#define sk_BY_DIR_ENTRY_find(st, val) SKM_sk_find(BY_DIR_ENTRY, (st), (val)) +#define sk_BY_DIR_ENTRY_find_ex(st, val) SKM_sk_find_ex(BY_DIR_ENTRY, (st), (val)) +#define sk_BY_DIR_ENTRY_delete(st, i) SKM_sk_delete(BY_DIR_ENTRY, (st), (i)) +#define sk_BY_DIR_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_ENTRY, (st), (ptr)) +#define sk_BY_DIR_ENTRY_insert(st, val, i) SKM_sk_insert(BY_DIR_ENTRY, (st), (val), (i)) +#define sk_BY_DIR_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_ENTRY, (st), (cmp)) +#define sk_BY_DIR_ENTRY_dup(st) SKM_sk_dup(BY_DIR_ENTRY, st) +#define sk_BY_DIR_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_ENTRY, (st), (free_func)) +#define sk_BY_DIR_ENTRY_shift(st) SKM_sk_shift(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_pop(st) SKM_sk_pop(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_sort(st) SKM_sk_sort(BY_DIR_ENTRY, (st)) +#define sk_BY_DIR_ENTRY_is_sorted(st) SKM_sk_is_sorted(BY_DIR_ENTRY, (st)) + +#define sk_BY_DIR_HASH_new(cmp) SKM_sk_new(BY_DIR_HASH, (cmp)) +#define sk_BY_DIR_HASH_new_null() SKM_sk_new_null(BY_DIR_HASH) +#define sk_BY_DIR_HASH_free(st) SKM_sk_free(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_num(st) SKM_sk_num(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_value(st, i) SKM_sk_value(BY_DIR_HASH, (st), (i)) +#define sk_BY_DIR_HASH_set(st, i, val) SKM_sk_set(BY_DIR_HASH, (st), (i), (val)) +#define sk_BY_DIR_HASH_zero(st) SKM_sk_zero(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_push(st, val) SKM_sk_push(BY_DIR_HASH, (st), (val)) +#define sk_BY_DIR_HASH_unshift(st, val) SKM_sk_unshift(BY_DIR_HASH, (st), (val)) +#define sk_BY_DIR_HASH_find(st, val) SKM_sk_find(BY_DIR_HASH, (st), (val)) +#define sk_BY_DIR_HASH_find_ex(st, val) SKM_sk_find_ex(BY_DIR_HASH, (st), (val)) +#define sk_BY_DIR_HASH_delete(st, i) SKM_sk_delete(BY_DIR_HASH, (st), (i)) +#define sk_BY_DIR_HASH_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_HASH, (st), (ptr)) +#define sk_BY_DIR_HASH_insert(st, val, i) SKM_sk_insert(BY_DIR_HASH, (st), (val), (i)) +#define sk_BY_DIR_HASH_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_HASH, (st), (cmp)) +#define sk_BY_DIR_HASH_dup(st) SKM_sk_dup(BY_DIR_HASH, st) +#define sk_BY_DIR_HASH_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_HASH, (st), (free_func)) +#define sk_BY_DIR_HASH_shift(st) SKM_sk_shift(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_pop(st) SKM_sk_pop(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_sort(st) SKM_sk_sort(BY_DIR_HASH, (st)) +#define sk_BY_DIR_HASH_is_sorted(st) SKM_sk_is_sorted(BY_DIR_HASH, (st)) + +#define sk_CMS_CertificateChoices_new(cmp) SKM_sk_new(CMS_CertificateChoices, (cmp)) +#define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices) +#define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st)) +#define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st)) +#define sk_CMS_CertificateChoices_value(st, i) SKM_sk_value(CMS_CertificateChoices, (st), (i)) +#define sk_CMS_CertificateChoices_set(st, i, val) SKM_sk_set(CMS_CertificateChoices, (st), (i), (val)) +#define sk_CMS_CertificateChoices_zero(st) SKM_sk_zero(CMS_CertificateChoices, (st)) +#define sk_CMS_CertificateChoices_push(st, val) SKM_sk_push(CMS_CertificateChoices, (st), (val)) +#define sk_CMS_CertificateChoices_unshift(st, val) SKM_sk_unshift(CMS_CertificateChoices, (st), (val)) +#define sk_CMS_CertificateChoices_find(st, val) SKM_sk_find(CMS_CertificateChoices, (st), (val)) +#define sk_CMS_CertificateChoices_find_ex(st, val) SKM_sk_find_ex(CMS_CertificateChoices, (st), (val)) +#define sk_CMS_CertificateChoices_delete(st, i) SKM_sk_delete(CMS_CertificateChoices, (st), (i)) +#define sk_CMS_CertificateChoices_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_CertificateChoices, (st), (ptr)) +#define sk_CMS_CertificateChoices_insert(st, val, i) SKM_sk_insert(CMS_CertificateChoices, (st), (val), (i)) +#define sk_CMS_CertificateChoices_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_CertificateChoices, (st), (cmp)) +#define sk_CMS_CertificateChoices_dup(st) SKM_sk_dup(CMS_CertificateChoices, st) +#define sk_CMS_CertificateChoices_pop_free(st, free_func) SKM_sk_pop_free(CMS_CertificateChoices, (st), (free_func)) +#define sk_CMS_CertificateChoices_shift(st) SKM_sk_shift(CMS_CertificateChoices, (st)) +#define sk_CMS_CertificateChoices_pop(st) SKM_sk_pop(CMS_CertificateChoices, (st)) +#define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st)) +#define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st)) + +#define sk_CMS_RecipientInfo_new(cmp) SKM_sk_new(CMS_RecipientInfo, (cmp)) +#define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo) +#define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st)) +#define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st)) +#define sk_CMS_RecipientInfo_value(st, i) SKM_sk_value(CMS_RecipientInfo, (st), (i)) +#define sk_CMS_RecipientInfo_set(st, i, val) SKM_sk_set(CMS_RecipientInfo, (st), (i), (val)) +#define sk_CMS_RecipientInfo_zero(st) SKM_sk_zero(CMS_RecipientInfo, (st)) +#define sk_CMS_RecipientInfo_push(st, val) SKM_sk_push(CMS_RecipientInfo, (st), (val)) +#define sk_CMS_RecipientInfo_unshift(st, val) SKM_sk_unshift(CMS_RecipientInfo, (st), (val)) +#define sk_CMS_RecipientInfo_find(st, val) SKM_sk_find(CMS_RecipientInfo, (st), (val)) +#define sk_CMS_RecipientInfo_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientInfo, (st), (val)) +#define sk_CMS_RecipientInfo_delete(st, i) SKM_sk_delete(CMS_RecipientInfo, (st), (i)) +#define sk_CMS_RecipientInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientInfo, (st), (ptr)) +#define sk_CMS_RecipientInfo_insert(st, val, i) SKM_sk_insert(CMS_RecipientInfo, (st), (val), (i)) +#define sk_CMS_RecipientInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientInfo, (st), (cmp)) +#define sk_CMS_RecipientInfo_dup(st) SKM_sk_dup(CMS_RecipientInfo, st) +#define sk_CMS_RecipientInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientInfo, (st), (free_func)) +#define sk_CMS_RecipientInfo_shift(st) SKM_sk_shift(CMS_RecipientInfo, (st)) +#define sk_CMS_RecipientInfo_pop(st) SKM_sk_pop(CMS_RecipientInfo, (st)) +#define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st)) +#define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st)) + +#define sk_CMS_RevocationInfoChoice_new(cmp) SKM_sk_new(CMS_RevocationInfoChoice, (cmp)) +#define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice) +#define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st)) +#define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st)) +#define sk_CMS_RevocationInfoChoice_value(st, i) SKM_sk_value(CMS_RevocationInfoChoice, (st), (i)) +#define sk_CMS_RevocationInfoChoice_set(st, i, val) SKM_sk_set(CMS_RevocationInfoChoice, (st), (i), (val)) +#define sk_CMS_RevocationInfoChoice_zero(st) SKM_sk_zero(CMS_RevocationInfoChoice, (st)) +#define sk_CMS_RevocationInfoChoice_push(st, val) SKM_sk_push(CMS_RevocationInfoChoice, (st), (val)) +#define sk_CMS_RevocationInfoChoice_unshift(st, val) SKM_sk_unshift(CMS_RevocationInfoChoice, (st), (val)) +#define sk_CMS_RevocationInfoChoice_find(st, val) SKM_sk_find(CMS_RevocationInfoChoice, (st), (val)) +#define sk_CMS_RevocationInfoChoice_find_ex(st, val) SKM_sk_find_ex(CMS_RevocationInfoChoice, (st), (val)) +#define sk_CMS_RevocationInfoChoice_delete(st, i) SKM_sk_delete(CMS_RevocationInfoChoice, (st), (i)) +#define sk_CMS_RevocationInfoChoice_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RevocationInfoChoice, (st), (ptr)) +#define sk_CMS_RevocationInfoChoice_insert(st, val, i) SKM_sk_insert(CMS_RevocationInfoChoice, (st), (val), (i)) +#define sk_CMS_RevocationInfoChoice_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RevocationInfoChoice, (st), (cmp)) +#define sk_CMS_RevocationInfoChoice_dup(st) SKM_sk_dup(CMS_RevocationInfoChoice, st) +#define sk_CMS_RevocationInfoChoice_pop_free(st, free_func) SKM_sk_pop_free(CMS_RevocationInfoChoice, (st), (free_func)) +#define sk_CMS_RevocationInfoChoice_shift(st) SKM_sk_shift(CMS_RevocationInfoChoice, (st)) +#define sk_CMS_RevocationInfoChoice_pop(st) SKM_sk_pop(CMS_RevocationInfoChoice, (st)) +#define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st)) +#define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st)) + +#define sk_CMS_SignerInfo_new(cmp) SKM_sk_new(CMS_SignerInfo, (cmp)) +#define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo) +#define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st)) +#define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st)) +#define sk_CMS_SignerInfo_value(st, i) SKM_sk_value(CMS_SignerInfo, (st), (i)) +#define sk_CMS_SignerInfo_set(st, i, val) SKM_sk_set(CMS_SignerInfo, (st), (i), (val)) +#define sk_CMS_SignerInfo_zero(st) SKM_sk_zero(CMS_SignerInfo, (st)) +#define sk_CMS_SignerInfo_push(st, val) SKM_sk_push(CMS_SignerInfo, (st), (val)) +#define sk_CMS_SignerInfo_unshift(st, val) SKM_sk_unshift(CMS_SignerInfo, (st), (val)) +#define sk_CMS_SignerInfo_find(st, val) SKM_sk_find(CMS_SignerInfo, (st), (val)) +#define sk_CMS_SignerInfo_find_ex(st, val) SKM_sk_find_ex(CMS_SignerInfo, (st), (val)) +#define sk_CMS_SignerInfo_delete(st, i) SKM_sk_delete(CMS_SignerInfo, (st), (i)) +#define sk_CMS_SignerInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_SignerInfo, (st), (ptr)) +#define sk_CMS_SignerInfo_insert(st, val, i) SKM_sk_insert(CMS_SignerInfo, (st), (val), (i)) +#define sk_CMS_SignerInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_SignerInfo, (st), (cmp)) +#define sk_CMS_SignerInfo_dup(st) SKM_sk_dup(CMS_SignerInfo, st) +#define sk_CMS_SignerInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_SignerInfo, (st), (free_func)) +#define sk_CMS_SignerInfo_shift(st) SKM_sk_shift(CMS_SignerInfo, (st)) +#define sk_CMS_SignerInfo_pop(st) SKM_sk_pop(CMS_SignerInfo, (st)) +#define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st)) +#define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st)) + +#define sk_CONF_IMODULE_new(cmp) SKM_sk_new(CONF_IMODULE, (cmp)) +#define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE) +#define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st)) +#define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st)) +#define sk_CONF_IMODULE_value(st, i) SKM_sk_value(CONF_IMODULE, (st), (i)) +#define sk_CONF_IMODULE_set(st, i, val) SKM_sk_set(CONF_IMODULE, (st), (i), (val)) +#define sk_CONF_IMODULE_zero(st) SKM_sk_zero(CONF_IMODULE, (st)) +#define sk_CONF_IMODULE_push(st, val) SKM_sk_push(CONF_IMODULE, (st), (val)) +#define sk_CONF_IMODULE_unshift(st, val) SKM_sk_unshift(CONF_IMODULE, (st), (val)) +#define sk_CONF_IMODULE_find(st, val) SKM_sk_find(CONF_IMODULE, (st), (val)) +#define sk_CONF_IMODULE_find_ex(st, val) SKM_sk_find_ex(CONF_IMODULE, (st), (val)) +#define sk_CONF_IMODULE_delete(st, i) SKM_sk_delete(CONF_IMODULE, (st), (i)) +#define sk_CONF_IMODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_IMODULE, (st), (ptr)) +#define sk_CONF_IMODULE_insert(st, val, i) SKM_sk_insert(CONF_IMODULE, (st), (val), (i)) +#define sk_CONF_IMODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_IMODULE, (st), (cmp)) +#define sk_CONF_IMODULE_dup(st) SKM_sk_dup(CONF_IMODULE, st) +#define sk_CONF_IMODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_IMODULE, (st), (free_func)) +#define sk_CONF_IMODULE_shift(st) SKM_sk_shift(CONF_IMODULE, (st)) +#define sk_CONF_IMODULE_pop(st) SKM_sk_pop(CONF_IMODULE, (st)) +#define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st)) +#define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st)) + +#define sk_CONF_MODULE_new(cmp) SKM_sk_new(CONF_MODULE, (cmp)) +#define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE) +#define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st)) +#define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st)) +#define sk_CONF_MODULE_value(st, i) SKM_sk_value(CONF_MODULE, (st), (i)) +#define sk_CONF_MODULE_set(st, i, val) SKM_sk_set(CONF_MODULE, (st), (i), (val)) +#define sk_CONF_MODULE_zero(st) SKM_sk_zero(CONF_MODULE, (st)) +#define sk_CONF_MODULE_push(st, val) SKM_sk_push(CONF_MODULE, (st), (val)) +#define sk_CONF_MODULE_unshift(st, val) SKM_sk_unshift(CONF_MODULE, (st), (val)) +#define sk_CONF_MODULE_find(st, val) SKM_sk_find(CONF_MODULE, (st), (val)) +#define sk_CONF_MODULE_find_ex(st, val) SKM_sk_find_ex(CONF_MODULE, (st), (val)) +#define sk_CONF_MODULE_delete(st, i) SKM_sk_delete(CONF_MODULE, (st), (i)) +#define sk_CONF_MODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_MODULE, (st), (ptr)) +#define sk_CONF_MODULE_insert(st, val, i) SKM_sk_insert(CONF_MODULE, (st), (val), (i)) +#define sk_CONF_MODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_MODULE, (st), (cmp)) +#define sk_CONF_MODULE_dup(st) SKM_sk_dup(CONF_MODULE, st) +#define sk_CONF_MODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_MODULE, (st), (free_func)) +#define sk_CONF_MODULE_shift(st) SKM_sk_shift(CONF_MODULE, (st)) +#define sk_CONF_MODULE_pop(st) SKM_sk_pop(CONF_MODULE, (st)) +#define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st)) +#define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st)) + +#define sk_CONF_VALUE_new(cmp) SKM_sk_new(CONF_VALUE, (cmp)) +#define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE) +#define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st)) +#define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st)) +#define sk_CONF_VALUE_value(st, i) SKM_sk_value(CONF_VALUE, (st), (i)) +#define sk_CONF_VALUE_set(st, i, val) SKM_sk_set(CONF_VALUE, (st), (i), (val)) +#define sk_CONF_VALUE_zero(st) SKM_sk_zero(CONF_VALUE, (st)) +#define sk_CONF_VALUE_push(st, val) SKM_sk_push(CONF_VALUE, (st), (val)) +#define sk_CONF_VALUE_unshift(st, val) SKM_sk_unshift(CONF_VALUE, (st), (val)) +#define sk_CONF_VALUE_find(st, val) SKM_sk_find(CONF_VALUE, (st), (val)) +#define sk_CONF_VALUE_find_ex(st, val) SKM_sk_find_ex(CONF_VALUE, (st), (val)) +#define sk_CONF_VALUE_delete(st, i) SKM_sk_delete(CONF_VALUE, (st), (i)) +#define sk_CONF_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_VALUE, (st), (ptr)) +#define sk_CONF_VALUE_insert(st, val, i) SKM_sk_insert(CONF_VALUE, (st), (val), (i)) +#define sk_CONF_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_VALUE, (st), (cmp)) +#define sk_CONF_VALUE_dup(st) SKM_sk_dup(CONF_VALUE, st) +#define sk_CONF_VALUE_pop_free(st, free_func) SKM_sk_pop_free(CONF_VALUE, (st), (free_func)) +#define sk_CONF_VALUE_shift(st) SKM_sk_shift(CONF_VALUE, (st)) +#define sk_CONF_VALUE_pop(st) SKM_sk_pop(CONF_VALUE, (st)) +#define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st)) +#define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st)) + +#define sk_CRYPTO_EX_DATA_FUNCS_new(cmp) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (cmp)) +#define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS) +#define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st)) +#define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st)) +#define sk_CRYPTO_EX_DATA_FUNCS_value(st, i) SKM_sk_value(CRYPTO_EX_DATA_FUNCS, (st), (i)) +#define sk_CRYPTO_EX_DATA_FUNCS_set(st, i, val) SKM_sk_set(CRYPTO_EX_DATA_FUNCS, (st), (i), (val)) +#define sk_CRYPTO_EX_DATA_FUNCS_zero(st) SKM_sk_zero(CRYPTO_EX_DATA_FUNCS, (st)) +#define sk_CRYPTO_EX_DATA_FUNCS_push(st, val) SKM_sk_push(CRYPTO_EX_DATA_FUNCS, (st), (val)) +#define sk_CRYPTO_EX_DATA_FUNCS_unshift(st, val) SKM_sk_unshift(CRYPTO_EX_DATA_FUNCS, (st), (val)) +#define sk_CRYPTO_EX_DATA_FUNCS_find(st, val) SKM_sk_find(CRYPTO_EX_DATA_FUNCS, (st), (val)) +#define sk_CRYPTO_EX_DATA_FUNCS_find_ex(st, val) SKM_sk_find_ex(CRYPTO_EX_DATA_FUNCS, (st), (val)) +#define sk_CRYPTO_EX_DATA_FUNCS_delete(st, i) SKM_sk_delete(CRYPTO_EX_DATA_FUNCS, (st), (i)) +#define sk_CRYPTO_EX_DATA_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_EX_DATA_FUNCS, (st), (ptr)) +#define sk_CRYPTO_EX_DATA_FUNCS_insert(st, val, i) SKM_sk_insert(CRYPTO_EX_DATA_FUNCS, (st), (val), (i)) +#define sk_CRYPTO_EX_DATA_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_EX_DATA_FUNCS, (st), (cmp)) +#define sk_CRYPTO_EX_DATA_FUNCS_dup(st) SKM_sk_dup(CRYPTO_EX_DATA_FUNCS, st) +#define sk_CRYPTO_EX_DATA_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_EX_DATA_FUNCS, (st), (free_func)) +#define sk_CRYPTO_EX_DATA_FUNCS_shift(st) SKM_sk_shift(CRYPTO_EX_DATA_FUNCS, (st)) +#define sk_CRYPTO_EX_DATA_FUNCS_pop(st) SKM_sk_pop(CRYPTO_EX_DATA_FUNCS, (st)) +#define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st)) +#define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st)) + +#define sk_CRYPTO_dynlock_new(cmp) SKM_sk_new(CRYPTO_dynlock, (cmp)) +#define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock) +#define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st)) +#define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st)) +#define sk_CRYPTO_dynlock_value(st, i) SKM_sk_value(CRYPTO_dynlock, (st), (i)) +#define sk_CRYPTO_dynlock_set(st, i, val) SKM_sk_set(CRYPTO_dynlock, (st), (i), (val)) +#define sk_CRYPTO_dynlock_zero(st) SKM_sk_zero(CRYPTO_dynlock, (st)) +#define sk_CRYPTO_dynlock_push(st, val) SKM_sk_push(CRYPTO_dynlock, (st), (val)) +#define sk_CRYPTO_dynlock_unshift(st, val) SKM_sk_unshift(CRYPTO_dynlock, (st), (val)) +#define sk_CRYPTO_dynlock_find(st, val) SKM_sk_find(CRYPTO_dynlock, (st), (val)) +#define sk_CRYPTO_dynlock_find_ex(st, val) SKM_sk_find_ex(CRYPTO_dynlock, (st), (val)) +#define sk_CRYPTO_dynlock_delete(st, i) SKM_sk_delete(CRYPTO_dynlock, (st), (i)) +#define sk_CRYPTO_dynlock_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_dynlock, (st), (ptr)) +#define sk_CRYPTO_dynlock_insert(st, val, i) SKM_sk_insert(CRYPTO_dynlock, (st), (val), (i)) +#define sk_CRYPTO_dynlock_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_dynlock, (st), (cmp)) +#define sk_CRYPTO_dynlock_dup(st) SKM_sk_dup(CRYPTO_dynlock, st) +#define sk_CRYPTO_dynlock_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_dynlock, (st), (free_func)) +#define sk_CRYPTO_dynlock_shift(st) SKM_sk_shift(CRYPTO_dynlock, (st)) +#define sk_CRYPTO_dynlock_pop(st) SKM_sk_pop(CRYPTO_dynlock, (st)) +#define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st)) +#define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st)) + +#define sk_DIST_POINT_new(cmp) SKM_sk_new(DIST_POINT, (cmp)) +#define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT) +#define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st)) +#define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st)) +#define sk_DIST_POINT_value(st, i) SKM_sk_value(DIST_POINT, (st), (i)) +#define sk_DIST_POINT_set(st, i, val) SKM_sk_set(DIST_POINT, (st), (i), (val)) +#define sk_DIST_POINT_zero(st) SKM_sk_zero(DIST_POINT, (st)) +#define sk_DIST_POINT_push(st, val) SKM_sk_push(DIST_POINT, (st), (val)) +#define sk_DIST_POINT_unshift(st, val) SKM_sk_unshift(DIST_POINT, (st), (val)) +#define sk_DIST_POINT_find(st, val) SKM_sk_find(DIST_POINT, (st), (val)) +#define sk_DIST_POINT_find_ex(st, val) SKM_sk_find_ex(DIST_POINT, (st), (val)) +#define sk_DIST_POINT_delete(st, i) SKM_sk_delete(DIST_POINT, (st), (i)) +#define sk_DIST_POINT_delete_ptr(st, ptr) SKM_sk_delete_ptr(DIST_POINT, (st), (ptr)) +#define sk_DIST_POINT_insert(st, val, i) SKM_sk_insert(DIST_POINT, (st), (val), (i)) +#define sk_DIST_POINT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(DIST_POINT, (st), (cmp)) +#define sk_DIST_POINT_dup(st) SKM_sk_dup(DIST_POINT, st) +#define sk_DIST_POINT_pop_free(st, free_func) SKM_sk_pop_free(DIST_POINT, (st), (free_func)) +#define sk_DIST_POINT_shift(st) SKM_sk_shift(DIST_POINT, (st)) +#define sk_DIST_POINT_pop(st) SKM_sk_pop(DIST_POINT, (st)) +#define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st)) +#define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st)) + +#define sk_ENGINE_new(cmp) SKM_sk_new(ENGINE, (cmp)) +#define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE) +#define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st)) +#define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st)) +#define sk_ENGINE_value(st, i) SKM_sk_value(ENGINE, (st), (i)) +#define sk_ENGINE_set(st, i, val) SKM_sk_set(ENGINE, (st), (i), (val)) +#define sk_ENGINE_zero(st) SKM_sk_zero(ENGINE, (st)) +#define sk_ENGINE_push(st, val) SKM_sk_push(ENGINE, (st), (val)) +#define sk_ENGINE_unshift(st, val) SKM_sk_unshift(ENGINE, (st), (val)) +#define sk_ENGINE_find(st, val) SKM_sk_find(ENGINE, (st), (val)) +#define sk_ENGINE_find_ex(st, val) SKM_sk_find_ex(ENGINE, (st), (val)) +#define sk_ENGINE_delete(st, i) SKM_sk_delete(ENGINE, (st), (i)) +#define sk_ENGINE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE, (st), (ptr)) +#define sk_ENGINE_insert(st, val, i) SKM_sk_insert(ENGINE, (st), (val), (i)) +#define sk_ENGINE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE, (st), (cmp)) +#define sk_ENGINE_dup(st) SKM_sk_dup(ENGINE, st) +#define sk_ENGINE_pop_free(st, free_func) SKM_sk_pop_free(ENGINE, (st), (free_func)) +#define sk_ENGINE_shift(st) SKM_sk_shift(ENGINE, (st)) +#define sk_ENGINE_pop(st) SKM_sk_pop(ENGINE, (st)) +#define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st)) +#define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st)) + +#define sk_ENGINE_CLEANUP_ITEM_new(cmp) SKM_sk_new(ENGINE_CLEANUP_ITEM, (cmp)) +#define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM) +#define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st)) +#define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st)) +#define sk_ENGINE_CLEANUP_ITEM_value(st, i) SKM_sk_value(ENGINE_CLEANUP_ITEM, (st), (i)) +#define sk_ENGINE_CLEANUP_ITEM_set(st, i, val) SKM_sk_set(ENGINE_CLEANUP_ITEM, (st), (i), (val)) +#define sk_ENGINE_CLEANUP_ITEM_zero(st) SKM_sk_zero(ENGINE_CLEANUP_ITEM, (st)) +#define sk_ENGINE_CLEANUP_ITEM_push(st, val) SKM_sk_push(ENGINE_CLEANUP_ITEM, (st), (val)) +#define sk_ENGINE_CLEANUP_ITEM_unshift(st, val) SKM_sk_unshift(ENGINE_CLEANUP_ITEM, (st), (val)) +#define sk_ENGINE_CLEANUP_ITEM_find(st, val) SKM_sk_find(ENGINE_CLEANUP_ITEM, (st), (val)) +#define sk_ENGINE_CLEANUP_ITEM_find_ex(st, val) SKM_sk_find_ex(ENGINE_CLEANUP_ITEM, (st), (val)) +#define sk_ENGINE_CLEANUP_ITEM_delete(st, i) SKM_sk_delete(ENGINE_CLEANUP_ITEM, (st), (i)) +#define sk_ENGINE_CLEANUP_ITEM_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE_CLEANUP_ITEM, (st), (ptr)) +#define sk_ENGINE_CLEANUP_ITEM_insert(st, val, i) SKM_sk_insert(ENGINE_CLEANUP_ITEM, (st), (val), (i)) +#define sk_ENGINE_CLEANUP_ITEM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE_CLEANUP_ITEM, (st), (cmp)) +#define sk_ENGINE_CLEANUP_ITEM_dup(st) SKM_sk_dup(ENGINE_CLEANUP_ITEM, st) +#define sk_ENGINE_CLEANUP_ITEM_pop_free(st, free_func) SKM_sk_pop_free(ENGINE_CLEANUP_ITEM, (st), (free_func)) +#define sk_ENGINE_CLEANUP_ITEM_shift(st) SKM_sk_shift(ENGINE_CLEANUP_ITEM, (st)) +#define sk_ENGINE_CLEANUP_ITEM_pop(st) SKM_sk_pop(ENGINE_CLEANUP_ITEM, (st)) +#define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st)) +#define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st)) + +#define sk_ESS_CERT_ID_new(cmp) SKM_sk_new(ESS_CERT_ID, (cmp)) +#define sk_ESS_CERT_ID_new_null() SKM_sk_new_null(ESS_CERT_ID) +#define sk_ESS_CERT_ID_free(st) SKM_sk_free(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_num(st) SKM_sk_num(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_value(st, i) SKM_sk_value(ESS_CERT_ID, (st), (i)) +#define sk_ESS_CERT_ID_set(st, i, val) SKM_sk_set(ESS_CERT_ID, (st), (i), (val)) +#define sk_ESS_CERT_ID_zero(st) SKM_sk_zero(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_push(st, val) SKM_sk_push(ESS_CERT_ID, (st), (val)) +#define sk_ESS_CERT_ID_unshift(st, val) SKM_sk_unshift(ESS_CERT_ID, (st), (val)) +#define sk_ESS_CERT_ID_find(st, val) SKM_sk_find(ESS_CERT_ID, (st), (val)) +#define sk_ESS_CERT_ID_find_ex(st, val) SKM_sk_find_ex(ESS_CERT_ID, (st), (val)) +#define sk_ESS_CERT_ID_delete(st, i) SKM_sk_delete(ESS_CERT_ID, (st), (i)) +#define sk_ESS_CERT_ID_delete_ptr(st, ptr) SKM_sk_delete_ptr(ESS_CERT_ID, (st), (ptr)) +#define sk_ESS_CERT_ID_insert(st, val, i) SKM_sk_insert(ESS_CERT_ID, (st), (val), (i)) +#define sk_ESS_CERT_ID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ESS_CERT_ID, (st), (cmp)) +#define sk_ESS_CERT_ID_dup(st) SKM_sk_dup(ESS_CERT_ID, st) +#define sk_ESS_CERT_ID_pop_free(st, free_func) SKM_sk_pop_free(ESS_CERT_ID, (st), (free_func)) +#define sk_ESS_CERT_ID_shift(st) SKM_sk_shift(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_pop(st) SKM_sk_pop(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_sort(st) SKM_sk_sort(ESS_CERT_ID, (st)) +#define sk_ESS_CERT_ID_is_sorted(st) SKM_sk_is_sorted(ESS_CERT_ID, (st)) + +#define sk_EVP_MD_new(cmp) SKM_sk_new(EVP_MD, (cmp)) +#define sk_EVP_MD_new_null() SKM_sk_new_null(EVP_MD) +#define sk_EVP_MD_free(st) SKM_sk_free(EVP_MD, (st)) +#define sk_EVP_MD_num(st) SKM_sk_num(EVP_MD, (st)) +#define sk_EVP_MD_value(st, i) SKM_sk_value(EVP_MD, (st), (i)) +#define sk_EVP_MD_set(st, i, val) SKM_sk_set(EVP_MD, (st), (i), (val)) +#define sk_EVP_MD_zero(st) SKM_sk_zero(EVP_MD, (st)) +#define sk_EVP_MD_push(st, val) SKM_sk_push(EVP_MD, (st), (val)) +#define sk_EVP_MD_unshift(st, val) SKM_sk_unshift(EVP_MD, (st), (val)) +#define sk_EVP_MD_find(st, val) SKM_sk_find(EVP_MD, (st), (val)) +#define sk_EVP_MD_find_ex(st, val) SKM_sk_find_ex(EVP_MD, (st), (val)) +#define sk_EVP_MD_delete(st, i) SKM_sk_delete(EVP_MD, (st), (i)) +#define sk_EVP_MD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_MD, (st), (ptr)) +#define sk_EVP_MD_insert(st, val, i) SKM_sk_insert(EVP_MD, (st), (val), (i)) +#define sk_EVP_MD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_MD, (st), (cmp)) +#define sk_EVP_MD_dup(st) SKM_sk_dup(EVP_MD, st) +#define sk_EVP_MD_pop_free(st, free_func) SKM_sk_pop_free(EVP_MD, (st), (free_func)) +#define sk_EVP_MD_shift(st) SKM_sk_shift(EVP_MD, (st)) +#define sk_EVP_MD_pop(st) SKM_sk_pop(EVP_MD, (st)) +#define sk_EVP_MD_sort(st) SKM_sk_sort(EVP_MD, (st)) +#define sk_EVP_MD_is_sorted(st) SKM_sk_is_sorted(EVP_MD, (st)) + +#define sk_EVP_PBE_CTL_new(cmp) SKM_sk_new(EVP_PBE_CTL, (cmp)) +#define sk_EVP_PBE_CTL_new_null() SKM_sk_new_null(EVP_PBE_CTL) +#define sk_EVP_PBE_CTL_free(st) SKM_sk_free(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_num(st) SKM_sk_num(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_value(st, i) SKM_sk_value(EVP_PBE_CTL, (st), (i)) +#define sk_EVP_PBE_CTL_set(st, i, val) SKM_sk_set(EVP_PBE_CTL, (st), (i), (val)) +#define sk_EVP_PBE_CTL_zero(st) SKM_sk_zero(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_push(st, val) SKM_sk_push(EVP_PBE_CTL, (st), (val)) +#define sk_EVP_PBE_CTL_unshift(st, val) SKM_sk_unshift(EVP_PBE_CTL, (st), (val)) +#define sk_EVP_PBE_CTL_find(st, val) SKM_sk_find(EVP_PBE_CTL, (st), (val)) +#define sk_EVP_PBE_CTL_find_ex(st, val) SKM_sk_find_ex(EVP_PBE_CTL, (st), (val)) +#define sk_EVP_PBE_CTL_delete(st, i) SKM_sk_delete(EVP_PBE_CTL, (st), (i)) +#define sk_EVP_PBE_CTL_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PBE_CTL, (st), (ptr)) +#define sk_EVP_PBE_CTL_insert(st, val, i) SKM_sk_insert(EVP_PBE_CTL, (st), (val), (i)) +#define sk_EVP_PBE_CTL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PBE_CTL, (st), (cmp)) +#define sk_EVP_PBE_CTL_dup(st) SKM_sk_dup(EVP_PBE_CTL, st) +#define sk_EVP_PBE_CTL_pop_free(st, free_func) SKM_sk_pop_free(EVP_PBE_CTL, (st), (free_func)) +#define sk_EVP_PBE_CTL_shift(st) SKM_sk_shift(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_pop(st) SKM_sk_pop(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_sort(st) SKM_sk_sort(EVP_PBE_CTL, (st)) +#define sk_EVP_PBE_CTL_is_sorted(st) SKM_sk_is_sorted(EVP_PBE_CTL, (st)) + +#define sk_EVP_PKEY_ASN1_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_ASN1_METHOD, (cmp)) +#define sk_EVP_PKEY_ASN1_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_ASN1_METHOD) +#define sk_EVP_PKEY_ASN1_METHOD_free(st) SKM_sk_free(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_num(st) SKM_sk_num(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_ASN1_METHOD, (st), (i)) +#define sk_EVP_PKEY_ASN1_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_ASN1_METHOD, (st), (i), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_ASN1_METHOD, (st), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_ASN1_METHOD, (st), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_ASN1_METHOD, (st), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_ASN1_METHOD, (st), (val)) +#define sk_EVP_PKEY_ASN1_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_ASN1_METHOD, (st), (i)) +#define sk_EVP_PKEY_ASN1_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_ASN1_METHOD, (st), (ptr)) +#define sk_EVP_PKEY_ASN1_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_ASN1_METHOD, (st), (val), (i)) +#define sk_EVP_PKEY_ASN1_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_ASN1_METHOD, (st), (cmp)) +#define sk_EVP_PKEY_ASN1_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_ASN1_METHOD, st) +#define sk_EVP_PKEY_ASN1_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_ASN1_METHOD, (st), (free_func)) +#define sk_EVP_PKEY_ASN1_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_ASN1_METHOD, (st)) +#define sk_EVP_PKEY_ASN1_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_ASN1_METHOD, (st)) + +#define sk_EVP_PKEY_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_METHOD, (cmp)) +#define sk_EVP_PKEY_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_METHOD) +#define sk_EVP_PKEY_METHOD_free(st) SKM_sk_free(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_num(st) SKM_sk_num(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_METHOD, (st), (i)) +#define sk_EVP_PKEY_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_METHOD, (st), (i), (val)) +#define sk_EVP_PKEY_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_METHOD, (st), (val)) +#define sk_EVP_PKEY_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_METHOD, (st), (val)) +#define sk_EVP_PKEY_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_METHOD, (st), (val)) +#define sk_EVP_PKEY_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_METHOD, (st), (val)) +#define sk_EVP_PKEY_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_METHOD, (st), (i)) +#define sk_EVP_PKEY_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_METHOD, (st), (ptr)) +#define sk_EVP_PKEY_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_METHOD, (st), (val), (i)) +#define sk_EVP_PKEY_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_METHOD, (st), (cmp)) +#define sk_EVP_PKEY_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_METHOD, st) +#define sk_EVP_PKEY_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_METHOD, (st), (free_func)) +#define sk_EVP_PKEY_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_METHOD, (st)) +#define sk_EVP_PKEY_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_METHOD, (st)) + +#define sk_GENERAL_NAME_new(cmp) SKM_sk_new(GENERAL_NAME, (cmp)) +#define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME) +#define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st)) +#define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st)) +#define sk_GENERAL_NAME_value(st, i) SKM_sk_value(GENERAL_NAME, (st), (i)) +#define sk_GENERAL_NAME_set(st, i, val) SKM_sk_set(GENERAL_NAME, (st), (i), (val)) +#define sk_GENERAL_NAME_zero(st) SKM_sk_zero(GENERAL_NAME, (st)) +#define sk_GENERAL_NAME_push(st, val) SKM_sk_push(GENERAL_NAME, (st), (val)) +#define sk_GENERAL_NAME_unshift(st, val) SKM_sk_unshift(GENERAL_NAME, (st), (val)) +#define sk_GENERAL_NAME_find(st, val) SKM_sk_find(GENERAL_NAME, (st), (val)) +#define sk_GENERAL_NAME_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAME, (st), (val)) +#define sk_GENERAL_NAME_delete(st, i) SKM_sk_delete(GENERAL_NAME, (st), (i)) +#define sk_GENERAL_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAME, (st), (ptr)) +#define sk_GENERAL_NAME_insert(st, val, i) SKM_sk_insert(GENERAL_NAME, (st), (val), (i)) +#define sk_GENERAL_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAME, (st), (cmp)) +#define sk_GENERAL_NAME_dup(st) SKM_sk_dup(GENERAL_NAME, st) +#define sk_GENERAL_NAME_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAME, (st), (free_func)) +#define sk_GENERAL_NAME_shift(st) SKM_sk_shift(GENERAL_NAME, (st)) +#define sk_GENERAL_NAME_pop(st) SKM_sk_pop(GENERAL_NAME, (st)) +#define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st)) +#define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st)) + +#define sk_GENERAL_NAMES_new(cmp) SKM_sk_new(GENERAL_NAMES, (cmp)) +#define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES) +#define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st)) +#define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st)) +#define sk_GENERAL_NAMES_value(st, i) SKM_sk_value(GENERAL_NAMES, (st), (i)) +#define sk_GENERAL_NAMES_set(st, i, val) SKM_sk_set(GENERAL_NAMES, (st), (i), (val)) +#define sk_GENERAL_NAMES_zero(st) SKM_sk_zero(GENERAL_NAMES, (st)) +#define sk_GENERAL_NAMES_push(st, val) SKM_sk_push(GENERAL_NAMES, (st), (val)) +#define sk_GENERAL_NAMES_unshift(st, val) SKM_sk_unshift(GENERAL_NAMES, (st), (val)) +#define sk_GENERAL_NAMES_find(st, val) SKM_sk_find(GENERAL_NAMES, (st), (val)) +#define sk_GENERAL_NAMES_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAMES, (st), (val)) +#define sk_GENERAL_NAMES_delete(st, i) SKM_sk_delete(GENERAL_NAMES, (st), (i)) +#define sk_GENERAL_NAMES_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAMES, (st), (ptr)) +#define sk_GENERAL_NAMES_insert(st, val, i) SKM_sk_insert(GENERAL_NAMES, (st), (val), (i)) +#define sk_GENERAL_NAMES_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAMES, (st), (cmp)) +#define sk_GENERAL_NAMES_dup(st) SKM_sk_dup(GENERAL_NAMES, st) +#define sk_GENERAL_NAMES_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAMES, (st), (free_func)) +#define sk_GENERAL_NAMES_shift(st) SKM_sk_shift(GENERAL_NAMES, (st)) +#define sk_GENERAL_NAMES_pop(st) SKM_sk_pop(GENERAL_NAMES, (st)) +#define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st)) +#define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st)) + +#define sk_GENERAL_SUBTREE_new(cmp) SKM_sk_new(GENERAL_SUBTREE, (cmp)) +#define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE) +#define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st)) +#define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st)) +#define sk_GENERAL_SUBTREE_value(st, i) SKM_sk_value(GENERAL_SUBTREE, (st), (i)) +#define sk_GENERAL_SUBTREE_set(st, i, val) SKM_sk_set(GENERAL_SUBTREE, (st), (i), (val)) +#define sk_GENERAL_SUBTREE_zero(st) SKM_sk_zero(GENERAL_SUBTREE, (st)) +#define sk_GENERAL_SUBTREE_push(st, val) SKM_sk_push(GENERAL_SUBTREE, (st), (val)) +#define sk_GENERAL_SUBTREE_unshift(st, val) SKM_sk_unshift(GENERAL_SUBTREE, (st), (val)) +#define sk_GENERAL_SUBTREE_find(st, val) SKM_sk_find(GENERAL_SUBTREE, (st), (val)) +#define sk_GENERAL_SUBTREE_find_ex(st, val) SKM_sk_find_ex(GENERAL_SUBTREE, (st), (val)) +#define sk_GENERAL_SUBTREE_delete(st, i) SKM_sk_delete(GENERAL_SUBTREE, (st), (i)) +#define sk_GENERAL_SUBTREE_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_SUBTREE, (st), (ptr)) +#define sk_GENERAL_SUBTREE_insert(st, val, i) SKM_sk_insert(GENERAL_SUBTREE, (st), (val), (i)) +#define sk_GENERAL_SUBTREE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_SUBTREE, (st), (cmp)) +#define sk_GENERAL_SUBTREE_dup(st) SKM_sk_dup(GENERAL_SUBTREE, st) +#define sk_GENERAL_SUBTREE_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_SUBTREE, (st), (free_func)) +#define sk_GENERAL_SUBTREE_shift(st) SKM_sk_shift(GENERAL_SUBTREE, (st)) +#define sk_GENERAL_SUBTREE_pop(st) SKM_sk_pop(GENERAL_SUBTREE, (st)) +#define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st)) +#define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st)) + +#define sk_IPAddressFamily_new(cmp) SKM_sk_new(IPAddressFamily, (cmp)) +#define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily) +#define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st)) +#define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st)) +#define sk_IPAddressFamily_value(st, i) SKM_sk_value(IPAddressFamily, (st), (i)) +#define sk_IPAddressFamily_set(st, i, val) SKM_sk_set(IPAddressFamily, (st), (i), (val)) +#define sk_IPAddressFamily_zero(st) SKM_sk_zero(IPAddressFamily, (st)) +#define sk_IPAddressFamily_push(st, val) SKM_sk_push(IPAddressFamily, (st), (val)) +#define sk_IPAddressFamily_unshift(st, val) SKM_sk_unshift(IPAddressFamily, (st), (val)) +#define sk_IPAddressFamily_find(st, val) SKM_sk_find(IPAddressFamily, (st), (val)) +#define sk_IPAddressFamily_find_ex(st, val) SKM_sk_find_ex(IPAddressFamily, (st), (val)) +#define sk_IPAddressFamily_delete(st, i) SKM_sk_delete(IPAddressFamily, (st), (i)) +#define sk_IPAddressFamily_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressFamily, (st), (ptr)) +#define sk_IPAddressFamily_insert(st, val, i) SKM_sk_insert(IPAddressFamily, (st), (val), (i)) +#define sk_IPAddressFamily_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressFamily, (st), (cmp)) +#define sk_IPAddressFamily_dup(st) SKM_sk_dup(IPAddressFamily, st) +#define sk_IPAddressFamily_pop_free(st, free_func) SKM_sk_pop_free(IPAddressFamily, (st), (free_func)) +#define sk_IPAddressFamily_shift(st) SKM_sk_shift(IPAddressFamily, (st)) +#define sk_IPAddressFamily_pop(st) SKM_sk_pop(IPAddressFamily, (st)) +#define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st)) +#define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st)) + +#define sk_IPAddressOrRange_new(cmp) SKM_sk_new(IPAddressOrRange, (cmp)) +#define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange) +#define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st)) +#define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st)) +#define sk_IPAddressOrRange_value(st, i) SKM_sk_value(IPAddressOrRange, (st), (i)) +#define sk_IPAddressOrRange_set(st, i, val) SKM_sk_set(IPAddressOrRange, (st), (i), (val)) +#define sk_IPAddressOrRange_zero(st) SKM_sk_zero(IPAddressOrRange, (st)) +#define sk_IPAddressOrRange_push(st, val) SKM_sk_push(IPAddressOrRange, (st), (val)) +#define sk_IPAddressOrRange_unshift(st, val) SKM_sk_unshift(IPAddressOrRange, (st), (val)) +#define sk_IPAddressOrRange_find(st, val) SKM_sk_find(IPAddressOrRange, (st), (val)) +#define sk_IPAddressOrRange_find_ex(st, val) SKM_sk_find_ex(IPAddressOrRange, (st), (val)) +#define sk_IPAddressOrRange_delete(st, i) SKM_sk_delete(IPAddressOrRange, (st), (i)) +#define sk_IPAddressOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressOrRange, (st), (ptr)) +#define sk_IPAddressOrRange_insert(st, val, i) SKM_sk_insert(IPAddressOrRange, (st), (val), (i)) +#define sk_IPAddressOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressOrRange, (st), (cmp)) +#define sk_IPAddressOrRange_dup(st) SKM_sk_dup(IPAddressOrRange, st) +#define sk_IPAddressOrRange_pop_free(st, free_func) SKM_sk_pop_free(IPAddressOrRange, (st), (free_func)) +#define sk_IPAddressOrRange_shift(st) SKM_sk_shift(IPAddressOrRange, (st)) +#define sk_IPAddressOrRange_pop(st) SKM_sk_pop(IPAddressOrRange, (st)) +#define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st)) +#define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st)) + +#define sk_KRB5_APREQBODY_new(cmp) SKM_sk_new(KRB5_APREQBODY, (cmp)) +#define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY) +#define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st)) +#define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st)) +#define sk_KRB5_APREQBODY_value(st, i) SKM_sk_value(KRB5_APREQBODY, (st), (i)) +#define sk_KRB5_APREQBODY_set(st, i, val) SKM_sk_set(KRB5_APREQBODY, (st), (i), (val)) +#define sk_KRB5_APREQBODY_zero(st) SKM_sk_zero(KRB5_APREQBODY, (st)) +#define sk_KRB5_APREQBODY_push(st, val) SKM_sk_push(KRB5_APREQBODY, (st), (val)) +#define sk_KRB5_APREQBODY_unshift(st, val) SKM_sk_unshift(KRB5_APREQBODY, (st), (val)) +#define sk_KRB5_APREQBODY_find(st, val) SKM_sk_find(KRB5_APREQBODY, (st), (val)) +#define sk_KRB5_APREQBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_APREQBODY, (st), (val)) +#define sk_KRB5_APREQBODY_delete(st, i) SKM_sk_delete(KRB5_APREQBODY, (st), (i)) +#define sk_KRB5_APREQBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_APREQBODY, (st), (ptr)) +#define sk_KRB5_APREQBODY_insert(st, val, i) SKM_sk_insert(KRB5_APREQBODY, (st), (val), (i)) +#define sk_KRB5_APREQBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_APREQBODY, (st), (cmp)) +#define sk_KRB5_APREQBODY_dup(st) SKM_sk_dup(KRB5_APREQBODY, st) +#define sk_KRB5_APREQBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_APREQBODY, (st), (free_func)) +#define sk_KRB5_APREQBODY_shift(st) SKM_sk_shift(KRB5_APREQBODY, (st)) +#define sk_KRB5_APREQBODY_pop(st) SKM_sk_pop(KRB5_APREQBODY, (st)) +#define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st)) +#define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st)) + +#define sk_KRB5_AUTHDATA_new(cmp) SKM_sk_new(KRB5_AUTHDATA, (cmp)) +#define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA) +#define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st)) +#define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st)) +#define sk_KRB5_AUTHDATA_value(st, i) SKM_sk_value(KRB5_AUTHDATA, (st), (i)) +#define sk_KRB5_AUTHDATA_set(st, i, val) SKM_sk_set(KRB5_AUTHDATA, (st), (i), (val)) +#define sk_KRB5_AUTHDATA_zero(st) SKM_sk_zero(KRB5_AUTHDATA, (st)) +#define sk_KRB5_AUTHDATA_push(st, val) SKM_sk_push(KRB5_AUTHDATA, (st), (val)) +#define sk_KRB5_AUTHDATA_unshift(st, val) SKM_sk_unshift(KRB5_AUTHDATA, (st), (val)) +#define sk_KRB5_AUTHDATA_find(st, val) SKM_sk_find(KRB5_AUTHDATA, (st), (val)) +#define sk_KRB5_AUTHDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHDATA, (st), (val)) +#define sk_KRB5_AUTHDATA_delete(st, i) SKM_sk_delete(KRB5_AUTHDATA, (st), (i)) +#define sk_KRB5_AUTHDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHDATA, (st), (ptr)) +#define sk_KRB5_AUTHDATA_insert(st, val, i) SKM_sk_insert(KRB5_AUTHDATA, (st), (val), (i)) +#define sk_KRB5_AUTHDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHDATA, (st), (cmp)) +#define sk_KRB5_AUTHDATA_dup(st) SKM_sk_dup(KRB5_AUTHDATA, st) +#define sk_KRB5_AUTHDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHDATA, (st), (free_func)) +#define sk_KRB5_AUTHDATA_shift(st) SKM_sk_shift(KRB5_AUTHDATA, (st)) +#define sk_KRB5_AUTHDATA_pop(st) SKM_sk_pop(KRB5_AUTHDATA, (st)) +#define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st)) +#define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st)) + +#define sk_KRB5_AUTHENTBODY_new(cmp) SKM_sk_new(KRB5_AUTHENTBODY, (cmp)) +#define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY) +#define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st)) +#define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st)) +#define sk_KRB5_AUTHENTBODY_value(st, i) SKM_sk_value(KRB5_AUTHENTBODY, (st), (i)) +#define sk_KRB5_AUTHENTBODY_set(st, i, val) SKM_sk_set(KRB5_AUTHENTBODY, (st), (i), (val)) +#define sk_KRB5_AUTHENTBODY_zero(st) SKM_sk_zero(KRB5_AUTHENTBODY, (st)) +#define sk_KRB5_AUTHENTBODY_push(st, val) SKM_sk_push(KRB5_AUTHENTBODY, (st), (val)) +#define sk_KRB5_AUTHENTBODY_unshift(st, val) SKM_sk_unshift(KRB5_AUTHENTBODY, (st), (val)) +#define sk_KRB5_AUTHENTBODY_find(st, val) SKM_sk_find(KRB5_AUTHENTBODY, (st), (val)) +#define sk_KRB5_AUTHENTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHENTBODY, (st), (val)) +#define sk_KRB5_AUTHENTBODY_delete(st, i) SKM_sk_delete(KRB5_AUTHENTBODY, (st), (i)) +#define sk_KRB5_AUTHENTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHENTBODY, (st), (ptr)) +#define sk_KRB5_AUTHENTBODY_insert(st, val, i) SKM_sk_insert(KRB5_AUTHENTBODY, (st), (val), (i)) +#define sk_KRB5_AUTHENTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHENTBODY, (st), (cmp)) +#define sk_KRB5_AUTHENTBODY_dup(st) SKM_sk_dup(KRB5_AUTHENTBODY, st) +#define sk_KRB5_AUTHENTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHENTBODY, (st), (free_func)) +#define sk_KRB5_AUTHENTBODY_shift(st) SKM_sk_shift(KRB5_AUTHENTBODY, (st)) +#define sk_KRB5_AUTHENTBODY_pop(st) SKM_sk_pop(KRB5_AUTHENTBODY, (st)) +#define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st)) +#define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st)) + +#define sk_KRB5_CHECKSUM_new(cmp) SKM_sk_new(KRB5_CHECKSUM, (cmp)) +#define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM) +#define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st)) +#define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st)) +#define sk_KRB5_CHECKSUM_value(st, i) SKM_sk_value(KRB5_CHECKSUM, (st), (i)) +#define sk_KRB5_CHECKSUM_set(st, i, val) SKM_sk_set(KRB5_CHECKSUM, (st), (i), (val)) +#define sk_KRB5_CHECKSUM_zero(st) SKM_sk_zero(KRB5_CHECKSUM, (st)) +#define sk_KRB5_CHECKSUM_push(st, val) SKM_sk_push(KRB5_CHECKSUM, (st), (val)) +#define sk_KRB5_CHECKSUM_unshift(st, val) SKM_sk_unshift(KRB5_CHECKSUM, (st), (val)) +#define sk_KRB5_CHECKSUM_find(st, val) SKM_sk_find(KRB5_CHECKSUM, (st), (val)) +#define sk_KRB5_CHECKSUM_find_ex(st, val) SKM_sk_find_ex(KRB5_CHECKSUM, (st), (val)) +#define sk_KRB5_CHECKSUM_delete(st, i) SKM_sk_delete(KRB5_CHECKSUM, (st), (i)) +#define sk_KRB5_CHECKSUM_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_CHECKSUM, (st), (ptr)) +#define sk_KRB5_CHECKSUM_insert(st, val, i) SKM_sk_insert(KRB5_CHECKSUM, (st), (val), (i)) +#define sk_KRB5_CHECKSUM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_CHECKSUM, (st), (cmp)) +#define sk_KRB5_CHECKSUM_dup(st) SKM_sk_dup(KRB5_CHECKSUM, st) +#define sk_KRB5_CHECKSUM_pop_free(st, free_func) SKM_sk_pop_free(KRB5_CHECKSUM, (st), (free_func)) +#define sk_KRB5_CHECKSUM_shift(st) SKM_sk_shift(KRB5_CHECKSUM, (st)) +#define sk_KRB5_CHECKSUM_pop(st) SKM_sk_pop(KRB5_CHECKSUM, (st)) +#define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st)) +#define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st)) + +#define sk_KRB5_ENCDATA_new(cmp) SKM_sk_new(KRB5_ENCDATA, (cmp)) +#define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA) +#define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st)) +#define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st)) +#define sk_KRB5_ENCDATA_value(st, i) SKM_sk_value(KRB5_ENCDATA, (st), (i)) +#define sk_KRB5_ENCDATA_set(st, i, val) SKM_sk_set(KRB5_ENCDATA, (st), (i), (val)) +#define sk_KRB5_ENCDATA_zero(st) SKM_sk_zero(KRB5_ENCDATA, (st)) +#define sk_KRB5_ENCDATA_push(st, val) SKM_sk_push(KRB5_ENCDATA, (st), (val)) +#define sk_KRB5_ENCDATA_unshift(st, val) SKM_sk_unshift(KRB5_ENCDATA, (st), (val)) +#define sk_KRB5_ENCDATA_find(st, val) SKM_sk_find(KRB5_ENCDATA, (st), (val)) +#define sk_KRB5_ENCDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCDATA, (st), (val)) +#define sk_KRB5_ENCDATA_delete(st, i) SKM_sk_delete(KRB5_ENCDATA, (st), (i)) +#define sk_KRB5_ENCDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCDATA, (st), (ptr)) +#define sk_KRB5_ENCDATA_insert(st, val, i) SKM_sk_insert(KRB5_ENCDATA, (st), (val), (i)) +#define sk_KRB5_ENCDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCDATA, (st), (cmp)) +#define sk_KRB5_ENCDATA_dup(st) SKM_sk_dup(KRB5_ENCDATA, st) +#define sk_KRB5_ENCDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCDATA, (st), (free_func)) +#define sk_KRB5_ENCDATA_shift(st) SKM_sk_shift(KRB5_ENCDATA, (st)) +#define sk_KRB5_ENCDATA_pop(st) SKM_sk_pop(KRB5_ENCDATA, (st)) +#define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st)) +#define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st)) + +#define sk_KRB5_ENCKEY_new(cmp) SKM_sk_new(KRB5_ENCKEY, (cmp)) +#define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY) +#define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st)) +#define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st)) +#define sk_KRB5_ENCKEY_value(st, i) SKM_sk_value(KRB5_ENCKEY, (st), (i)) +#define sk_KRB5_ENCKEY_set(st, i, val) SKM_sk_set(KRB5_ENCKEY, (st), (i), (val)) +#define sk_KRB5_ENCKEY_zero(st) SKM_sk_zero(KRB5_ENCKEY, (st)) +#define sk_KRB5_ENCKEY_push(st, val) SKM_sk_push(KRB5_ENCKEY, (st), (val)) +#define sk_KRB5_ENCKEY_unshift(st, val) SKM_sk_unshift(KRB5_ENCKEY, (st), (val)) +#define sk_KRB5_ENCKEY_find(st, val) SKM_sk_find(KRB5_ENCKEY, (st), (val)) +#define sk_KRB5_ENCKEY_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCKEY, (st), (val)) +#define sk_KRB5_ENCKEY_delete(st, i) SKM_sk_delete(KRB5_ENCKEY, (st), (i)) +#define sk_KRB5_ENCKEY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCKEY, (st), (ptr)) +#define sk_KRB5_ENCKEY_insert(st, val, i) SKM_sk_insert(KRB5_ENCKEY, (st), (val), (i)) +#define sk_KRB5_ENCKEY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCKEY, (st), (cmp)) +#define sk_KRB5_ENCKEY_dup(st) SKM_sk_dup(KRB5_ENCKEY, st) +#define sk_KRB5_ENCKEY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCKEY, (st), (free_func)) +#define sk_KRB5_ENCKEY_shift(st) SKM_sk_shift(KRB5_ENCKEY, (st)) +#define sk_KRB5_ENCKEY_pop(st) SKM_sk_pop(KRB5_ENCKEY, (st)) +#define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st)) +#define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st)) + +#define sk_KRB5_PRINCNAME_new(cmp) SKM_sk_new(KRB5_PRINCNAME, (cmp)) +#define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME) +#define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st)) +#define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st)) +#define sk_KRB5_PRINCNAME_value(st, i) SKM_sk_value(KRB5_PRINCNAME, (st), (i)) +#define sk_KRB5_PRINCNAME_set(st, i, val) SKM_sk_set(KRB5_PRINCNAME, (st), (i), (val)) +#define sk_KRB5_PRINCNAME_zero(st) SKM_sk_zero(KRB5_PRINCNAME, (st)) +#define sk_KRB5_PRINCNAME_push(st, val) SKM_sk_push(KRB5_PRINCNAME, (st), (val)) +#define sk_KRB5_PRINCNAME_unshift(st, val) SKM_sk_unshift(KRB5_PRINCNAME, (st), (val)) +#define sk_KRB5_PRINCNAME_find(st, val) SKM_sk_find(KRB5_PRINCNAME, (st), (val)) +#define sk_KRB5_PRINCNAME_find_ex(st, val) SKM_sk_find_ex(KRB5_PRINCNAME, (st), (val)) +#define sk_KRB5_PRINCNAME_delete(st, i) SKM_sk_delete(KRB5_PRINCNAME, (st), (i)) +#define sk_KRB5_PRINCNAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_PRINCNAME, (st), (ptr)) +#define sk_KRB5_PRINCNAME_insert(st, val, i) SKM_sk_insert(KRB5_PRINCNAME, (st), (val), (i)) +#define sk_KRB5_PRINCNAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_PRINCNAME, (st), (cmp)) +#define sk_KRB5_PRINCNAME_dup(st) SKM_sk_dup(KRB5_PRINCNAME, st) +#define sk_KRB5_PRINCNAME_pop_free(st, free_func) SKM_sk_pop_free(KRB5_PRINCNAME, (st), (free_func)) +#define sk_KRB5_PRINCNAME_shift(st) SKM_sk_shift(KRB5_PRINCNAME, (st)) +#define sk_KRB5_PRINCNAME_pop(st) SKM_sk_pop(KRB5_PRINCNAME, (st)) +#define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st)) +#define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st)) + +#define sk_KRB5_TKTBODY_new(cmp) SKM_sk_new(KRB5_TKTBODY, (cmp)) +#define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY) +#define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st)) +#define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st)) +#define sk_KRB5_TKTBODY_value(st, i) SKM_sk_value(KRB5_TKTBODY, (st), (i)) +#define sk_KRB5_TKTBODY_set(st, i, val) SKM_sk_set(KRB5_TKTBODY, (st), (i), (val)) +#define sk_KRB5_TKTBODY_zero(st) SKM_sk_zero(KRB5_TKTBODY, (st)) +#define sk_KRB5_TKTBODY_push(st, val) SKM_sk_push(KRB5_TKTBODY, (st), (val)) +#define sk_KRB5_TKTBODY_unshift(st, val) SKM_sk_unshift(KRB5_TKTBODY, (st), (val)) +#define sk_KRB5_TKTBODY_find(st, val) SKM_sk_find(KRB5_TKTBODY, (st), (val)) +#define sk_KRB5_TKTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_TKTBODY, (st), (val)) +#define sk_KRB5_TKTBODY_delete(st, i) SKM_sk_delete(KRB5_TKTBODY, (st), (i)) +#define sk_KRB5_TKTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_TKTBODY, (st), (ptr)) +#define sk_KRB5_TKTBODY_insert(st, val, i) SKM_sk_insert(KRB5_TKTBODY, (st), (val), (i)) +#define sk_KRB5_TKTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_TKTBODY, (st), (cmp)) +#define sk_KRB5_TKTBODY_dup(st) SKM_sk_dup(KRB5_TKTBODY, st) +#define sk_KRB5_TKTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_TKTBODY, (st), (free_func)) +#define sk_KRB5_TKTBODY_shift(st) SKM_sk_shift(KRB5_TKTBODY, (st)) +#define sk_KRB5_TKTBODY_pop(st) SKM_sk_pop(KRB5_TKTBODY, (st)) +#define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st)) +#define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st)) + +#define sk_MEM_OBJECT_DATA_new(cmp) SKM_sk_new(MEM_OBJECT_DATA, (cmp)) +#define sk_MEM_OBJECT_DATA_new_null() SKM_sk_new_null(MEM_OBJECT_DATA) +#define sk_MEM_OBJECT_DATA_free(st) SKM_sk_free(MEM_OBJECT_DATA, (st)) +#define sk_MEM_OBJECT_DATA_num(st) SKM_sk_num(MEM_OBJECT_DATA, (st)) +#define sk_MEM_OBJECT_DATA_value(st, i) SKM_sk_value(MEM_OBJECT_DATA, (st), (i)) +#define sk_MEM_OBJECT_DATA_set(st, i, val) SKM_sk_set(MEM_OBJECT_DATA, (st), (i), (val)) +#define sk_MEM_OBJECT_DATA_zero(st) SKM_sk_zero(MEM_OBJECT_DATA, (st)) +#define sk_MEM_OBJECT_DATA_push(st, val) SKM_sk_push(MEM_OBJECT_DATA, (st), (val)) +#define sk_MEM_OBJECT_DATA_unshift(st, val) SKM_sk_unshift(MEM_OBJECT_DATA, (st), (val)) +#define sk_MEM_OBJECT_DATA_find(st, val) SKM_sk_find(MEM_OBJECT_DATA, (st), (val)) +#define sk_MEM_OBJECT_DATA_find_ex(st, val) SKM_sk_find_ex(MEM_OBJECT_DATA, (st), (val)) +#define sk_MEM_OBJECT_DATA_delete(st, i) SKM_sk_delete(MEM_OBJECT_DATA, (st), (i)) +#define sk_MEM_OBJECT_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(MEM_OBJECT_DATA, (st), (ptr)) +#define sk_MEM_OBJECT_DATA_insert(st, val, i) SKM_sk_insert(MEM_OBJECT_DATA, (st), (val), (i)) +#define sk_MEM_OBJECT_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MEM_OBJECT_DATA, (st), (cmp)) +#define sk_MEM_OBJECT_DATA_dup(st) SKM_sk_dup(MEM_OBJECT_DATA, st) +#define sk_MEM_OBJECT_DATA_pop_free(st, free_func) SKM_sk_pop_free(MEM_OBJECT_DATA, (st), (free_func)) +#define sk_MEM_OBJECT_DATA_shift(st) SKM_sk_shift(MEM_OBJECT_DATA, (st)) +#define sk_MEM_OBJECT_DATA_pop(st) SKM_sk_pop(MEM_OBJECT_DATA, (st)) +#define sk_MEM_OBJECT_DATA_sort(st) SKM_sk_sort(MEM_OBJECT_DATA, (st)) +#define sk_MEM_OBJECT_DATA_is_sorted(st) SKM_sk_is_sorted(MEM_OBJECT_DATA, (st)) + +#define sk_MIME_HEADER_new(cmp) SKM_sk_new(MIME_HEADER, (cmp)) +#define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER) +#define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st)) +#define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st)) +#define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i)) +#define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val)) +#define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st)) +#define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val)) +#define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val)) +#define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val)) +#define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val)) +#define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i)) +#define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr)) +#define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i)) +#define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp)) +#define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st) +#define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func)) +#define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st)) +#define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st)) +#define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st)) +#define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st)) + +#define sk_MIME_PARAM_new(cmp) SKM_sk_new(MIME_PARAM, (cmp)) +#define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM) +#define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st)) +#define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st)) +#define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i)) +#define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val)) +#define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st)) +#define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val)) +#define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val)) +#define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val)) +#define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val)) +#define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i)) +#define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr)) +#define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i)) +#define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp)) +#define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st) +#define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func)) +#define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st)) +#define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st)) +#define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st)) +#define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st)) + +#define sk_NAME_FUNCS_new(cmp) SKM_sk_new(NAME_FUNCS, (cmp)) +#define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS) +#define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st)) +#define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st)) +#define sk_NAME_FUNCS_value(st, i) SKM_sk_value(NAME_FUNCS, (st), (i)) +#define sk_NAME_FUNCS_set(st, i, val) SKM_sk_set(NAME_FUNCS, (st), (i), (val)) +#define sk_NAME_FUNCS_zero(st) SKM_sk_zero(NAME_FUNCS, (st)) +#define sk_NAME_FUNCS_push(st, val) SKM_sk_push(NAME_FUNCS, (st), (val)) +#define sk_NAME_FUNCS_unshift(st, val) SKM_sk_unshift(NAME_FUNCS, (st), (val)) +#define sk_NAME_FUNCS_find(st, val) SKM_sk_find(NAME_FUNCS, (st), (val)) +#define sk_NAME_FUNCS_find_ex(st, val) SKM_sk_find_ex(NAME_FUNCS, (st), (val)) +#define sk_NAME_FUNCS_delete(st, i) SKM_sk_delete(NAME_FUNCS, (st), (i)) +#define sk_NAME_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(NAME_FUNCS, (st), (ptr)) +#define sk_NAME_FUNCS_insert(st, val, i) SKM_sk_insert(NAME_FUNCS, (st), (val), (i)) +#define sk_NAME_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(NAME_FUNCS, (st), (cmp)) +#define sk_NAME_FUNCS_dup(st) SKM_sk_dup(NAME_FUNCS, st) +#define sk_NAME_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(NAME_FUNCS, (st), (free_func)) +#define sk_NAME_FUNCS_shift(st) SKM_sk_shift(NAME_FUNCS, (st)) +#define sk_NAME_FUNCS_pop(st) SKM_sk_pop(NAME_FUNCS, (st)) +#define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st)) +#define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st)) + +#define sk_OCSP_CERTID_new(cmp) SKM_sk_new(OCSP_CERTID, (cmp)) +#define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID) +#define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st)) +#define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st)) +#define sk_OCSP_CERTID_value(st, i) SKM_sk_value(OCSP_CERTID, (st), (i)) +#define sk_OCSP_CERTID_set(st, i, val) SKM_sk_set(OCSP_CERTID, (st), (i), (val)) +#define sk_OCSP_CERTID_zero(st) SKM_sk_zero(OCSP_CERTID, (st)) +#define sk_OCSP_CERTID_push(st, val) SKM_sk_push(OCSP_CERTID, (st), (val)) +#define sk_OCSP_CERTID_unshift(st, val) SKM_sk_unshift(OCSP_CERTID, (st), (val)) +#define sk_OCSP_CERTID_find(st, val) SKM_sk_find(OCSP_CERTID, (st), (val)) +#define sk_OCSP_CERTID_find_ex(st, val) SKM_sk_find_ex(OCSP_CERTID, (st), (val)) +#define sk_OCSP_CERTID_delete(st, i) SKM_sk_delete(OCSP_CERTID, (st), (i)) +#define sk_OCSP_CERTID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_CERTID, (st), (ptr)) +#define sk_OCSP_CERTID_insert(st, val, i) SKM_sk_insert(OCSP_CERTID, (st), (val), (i)) +#define sk_OCSP_CERTID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_CERTID, (st), (cmp)) +#define sk_OCSP_CERTID_dup(st) SKM_sk_dup(OCSP_CERTID, st) +#define sk_OCSP_CERTID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_CERTID, (st), (free_func)) +#define sk_OCSP_CERTID_shift(st) SKM_sk_shift(OCSP_CERTID, (st)) +#define sk_OCSP_CERTID_pop(st) SKM_sk_pop(OCSP_CERTID, (st)) +#define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st)) +#define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st)) + +#define sk_OCSP_ONEREQ_new(cmp) SKM_sk_new(OCSP_ONEREQ, (cmp)) +#define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ) +#define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st)) +#define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st)) +#define sk_OCSP_ONEREQ_value(st, i) SKM_sk_value(OCSP_ONEREQ, (st), (i)) +#define sk_OCSP_ONEREQ_set(st, i, val) SKM_sk_set(OCSP_ONEREQ, (st), (i), (val)) +#define sk_OCSP_ONEREQ_zero(st) SKM_sk_zero(OCSP_ONEREQ, (st)) +#define sk_OCSP_ONEREQ_push(st, val) SKM_sk_push(OCSP_ONEREQ, (st), (val)) +#define sk_OCSP_ONEREQ_unshift(st, val) SKM_sk_unshift(OCSP_ONEREQ, (st), (val)) +#define sk_OCSP_ONEREQ_find(st, val) SKM_sk_find(OCSP_ONEREQ, (st), (val)) +#define sk_OCSP_ONEREQ_find_ex(st, val) SKM_sk_find_ex(OCSP_ONEREQ, (st), (val)) +#define sk_OCSP_ONEREQ_delete(st, i) SKM_sk_delete(OCSP_ONEREQ, (st), (i)) +#define sk_OCSP_ONEREQ_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_ONEREQ, (st), (ptr)) +#define sk_OCSP_ONEREQ_insert(st, val, i) SKM_sk_insert(OCSP_ONEREQ, (st), (val), (i)) +#define sk_OCSP_ONEREQ_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_ONEREQ, (st), (cmp)) +#define sk_OCSP_ONEREQ_dup(st) SKM_sk_dup(OCSP_ONEREQ, st) +#define sk_OCSP_ONEREQ_pop_free(st, free_func) SKM_sk_pop_free(OCSP_ONEREQ, (st), (free_func)) +#define sk_OCSP_ONEREQ_shift(st) SKM_sk_shift(OCSP_ONEREQ, (st)) +#define sk_OCSP_ONEREQ_pop(st) SKM_sk_pop(OCSP_ONEREQ, (st)) +#define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st)) +#define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st)) + +#define sk_OCSP_RESPID_new(cmp) SKM_sk_new(OCSP_RESPID, (cmp)) +#define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID) +#define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st)) +#define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st)) +#define sk_OCSP_RESPID_value(st, i) SKM_sk_value(OCSP_RESPID, (st), (i)) +#define sk_OCSP_RESPID_set(st, i, val) SKM_sk_set(OCSP_RESPID, (st), (i), (val)) +#define sk_OCSP_RESPID_zero(st) SKM_sk_zero(OCSP_RESPID, (st)) +#define sk_OCSP_RESPID_push(st, val) SKM_sk_push(OCSP_RESPID, (st), (val)) +#define sk_OCSP_RESPID_unshift(st, val) SKM_sk_unshift(OCSP_RESPID, (st), (val)) +#define sk_OCSP_RESPID_find(st, val) SKM_sk_find(OCSP_RESPID, (st), (val)) +#define sk_OCSP_RESPID_find_ex(st, val) SKM_sk_find_ex(OCSP_RESPID, (st), (val)) +#define sk_OCSP_RESPID_delete(st, i) SKM_sk_delete(OCSP_RESPID, (st), (i)) +#define sk_OCSP_RESPID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_RESPID, (st), (ptr)) +#define sk_OCSP_RESPID_insert(st, val, i) SKM_sk_insert(OCSP_RESPID, (st), (val), (i)) +#define sk_OCSP_RESPID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_RESPID, (st), (cmp)) +#define sk_OCSP_RESPID_dup(st) SKM_sk_dup(OCSP_RESPID, st) +#define sk_OCSP_RESPID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_RESPID, (st), (free_func)) +#define sk_OCSP_RESPID_shift(st) SKM_sk_shift(OCSP_RESPID, (st)) +#define sk_OCSP_RESPID_pop(st) SKM_sk_pop(OCSP_RESPID, (st)) +#define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st)) +#define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st)) + +#define sk_OCSP_SINGLERESP_new(cmp) SKM_sk_new(OCSP_SINGLERESP, (cmp)) +#define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP) +#define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st)) +#define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st)) +#define sk_OCSP_SINGLERESP_value(st, i) SKM_sk_value(OCSP_SINGLERESP, (st), (i)) +#define sk_OCSP_SINGLERESP_set(st, i, val) SKM_sk_set(OCSP_SINGLERESP, (st), (i), (val)) +#define sk_OCSP_SINGLERESP_zero(st) SKM_sk_zero(OCSP_SINGLERESP, (st)) +#define sk_OCSP_SINGLERESP_push(st, val) SKM_sk_push(OCSP_SINGLERESP, (st), (val)) +#define sk_OCSP_SINGLERESP_unshift(st, val) SKM_sk_unshift(OCSP_SINGLERESP, (st), (val)) +#define sk_OCSP_SINGLERESP_find(st, val) SKM_sk_find(OCSP_SINGLERESP, (st), (val)) +#define sk_OCSP_SINGLERESP_find_ex(st, val) SKM_sk_find_ex(OCSP_SINGLERESP, (st), (val)) +#define sk_OCSP_SINGLERESP_delete(st, i) SKM_sk_delete(OCSP_SINGLERESP, (st), (i)) +#define sk_OCSP_SINGLERESP_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_SINGLERESP, (st), (ptr)) +#define sk_OCSP_SINGLERESP_insert(st, val, i) SKM_sk_insert(OCSP_SINGLERESP, (st), (val), (i)) +#define sk_OCSP_SINGLERESP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_SINGLERESP, (st), (cmp)) +#define sk_OCSP_SINGLERESP_dup(st) SKM_sk_dup(OCSP_SINGLERESP, st) +#define sk_OCSP_SINGLERESP_pop_free(st, free_func) SKM_sk_pop_free(OCSP_SINGLERESP, (st), (free_func)) +#define sk_OCSP_SINGLERESP_shift(st) SKM_sk_shift(OCSP_SINGLERESP, (st)) +#define sk_OCSP_SINGLERESP_pop(st) SKM_sk_pop(OCSP_SINGLERESP, (st)) +#define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st)) +#define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st)) + +#define sk_PKCS12_SAFEBAG_new(cmp) SKM_sk_new(PKCS12_SAFEBAG, (cmp)) +#define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG) +#define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st)) +#define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st)) +#define sk_PKCS12_SAFEBAG_value(st, i) SKM_sk_value(PKCS12_SAFEBAG, (st), (i)) +#define sk_PKCS12_SAFEBAG_set(st, i, val) SKM_sk_set(PKCS12_SAFEBAG, (st), (i), (val)) +#define sk_PKCS12_SAFEBAG_zero(st) SKM_sk_zero(PKCS12_SAFEBAG, (st)) +#define sk_PKCS12_SAFEBAG_push(st, val) SKM_sk_push(PKCS12_SAFEBAG, (st), (val)) +#define sk_PKCS12_SAFEBAG_unshift(st, val) SKM_sk_unshift(PKCS12_SAFEBAG, (st), (val)) +#define sk_PKCS12_SAFEBAG_find(st, val) SKM_sk_find(PKCS12_SAFEBAG, (st), (val)) +#define sk_PKCS12_SAFEBAG_find_ex(st, val) SKM_sk_find_ex(PKCS12_SAFEBAG, (st), (val)) +#define sk_PKCS12_SAFEBAG_delete(st, i) SKM_sk_delete(PKCS12_SAFEBAG, (st), (i)) +#define sk_PKCS12_SAFEBAG_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS12_SAFEBAG, (st), (ptr)) +#define sk_PKCS12_SAFEBAG_insert(st, val, i) SKM_sk_insert(PKCS12_SAFEBAG, (st), (val), (i)) +#define sk_PKCS12_SAFEBAG_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS12_SAFEBAG, (st), (cmp)) +#define sk_PKCS12_SAFEBAG_dup(st) SKM_sk_dup(PKCS12_SAFEBAG, st) +#define sk_PKCS12_SAFEBAG_pop_free(st, free_func) SKM_sk_pop_free(PKCS12_SAFEBAG, (st), (free_func)) +#define sk_PKCS12_SAFEBAG_shift(st) SKM_sk_shift(PKCS12_SAFEBAG, (st)) +#define sk_PKCS12_SAFEBAG_pop(st) SKM_sk_pop(PKCS12_SAFEBAG, (st)) +#define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st)) +#define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st)) + +#define sk_PKCS7_new(cmp) SKM_sk_new(PKCS7, (cmp)) +#define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7) +#define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st)) +#define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st)) +#define sk_PKCS7_value(st, i) SKM_sk_value(PKCS7, (st), (i)) +#define sk_PKCS7_set(st, i, val) SKM_sk_set(PKCS7, (st), (i), (val)) +#define sk_PKCS7_zero(st) SKM_sk_zero(PKCS7, (st)) +#define sk_PKCS7_push(st, val) SKM_sk_push(PKCS7, (st), (val)) +#define sk_PKCS7_unshift(st, val) SKM_sk_unshift(PKCS7, (st), (val)) +#define sk_PKCS7_find(st, val) SKM_sk_find(PKCS7, (st), (val)) +#define sk_PKCS7_find_ex(st, val) SKM_sk_find_ex(PKCS7, (st), (val)) +#define sk_PKCS7_delete(st, i) SKM_sk_delete(PKCS7, (st), (i)) +#define sk_PKCS7_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7, (st), (ptr)) +#define sk_PKCS7_insert(st, val, i) SKM_sk_insert(PKCS7, (st), (val), (i)) +#define sk_PKCS7_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7, (st), (cmp)) +#define sk_PKCS7_dup(st) SKM_sk_dup(PKCS7, st) +#define sk_PKCS7_pop_free(st, free_func) SKM_sk_pop_free(PKCS7, (st), (free_func)) +#define sk_PKCS7_shift(st) SKM_sk_shift(PKCS7, (st)) +#define sk_PKCS7_pop(st) SKM_sk_pop(PKCS7, (st)) +#define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st)) +#define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st)) + +#define sk_PKCS7_RECIP_INFO_new(cmp) SKM_sk_new(PKCS7_RECIP_INFO, (cmp)) +#define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO) +#define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st)) +#define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st)) +#define sk_PKCS7_RECIP_INFO_value(st, i) SKM_sk_value(PKCS7_RECIP_INFO, (st), (i)) +#define sk_PKCS7_RECIP_INFO_set(st, i, val) SKM_sk_set(PKCS7_RECIP_INFO, (st), (i), (val)) +#define sk_PKCS7_RECIP_INFO_zero(st) SKM_sk_zero(PKCS7_RECIP_INFO, (st)) +#define sk_PKCS7_RECIP_INFO_push(st, val) SKM_sk_push(PKCS7_RECIP_INFO, (st), (val)) +#define sk_PKCS7_RECIP_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_RECIP_INFO, (st), (val)) +#define sk_PKCS7_RECIP_INFO_find(st, val) SKM_sk_find(PKCS7_RECIP_INFO, (st), (val)) +#define sk_PKCS7_RECIP_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_RECIP_INFO, (st), (val)) +#define sk_PKCS7_RECIP_INFO_delete(st, i) SKM_sk_delete(PKCS7_RECIP_INFO, (st), (i)) +#define sk_PKCS7_RECIP_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_RECIP_INFO, (st), (ptr)) +#define sk_PKCS7_RECIP_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_RECIP_INFO, (st), (val), (i)) +#define sk_PKCS7_RECIP_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_RECIP_INFO, (st), (cmp)) +#define sk_PKCS7_RECIP_INFO_dup(st) SKM_sk_dup(PKCS7_RECIP_INFO, st) +#define sk_PKCS7_RECIP_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_RECIP_INFO, (st), (free_func)) +#define sk_PKCS7_RECIP_INFO_shift(st) SKM_sk_shift(PKCS7_RECIP_INFO, (st)) +#define sk_PKCS7_RECIP_INFO_pop(st) SKM_sk_pop(PKCS7_RECIP_INFO, (st)) +#define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st)) +#define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st)) + +#define sk_PKCS7_SIGNER_INFO_new(cmp) SKM_sk_new(PKCS7_SIGNER_INFO, (cmp)) +#define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO) +#define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st)) +#define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st)) +#define sk_PKCS7_SIGNER_INFO_value(st, i) SKM_sk_value(PKCS7_SIGNER_INFO, (st), (i)) +#define sk_PKCS7_SIGNER_INFO_set(st, i, val) SKM_sk_set(PKCS7_SIGNER_INFO, (st), (i), (val)) +#define sk_PKCS7_SIGNER_INFO_zero(st) SKM_sk_zero(PKCS7_SIGNER_INFO, (st)) +#define sk_PKCS7_SIGNER_INFO_push(st, val) SKM_sk_push(PKCS7_SIGNER_INFO, (st), (val)) +#define sk_PKCS7_SIGNER_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_SIGNER_INFO, (st), (val)) +#define sk_PKCS7_SIGNER_INFO_find(st, val) SKM_sk_find(PKCS7_SIGNER_INFO, (st), (val)) +#define sk_PKCS7_SIGNER_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_SIGNER_INFO, (st), (val)) +#define sk_PKCS7_SIGNER_INFO_delete(st, i) SKM_sk_delete(PKCS7_SIGNER_INFO, (st), (i)) +#define sk_PKCS7_SIGNER_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_SIGNER_INFO, (st), (ptr)) +#define sk_PKCS7_SIGNER_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_SIGNER_INFO, (st), (val), (i)) +#define sk_PKCS7_SIGNER_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_SIGNER_INFO, (st), (cmp)) +#define sk_PKCS7_SIGNER_INFO_dup(st) SKM_sk_dup(PKCS7_SIGNER_INFO, st) +#define sk_PKCS7_SIGNER_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_SIGNER_INFO, (st), (free_func)) +#define sk_PKCS7_SIGNER_INFO_shift(st) SKM_sk_shift(PKCS7_SIGNER_INFO, (st)) +#define sk_PKCS7_SIGNER_INFO_pop(st) SKM_sk_pop(PKCS7_SIGNER_INFO, (st)) +#define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st)) +#define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st)) + +#define sk_POLICYINFO_new(cmp) SKM_sk_new(POLICYINFO, (cmp)) +#define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO) +#define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st)) +#define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st)) +#define sk_POLICYINFO_value(st, i) SKM_sk_value(POLICYINFO, (st), (i)) +#define sk_POLICYINFO_set(st, i, val) SKM_sk_set(POLICYINFO, (st), (i), (val)) +#define sk_POLICYINFO_zero(st) SKM_sk_zero(POLICYINFO, (st)) +#define sk_POLICYINFO_push(st, val) SKM_sk_push(POLICYINFO, (st), (val)) +#define sk_POLICYINFO_unshift(st, val) SKM_sk_unshift(POLICYINFO, (st), (val)) +#define sk_POLICYINFO_find(st, val) SKM_sk_find(POLICYINFO, (st), (val)) +#define sk_POLICYINFO_find_ex(st, val) SKM_sk_find_ex(POLICYINFO, (st), (val)) +#define sk_POLICYINFO_delete(st, i) SKM_sk_delete(POLICYINFO, (st), (i)) +#define sk_POLICYINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYINFO, (st), (ptr)) +#define sk_POLICYINFO_insert(st, val, i) SKM_sk_insert(POLICYINFO, (st), (val), (i)) +#define sk_POLICYINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYINFO, (st), (cmp)) +#define sk_POLICYINFO_dup(st) SKM_sk_dup(POLICYINFO, st) +#define sk_POLICYINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYINFO, (st), (free_func)) +#define sk_POLICYINFO_shift(st) SKM_sk_shift(POLICYINFO, (st)) +#define sk_POLICYINFO_pop(st) SKM_sk_pop(POLICYINFO, (st)) +#define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st)) +#define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st)) + +#define sk_POLICYQUALINFO_new(cmp) SKM_sk_new(POLICYQUALINFO, (cmp)) +#define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO) +#define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st)) +#define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st)) +#define sk_POLICYQUALINFO_value(st, i) SKM_sk_value(POLICYQUALINFO, (st), (i)) +#define sk_POLICYQUALINFO_set(st, i, val) SKM_sk_set(POLICYQUALINFO, (st), (i), (val)) +#define sk_POLICYQUALINFO_zero(st) SKM_sk_zero(POLICYQUALINFO, (st)) +#define sk_POLICYQUALINFO_push(st, val) SKM_sk_push(POLICYQUALINFO, (st), (val)) +#define sk_POLICYQUALINFO_unshift(st, val) SKM_sk_unshift(POLICYQUALINFO, (st), (val)) +#define sk_POLICYQUALINFO_find(st, val) SKM_sk_find(POLICYQUALINFO, (st), (val)) +#define sk_POLICYQUALINFO_find_ex(st, val) SKM_sk_find_ex(POLICYQUALINFO, (st), (val)) +#define sk_POLICYQUALINFO_delete(st, i) SKM_sk_delete(POLICYQUALINFO, (st), (i)) +#define sk_POLICYQUALINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYQUALINFO, (st), (ptr)) +#define sk_POLICYQUALINFO_insert(st, val, i) SKM_sk_insert(POLICYQUALINFO, (st), (val), (i)) +#define sk_POLICYQUALINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYQUALINFO, (st), (cmp)) +#define sk_POLICYQUALINFO_dup(st) SKM_sk_dup(POLICYQUALINFO, st) +#define sk_POLICYQUALINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYQUALINFO, (st), (free_func)) +#define sk_POLICYQUALINFO_shift(st) SKM_sk_shift(POLICYQUALINFO, (st)) +#define sk_POLICYQUALINFO_pop(st) SKM_sk_pop(POLICYQUALINFO, (st)) +#define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st)) +#define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st)) + +#define sk_POLICY_MAPPING_new(cmp) SKM_sk_new(POLICY_MAPPING, (cmp)) +#define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING) +#define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st)) +#define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st)) +#define sk_POLICY_MAPPING_value(st, i) SKM_sk_value(POLICY_MAPPING, (st), (i)) +#define sk_POLICY_MAPPING_set(st, i, val) SKM_sk_set(POLICY_MAPPING, (st), (i), (val)) +#define sk_POLICY_MAPPING_zero(st) SKM_sk_zero(POLICY_MAPPING, (st)) +#define sk_POLICY_MAPPING_push(st, val) SKM_sk_push(POLICY_MAPPING, (st), (val)) +#define sk_POLICY_MAPPING_unshift(st, val) SKM_sk_unshift(POLICY_MAPPING, (st), (val)) +#define sk_POLICY_MAPPING_find(st, val) SKM_sk_find(POLICY_MAPPING, (st), (val)) +#define sk_POLICY_MAPPING_find_ex(st, val) SKM_sk_find_ex(POLICY_MAPPING, (st), (val)) +#define sk_POLICY_MAPPING_delete(st, i) SKM_sk_delete(POLICY_MAPPING, (st), (i)) +#define sk_POLICY_MAPPING_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICY_MAPPING, (st), (ptr)) +#define sk_POLICY_MAPPING_insert(st, val, i) SKM_sk_insert(POLICY_MAPPING, (st), (val), (i)) +#define sk_POLICY_MAPPING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICY_MAPPING, (st), (cmp)) +#define sk_POLICY_MAPPING_dup(st) SKM_sk_dup(POLICY_MAPPING, st) +#define sk_POLICY_MAPPING_pop_free(st, free_func) SKM_sk_pop_free(POLICY_MAPPING, (st), (free_func)) +#define sk_POLICY_MAPPING_shift(st) SKM_sk_shift(POLICY_MAPPING, (st)) +#define sk_POLICY_MAPPING_pop(st) SKM_sk_pop(POLICY_MAPPING, (st)) +#define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st)) +#define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st)) + +#define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp)) +#define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER) +#define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st)) +#define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st)) +#define sk_SSL_CIPHER_value(st, i) SKM_sk_value(SSL_CIPHER, (st), (i)) +#define sk_SSL_CIPHER_set(st, i, val) SKM_sk_set(SSL_CIPHER, (st), (i), (val)) +#define sk_SSL_CIPHER_zero(st) SKM_sk_zero(SSL_CIPHER, (st)) +#define sk_SSL_CIPHER_push(st, val) SKM_sk_push(SSL_CIPHER, (st), (val)) +#define sk_SSL_CIPHER_unshift(st, val) SKM_sk_unshift(SSL_CIPHER, (st), (val)) +#define sk_SSL_CIPHER_find(st, val) SKM_sk_find(SSL_CIPHER, (st), (val)) +#define sk_SSL_CIPHER_find_ex(st, val) SKM_sk_find_ex(SSL_CIPHER, (st), (val)) +#define sk_SSL_CIPHER_delete(st, i) SKM_sk_delete(SSL_CIPHER, (st), (i)) +#define sk_SSL_CIPHER_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_CIPHER, (st), (ptr)) +#define sk_SSL_CIPHER_insert(st, val, i) SKM_sk_insert(SSL_CIPHER, (st), (val), (i)) +#define sk_SSL_CIPHER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_CIPHER, (st), (cmp)) +#define sk_SSL_CIPHER_dup(st) SKM_sk_dup(SSL_CIPHER, st) +#define sk_SSL_CIPHER_pop_free(st, free_func) SKM_sk_pop_free(SSL_CIPHER, (st), (free_func)) +#define sk_SSL_CIPHER_shift(st) SKM_sk_shift(SSL_CIPHER, (st)) +#define sk_SSL_CIPHER_pop(st) SKM_sk_pop(SSL_CIPHER, (st)) +#define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st)) +#define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st)) + +#define sk_SSL_COMP_new(cmp) SKM_sk_new(SSL_COMP, (cmp)) +#define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP) +#define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st)) +#define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st)) +#define sk_SSL_COMP_value(st, i) SKM_sk_value(SSL_COMP, (st), (i)) +#define sk_SSL_COMP_set(st, i, val) SKM_sk_set(SSL_COMP, (st), (i), (val)) +#define sk_SSL_COMP_zero(st) SKM_sk_zero(SSL_COMP, (st)) +#define sk_SSL_COMP_push(st, val) SKM_sk_push(SSL_COMP, (st), (val)) +#define sk_SSL_COMP_unshift(st, val) SKM_sk_unshift(SSL_COMP, (st), (val)) +#define sk_SSL_COMP_find(st, val) SKM_sk_find(SSL_COMP, (st), (val)) +#define sk_SSL_COMP_find_ex(st, val) SKM_sk_find_ex(SSL_COMP, (st), (val)) +#define sk_SSL_COMP_delete(st, i) SKM_sk_delete(SSL_COMP, (st), (i)) +#define sk_SSL_COMP_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_COMP, (st), (ptr)) +#define sk_SSL_COMP_insert(st, val, i) SKM_sk_insert(SSL_COMP, (st), (val), (i)) +#define sk_SSL_COMP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_COMP, (st), (cmp)) +#define sk_SSL_COMP_dup(st) SKM_sk_dup(SSL_COMP, st) +#define sk_SSL_COMP_pop_free(st, free_func) SKM_sk_pop_free(SSL_COMP, (st), (free_func)) +#define sk_SSL_COMP_shift(st) SKM_sk_shift(SSL_COMP, (st)) +#define sk_SSL_COMP_pop(st) SKM_sk_pop(SSL_COMP, (st)) +#define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st)) +#define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st)) + +#define sk_STACK_OF_X509_NAME_ENTRY_new(cmp) SKM_sk_new(STACK_OF_X509_NAME_ENTRY, (cmp)) +#define sk_STACK_OF_X509_NAME_ENTRY_new_null() SKM_sk_new_null(STACK_OF_X509_NAME_ENTRY) +#define sk_STACK_OF_X509_NAME_ENTRY_free(st) SKM_sk_free(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_num(st) SKM_sk_num(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_value(st, i) SKM_sk_value(STACK_OF_X509_NAME_ENTRY, (st), (i)) +#define sk_STACK_OF_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(STACK_OF_X509_NAME_ENTRY, (st), (i), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_zero(st) SKM_sk_zero(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_push(st, val) SKM_sk_push(STACK_OF_X509_NAME_ENTRY, (st), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(STACK_OF_X509_NAME_ENTRY, (st), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_find(st, val) SKM_sk_find(STACK_OF_X509_NAME_ENTRY, (st), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(STACK_OF_X509_NAME_ENTRY, (st), (val)) +#define sk_STACK_OF_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(STACK_OF_X509_NAME_ENTRY, (st), (i)) +#define sk_STACK_OF_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(STACK_OF_X509_NAME_ENTRY, (st), (ptr)) +#define sk_STACK_OF_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(STACK_OF_X509_NAME_ENTRY, (st), (val), (i)) +#define sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STACK_OF_X509_NAME_ENTRY, (st), (cmp)) +#define sk_STACK_OF_X509_NAME_ENTRY_dup(st) SKM_sk_dup(STACK_OF_X509_NAME_ENTRY, st) +#define sk_STACK_OF_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(STACK_OF_X509_NAME_ENTRY, (st), (free_func)) +#define sk_STACK_OF_X509_NAME_ENTRY_shift(st) SKM_sk_shift(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_pop(st) SKM_sk_pop(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_sort(st) SKM_sk_sort(STACK_OF_X509_NAME_ENTRY, (st)) +#define sk_STACK_OF_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(STACK_OF_X509_NAME_ENTRY, (st)) + +#define sk_STORE_ATTR_INFO_new(cmp) SKM_sk_new(STORE_ATTR_INFO, (cmp)) +#define sk_STORE_ATTR_INFO_new_null() SKM_sk_new_null(STORE_ATTR_INFO) +#define sk_STORE_ATTR_INFO_free(st) SKM_sk_free(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_num(st) SKM_sk_num(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_value(st, i) SKM_sk_value(STORE_ATTR_INFO, (st), (i)) +#define sk_STORE_ATTR_INFO_set(st, i, val) SKM_sk_set(STORE_ATTR_INFO, (st), (i), (val)) +#define sk_STORE_ATTR_INFO_zero(st) SKM_sk_zero(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_push(st, val) SKM_sk_push(STORE_ATTR_INFO, (st), (val)) +#define sk_STORE_ATTR_INFO_unshift(st, val) SKM_sk_unshift(STORE_ATTR_INFO, (st), (val)) +#define sk_STORE_ATTR_INFO_find(st, val) SKM_sk_find(STORE_ATTR_INFO, (st), (val)) +#define sk_STORE_ATTR_INFO_find_ex(st, val) SKM_sk_find_ex(STORE_ATTR_INFO, (st), (val)) +#define sk_STORE_ATTR_INFO_delete(st, i) SKM_sk_delete(STORE_ATTR_INFO, (st), (i)) +#define sk_STORE_ATTR_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_ATTR_INFO, (st), (ptr)) +#define sk_STORE_ATTR_INFO_insert(st, val, i) SKM_sk_insert(STORE_ATTR_INFO, (st), (val), (i)) +#define sk_STORE_ATTR_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_ATTR_INFO, (st), (cmp)) +#define sk_STORE_ATTR_INFO_dup(st) SKM_sk_dup(STORE_ATTR_INFO, st) +#define sk_STORE_ATTR_INFO_pop_free(st, free_func) SKM_sk_pop_free(STORE_ATTR_INFO, (st), (free_func)) +#define sk_STORE_ATTR_INFO_shift(st) SKM_sk_shift(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_pop(st) SKM_sk_pop(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_sort(st) SKM_sk_sort(STORE_ATTR_INFO, (st)) +#define sk_STORE_ATTR_INFO_is_sorted(st) SKM_sk_is_sorted(STORE_ATTR_INFO, (st)) + +#define sk_STORE_OBJECT_new(cmp) SKM_sk_new(STORE_OBJECT, (cmp)) +#define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT) +#define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st)) +#define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st)) +#define sk_STORE_OBJECT_value(st, i) SKM_sk_value(STORE_OBJECT, (st), (i)) +#define sk_STORE_OBJECT_set(st, i, val) SKM_sk_set(STORE_OBJECT, (st), (i), (val)) +#define sk_STORE_OBJECT_zero(st) SKM_sk_zero(STORE_OBJECT, (st)) +#define sk_STORE_OBJECT_push(st, val) SKM_sk_push(STORE_OBJECT, (st), (val)) +#define sk_STORE_OBJECT_unshift(st, val) SKM_sk_unshift(STORE_OBJECT, (st), (val)) +#define sk_STORE_OBJECT_find(st, val) SKM_sk_find(STORE_OBJECT, (st), (val)) +#define sk_STORE_OBJECT_find_ex(st, val) SKM_sk_find_ex(STORE_OBJECT, (st), (val)) +#define sk_STORE_OBJECT_delete(st, i) SKM_sk_delete(STORE_OBJECT, (st), (i)) +#define sk_STORE_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_OBJECT, (st), (ptr)) +#define sk_STORE_OBJECT_insert(st, val, i) SKM_sk_insert(STORE_OBJECT, (st), (val), (i)) +#define sk_STORE_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_OBJECT, (st), (cmp)) +#define sk_STORE_OBJECT_dup(st) SKM_sk_dup(STORE_OBJECT, st) +#define sk_STORE_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(STORE_OBJECT, (st), (free_func)) +#define sk_STORE_OBJECT_shift(st) SKM_sk_shift(STORE_OBJECT, (st)) +#define sk_STORE_OBJECT_pop(st) SKM_sk_pop(STORE_OBJECT, (st)) +#define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st)) +#define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st)) + +#define sk_SXNETID_new(cmp) SKM_sk_new(SXNETID, (cmp)) +#define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID) +#define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st)) +#define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st)) +#define sk_SXNETID_value(st, i) SKM_sk_value(SXNETID, (st), (i)) +#define sk_SXNETID_set(st, i, val) SKM_sk_set(SXNETID, (st), (i), (val)) +#define sk_SXNETID_zero(st) SKM_sk_zero(SXNETID, (st)) +#define sk_SXNETID_push(st, val) SKM_sk_push(SXNETID, (st), (val)) +#define sk_SXNETID_unshift(st, val) SKM_sk_unshift(SXNETID, (st), (val)) +#define sk_SXNETID_find(st, val) SKM_sk_find(SXNETID, (st), (val)) +#define sk_SXNETID_find_ex(st, val) SKM_sk_find_ex(SXNETID, (st), (val)) +#define sk_SXNETID_delete(st, i) SKM_sk_delete(SXNETID, (st), (i)) +#define sk_SXNETID_delete_ptr(st, ptr) SKM_sk_delete_ptr(SXNETID, (st), (ptr)) +#define sk_SXNETID_insert(st, val, i) SKM_sk_insert(SXNETID, (st), (val), (i)) +#define sk_SXNETID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SXNETID, (st), (cmp)) +#define sk_SXNETID_dup(st) SKM_sk_dup(SXNETID, st) +#define sk_SXNETID_pop_free(st, free_func) SKM_sk_pop_free(SXNETID, (st), (free_func)) +#define sk_SXNETID_shift(st) SKM_sk_shift(SXNETID, (st)) +#define sk_SXNETID_pop(st) SKM_sk_pop(SXNETID, (st)) +#define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st)) +#define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st)) + +#define sk_UI_STRING_new(cmp) SKM_sk_new(UI_STRING, (cmp)) +#define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING) +#define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st)) +#define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st)) +#define sk_UI_STRING_value(st, i) SKM_sk_value(UI_STRING, (st), (i)) +#define sk_UI_STRING_set(st, i, val) SKM_sk_set(UI_STRING, (st), (i), (val)) +#define sk_UI_STRING_zero(st) SKM_sk_zero(UI_STRING, (st)) +#define sk_UI_STRING_push(st, val) SKM_sk_push(UI_STRING, (st), (val)) +#define sk_UI_STRING_unshift(st, val) SKM_sk_unshift(UI_STRING, (st), (val)) +#define sk_UI_STRING_find(st, val) SKM_sk_find(UI_STRING, (st), (val)) +#define sk_UI_STRING_find_ex(st, val) SKM_sk_find_ex(UI_STRING, (st), (val)) +#define sk_UI_STRING_delete(st, i) SKM_sk_delete(UI_STRING, (st), (i)) +#define sk_UI_STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(UI_STRING, (st), (ptr)) +#define sk_UI_STRING_insert(st, val, i) SKM_sk_insert(UI_STRING, (st), (val), (i)) +#define sk_UI_STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(UI_STRING, (st), (cmp)) +#define sk_UI_STRING_dup(st) SKM_sk_dup(UI_STRING, st) +#define sk_UI_STRING_pop_free(st, free_func) SKM_sk_pop_free(UI_STRING, (st), (free_func)) +#define sk_UI_STRING_shift(st) SKM_sk_shift(UI_STRING, (st)) +#define sk_UI_STRING_pop(st) SKM_sk_pop(UI_STRING, (st)) +#define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st)) +#define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st)) + +#define sk_X509_new(cmp) SKM_sk_new(X509, (cmp)) +#define sk_X509_new_null() SKM_sk_new_null(X509) +#define sk_X509_free(st) SKM_sk_free(X509, (st)) +#define sk_X509_num(st) SKM_sk_num(X509, (st)) +#define sk_X509_value(st, i) SKM_sk_value(X509, (st), (i)) +#define sk_X509_set(st, i, val) SKM_sk_set(X509, (st), (i), (val)) +#define sk_X509_zero(st) SKM_sk_zero(X509, (st)) +#define sk_X509_push(st, val) SKM_sk_push(X509, (st), (val)) +#define sk_X509_unshift(st, val) SKM_sk_unshift(X509, (st), (val)) +#define sk_X509_find(st, val) SKM_sk_find(X509, (st), (val)) +#define sk_X509_find_ex(st, val) SKM_sk_find_ex(X509, (st), (val)) +#define sk_X509_delete(st, i) SKM_sk_delete(X509, (st), (i)) +#define sk_X509_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509, (st), (ptr)) +#define sk_X509_insert(st, val, i) SKM_sk_insert(X509, (st), (val), (i)) +#define sk_X509_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509, (st), (cmp)) +#define sk_X509_dup(st) SKM_sk_dup(X509, st) +#define sk_X509_pop_free(st, free_func) SKM_sk_pop_free(X509, (st), (free_func)) +#define sk_X509_shift(st) SKM_sk_shift(X509, (st)) +#define sk_X509_pop(st) SKM_sk_pop(X509, (st)) +#define sk_X509_sort(st) SKM_sk_sort(X509, (st)) +#define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st)) + +#define sk_X509V3_EXT_METHOD_new(cmp) SKM_sk_new(X509V3_EXT_METHOD, (cmp)) +#define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD) +#define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st)) +#define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st)) +#define sk_X509V3_EXT_METHOD_value(st, i) SKM_sk_value(X509V3_EXT_METHOD, (st), (i)) +#define sk_X509V3_EXT_METHOD_set(st, i, val) SKM_sk_set(X509V3_EXT_METHOD, (st), (i), (val)) +#define sk_X509V3_EXT_METHOD_zero(st) SKM_sk_zero(X509V3_EXT_METHOD, (st)) +#define sk_X509V3_EXT_METHOD_push(st, val) SKM_sk_push(X509V3_EXT_METHOD, (st), (val)) +#define sk_X509V3_EXT_METHOD_unshift(st, val) SKM_sk_unshift(X509V3_EXT_METHOD, (st), (val)) +#define sk_X509V3_EXT_METHOD_find(st, val) SKM_sk_find(X509V3_EXT_METHOD, (st), (val)) +#define sk_X509V3_EXT_METHOD_find_ex(st, val) SKM_sk_find_ex(X509V3_EXT_METHOD, (st), (val)) +#define sk_X509V3_EXT_METHOD_delete(st, i) SKM_sk_delete(X509V3_EXT_METHOD, (st), (i)) +#define sk_X509V3_EXT_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509V3_EXT_METHOD, (st), (ptr)) +#define sk_X509V3_EXT_METHOD_insert(st, val, i) SKM_sk_insert(X509V3_EXT_METHOD, (st), (val), (i)) +#define sk_X509V3_EXT_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509V3_EXT_METHOD, (st), (cmp)) +#define sk_X509V3_EXT_METHOD_dup(st) SKM_sk_dup(X509V3_EXT_METHOD, st) +#define sk_X509V3_EXT_METHOD_pop_free(st, free_func) SKM_sk_pop_free(X509V3_EXT_METHOD, (st), (free_func)) +#define sk_X509V3_EXT_METHOD_shift(st) SKM_sk_shift(X509V3_EXT_METHOD, (st)) +#define sk_X509V3_EXT_METHOD_pop(st) SKM_sk_pop(X509V3_EXT_METHOD, (st)) +#define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st)) +#define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st)) + +#define sk_X509_ALGOR_new(cmp) SKM_sk_new(X509_ALGOR, (cmp)) +#define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR) +#define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st)) +#define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st)) +#define sk_X509_ALGOR_value(st, i) SKM_sk_value(X509_ALGOR, (st), (i)) +#define sk_X509_ALGOR_set(st, i, val) SKM_sk_set(X509_ALGOR, (st), (i), (val)) +#define sk_X509_ALGOR_zero(st) SKM_sk_zero(X509_ALGOR, (st)) +#define sk_X509_ALGOR_push(st, val) SKM_sk_push(X509_ALGOR, (st), (val)) +#define sk_X509_ALGOR_unshift(st, val) SKM_sk_unshift(X509_ALGOR, (st), (val)) +#define sk_X509_ALGOR_find(st, val) SKM_sk_find(X509_ALGOR, (st), (val)) +#define sk_X509_ALGOR_find_ex(st, val) SKM_sk_find_ex(X509_ALGOR, (st), (val)) +#define sk_X509_ALGOR_delete(st, i) SKM_sk_delete(X509_ALGOR, (st), (i)) +#define sk_X509_ALGOR_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ALGOR, (st), (ptr)) +#define sk_X509_ALGOR_insert(st, val, i) SKM_sk_insert(X509_ALGOR, (st), (val), (i)) +#define sk_X509_ALGOR_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ALGOR, (st), (cmp)) +#define sk_X509_ALGOR_dup(st) SKM_sk_dup(X509_ALGOR, st) +#define sk_X509_ALGOR_pop_free(st, free_func) SKM_sk_pop_free(X509_ALGOR, (st), (free_func)) +#define sk_X509_ALGOR_shift(st) SKM_sk_shift(X509_ALGOR, (st)) +#define sk_X509_ALGOR_pop(st) SKM_sk_pop(X509_ALGOR, (st)) +#define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st)) +#define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st)) + +#define sk_X509_ATTRIBUTE_new(cmp) SKM_sk_new(X509_ATTRIBUTE, (cmp)) +#define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE) +#define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st)) +#define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st)) +#define sk_X509_ATTRIBUTE_value(st, i) SKM_sk_value(X509_ATTRIBUTE, (st), (i)) +#define sk_X509_ATTRIBUTE_set(st, i, val) SKM_sk_set(X509_ATTRIBUTE, (st), (i), (val)) +#define sk_X509_ATTRIBUTE_zero(st) SKM_sk_zero(X509_ATTRIBUTE, (st)) +#define sk_X509_ATTRIBUTE_push(st, val) SKM_sk_push(X509_ATTRIBUTE, (st), (val)) +#define sk_X509_ATTRIBUTE_unshift(st, val) SKM_sk_unshift(X509_ATTRIBUTE, (st), (val)) +#define sk_X509_ATTRIBUTE_find(st, val) SKM_sk_find(X509_ATTRIBUTE, (st), (val)) +#define sk_X509_ATTRIBUTE_find_ex(st, val) SKM_sk_find_ex(X509_ATTRIBUTE, (st), (val)) +#define sk_X509_ATTRIBUTE_delete(st, i) SKM_sk_delete(X509_ATTRIBUTE, (st), (i)) +#define sk_X509_ATTRIBUTE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ATTRIBUTE, (st), (ptr)) +#define sk_X509_ATTRIBUTE_insert(st, val, i) SKM_sk_insert(X509_ATTRIBUTE, (st), (val), (i)) +#define sk_X509_ATTRIBUTE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ATTRIBUTE, (st), (cmp)) +#define sk_X509_ATTRIBUTE_dup(st) SKM_sk_dup(X509_ATTRIBUTE, st) +#define sk_X509_ATTRIBUTE_pop_free(st, free_func) SKM_sk_pop_free(X509_ATTRIBUTE, (st), (free_func)) +#define sk_X509_ATTRIBUTE_shift(st) SKM_sk_shift(X509_ATTRIBUTE, (st)) +#define sk_X509_ATTRIBUTE_pop(st) SKM_sk_pop(X509_ATTRIBUTE, (st)) +#define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st)) +#define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st)) + +#define sk_X509_CRL_new(cmp) SKM_sk_new(X509_CRL, (cmp)) +#define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL) +#define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st)) +#define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st)) +#define sk_X509_CRL_value(st, i) SKM_sk_value(X509_CRL, (st), (i)) +#define sk_X509_CRL_set(st, i, val) SKM_sk_set(X509_CRL, (st), (i), (val)) +#define sk_X509_CRL_zero(st) SKM_sk_zero(X509_CRL, (st)) +#define sk_X509_CRL_push(st, val) SKM_sk_push(X509_CRL, (st), (val)) +#define sk_X509_CRL_unshift(st, val) SKM_sk_unshift(X509_CRL, (st), (val)) +#define sk_X509_CRL_find(st, val) SKM_sk_find(X509_CRL, (st), (val)) +#define sk_X509_CRL_find_ex(st, val) SKM_sk_find_ex(X509_CRL, (st), (val)) +#define sk_X509_CRL_delete(st, i) SKM_sk_delete(X509_CRL, (st), (i)) +#define sk_X509_CRL_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_CRL, (st), (ptr)) +#define sk_X509_CRL_insert(st, val, i) SKM_sk_insert(X509_CRL, (st), (val), (i)) +#define sk_X509_CRL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_CRL, (st), (cmp)) +#define sk_X509_CRL_dup(st) SKM_sk_dup(X509_CRL, st) +#define sk_X509_CRL_pop_free(st, free_func) SKM_sk_pop_free(X509_CRL, (st), (free_func)) +#define sk_X509_CRL_shift(st) SKM_sk_shift(X509_CRL, (st)) +#define sk_X509_CRL_pop(st) SKM_sk_pop(X509_CRL, (st)) +#define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st)) +#define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st)) + +#define sk_X509_EXTENSION_new(cmp) SKM_sk_new(X509_EXTENSION, (cmp)) +#define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION) +#define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st)) +#define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st)) +#define sk_X509_EXTENSION_value(st, i) SKM_sk_value(X509_EXTENSION, (st), (i)) +#define sk_X509_EXTENSION_set(st, i, val) SKM_sk_set(X509_EXTENSION, (st), (i), (val)) +#define sk_X509_EXTENSION_zero(st) SKM_sk_zero(X509_EXTENSION, (st)) +#define sk_X509_EXTENSION_push(st, val) SKM_sk_push(X509_EXTENSION, (st), (val)) +#define sk_X509_EXTENSION_unshift(st, val) SKM_sk_unshift(X509_EXTENSION, (st), (val)) +#define sk_X509_EXTENSION_find(st, val) SKM_sk_find(X509_EXTENSION, (st), (val)) +#define sk_X509_EXTENSION_find_ex(st, val) SKM_sk_find_ex(X509_EXTENSION, (st), (val)) +#define sk_X509_EXTENSION_delete(st, i) SKM_sk_delete(X509_EXTENSION, (st), (i)) +#define sk_X509_EXTENSION_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_EXTENSION, (st), (ptr)) +#define sk_X509_EXTENSION_insert(st, val, i) SKM_sk_insert(X509_EXTENSION, (st), (val), (i)) +#define sk_X509_EXTENSION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_EXTENSION, (st), (cmp)) +#define sk_X509_EXTENSION_dup(st) SKM_sk_dup(X509_EXTENSION, st) +#define sk_X509_EXTENSION_pop_free(st, free_func) SKM_sk_pop_free(X509_EXTENSION, (st), (free_func)) +#define sk_X509_EXTENSION_shift(st) SKM_sk_shift(X509_EXTENSION, (st)) +#define sk_X509_EXTENSION_pop(st) SKM_sk_pop(X509_EXTENSION, (st)) +#define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st)) +#define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st)) + +#define sk_X509_INFO_new(cmp) SKM_sk_new(X509_INFO, (cmp)) +#define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO) +#define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st)) +#define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st)) +#define sk_X509_INFO_value(st, i) SKM_sk_value(X509_INFO, (st), (i)) +#define sk_X509_INFO_set(st, i, val) SKM_sk_set(X509_INFO, (st), (i), (val)) +#define sk_X509_INFO_zero(st) SKM_sk_zero(X509_INFO, (st)) +#define sk_X509_INFO_push(st, val) SKM_sk_push(X509_INFO, (st), (val)) +#define sk_X509_INFO_unshift(st, val) SKM_sk_unshift(X509_INFO, (st), (val)) +#define sk_X509_INFO_find(st, val) SKM_sk_find(X509_INFO, (st), (val)) +#define sk_X509_INFO_find_ex(st, val) SKM_sk_find_ex(X509_INFO, (st), (val)) +#define sk_X509_INFO_delete(st, i) SKM_sk_delete(X509_INFO, (st), (i)) +#define sk_X509_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_INFO, (st), (ptr)) +#define sk_X509_INFO_insert(st, val, i) SKM_sk_insert(X509_INFO, (st), (val), (i)) +#define sk_X509_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_INFO, (st), (cmp)) +#define sk_X509_INFO_dup(st) SKM_sk_dup(X509_INFO, st) +#define sk_X509_INFO_pop_free(st, free_func) SKM_sk_pop_free(X509_INFO, (st), (free_func)) +#define sk_X509_INFO_shift(st) SKM_sk_shift(X509_INFO, (st)) +#define sk_X509_INFO_pop(st) SKM_sk_pop(X509_INFO, (st)) +#define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st)) +#define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st)) + +#define sk_X509_LOOKUP_new(cmp) SKM_sk_new(X509_LOOKUP, (cmp)) +#define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP) +#define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st)) +#define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st)) +#define sk_X509_LOOKUP_value(st, i) SKM_sk_value(X509_LOOKUP, (st), (i)) +#define sk_X509_LOOKUP_set(st, i, val) SKM_sk_set(X509_LOOKUP, (st), (i), (val)) +#define sk_X509_LOOKUP_zero(st) SKM_sk_zero(X509_LOOKUP, (st)) +#define sk_X509_LOOKUP_push(st, val) SKM_sk_push(X509_LOOKUP, (st), (val)) +#define sk_X509_LOOKUP_unshift(st, val) SKM_sk_unshift(X509_LOOKUP, (st), (val)) +#define sk_X509_LOOKUP_find(st, val) SKM_sk_find(X509_LOOKUP, (st), (val)) +#define sk_X509_LOOKUP_find_ex(st, val) SKM_sk_find_ex(X509_LOOKUP, (st), (val)) +#define sk_X509_LOOKUP_delete(st, i) SKM_sk_delete(X509_LOOKUP, (st), (i)) +#define sk_X509_LOOKUP_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_LOOKUP, (st), (ptr)) +#define sk_X509_LOOKUP_insert(st, val, i) SKM_sk_insert(X509_LOOKUP, (st), (val), (i)) +#define sk_X509_LOOKUP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_LOOKUP, (st), (cmp)) +#define sk_X509_LOOKUP_dup(st) SKM_sk_dup(X509_LOOKUP, st) +#define sk_X509_LOOKUP_pop_free(st, free_func) SKM_sk_pop_free(X509_LOOKUP, (st), (free_func)) +#define sk_X509_LOOKUP_shift(st) SKM_sk_shift(X509_LOOKUP, (st)) +#define sk_X509_LOOKUP_pop(st) SKM_sk_pop(X509_LOOKUP, (st)) +#define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st)) +#define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st)) + +#define sk_X509_NAME_new(cmp) SKM_sk_new(X509_NAME, (cmp)) +#define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME) +#define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st)) +#define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st)) +#define sk_X509_NAME_value(st, i) SKM_sk_value(X509_NAME, (st), (i)) +#define sk_X509_NAME_set(st, i, val) SKM_sk_set(X509_NAME, (st), (i), (val)) +#define sk_X509_NAME_zero(st) SKM_sk_zero(X509_NAME, (st)) +#define sk_X509_NAME_push(st, val) SKM_sk_push(X509_NAME, (st), (val)) +#define sk_X509_NAME_unshift(st, val) SKM_sk_unshift(X509_NAME, (st), (val)) +#define sk_X509_NAME_find(st, val) SKM_sk_find(X509_NAME, (st), (val)) +#define sk_X509_NAME_find_ex(st, val) SKM_sk_find_ex(X509_NAME, (st), (val)) +#define sk_X509_NAME_delete(st, i) SKM_sk_delete(X509_NAME, (st), (i)) +#define sk_X509_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME, (st), (ptr)) +#define sk_X509_NAME_insert(st, val, i) SKM_sk_insert(X509_NAME, (st), (val), (i)) +#define sk_X509_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME, (st), (cmp)) +#define sk_X509_NAME_dup(st) SKM_sk_dup(X509_NAME, st) +#define sk_X509_NAME_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME, (st), (free_func)) +#define sk_X509_NAME_shift(st) SKM_sk_shift(X509_NAME, (st)) +#define sk_X509_NAME_pop(st) SKM_sk_pop(X509_NAME, (st)) +#define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st)) +#define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st)) + +#define sk_X509_NAME_ENTRY_new(cmp) SKM_sk_new(X509_NAME_ENTRY, (cmp)) +#define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY) +#define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st)) +#define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st)) +#define sk_X509_NAME_ENTRY_value(st, i) SKM_sk_value(X509_NAME_ENTRY, (st), (i)) +#define sk_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(X509_NAME_ENTRY, (st), (i), (val)) +#define sk_X509_NAME_ENTRY_zero(st) SKM_sk_zero(X509_NAME_ENTRY, (st)) +#define sk_X509_NAME_ENTRY_push(st, val) SKM_sk_push(X509_NAME_ENTRY, (st), (val)) +#define sk_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(X509_NAME_ENTRY, (st), (val)) +#define sk_X509_NAME_ENTRY_find(st, val) SKM_sk_find(X509_NAME_ENTRY, (st), (val)) +#define sk_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(X509_NAME_ENTRY, (st), (val)) +#define sk_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(X509_NAME_ENTRY, (st), (i)) +#define sk_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME_ENTRY, (st), (ptr)) +#define sk_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(X509_NAME_ENTRY, (st), (val), (i)) +#define sk_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME_ENTRY, (st), (cmp)) +#define sk_X509_NAME_ENTRY_dup(st) SKM_sk_dup(X509_NAME_ENTRY, st) +#define sk_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME_ENTRY, (st), (free_func)) +#define sk_X509_NAME_ENTRY_shift(st) SKM_sk_shift(X509_NAME_ENTRY, (st)) +#define sk_X509_NAME_ENTRY_pop(st) SKM_sk_pop(X509_NAME_ENTRY, (st)) +#define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st)) +#define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st)) + +#define sk_X509_OBJECT_new(cmp) SKM_sk_new(X509_OBJECT, (cmp)) +#define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT) +#define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st)) +#define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st)) +#define sk_X509_OBJECT_value(st, i) SKM_sk_value(X509_OBJECT, (st), (i)) +#define sk_X509_OBJECT_set(st, i, val) SKM_sk_set(X509_OBJECT, (st), (i), (val)) +#define sk_X509_OBJECT_zero(st) SKM_sk_zero(X509_OBJECT, (st)) +#define sk_X509_OBJECT_push(st, val) SKM_sk_push(X509_OBJECT, (st), (val)) +#define sk_X509_OBJECT_unshift(st, val) SKM_sk_unshift(X509_OBJECT, (st), (val)) +#define sk_X509_OBJECT_find(st, val) SKM_sk_find(X509_OBJECT, (st), (val)) +#define sk_X509_OBJECT_find_ex(st, val) SKM_sk_find_ex(X509_OBJECT, (st), (val)) +#define sk_X509_OBJECT_delete(st, i) SKM_sk_delete(X509_OBJECT, (st), (i)) +#define sk_X509_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_OBJECT, (st), (ptr)) +#define sk_X509_OBJECT_insert(st, val, i) SKM_sk_insert(X509_OBJECT, (st), (val), (i)) +#define sk_X509_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_OBJECT, (st), (cmp)) +#define sk_X509_OBJECT_dup(st) SKM_sk_dup(X509_OBJECT, st) +#define sk_X509_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(X509_OBJECT, (st), (free_func)) +#define sk_X509_OBJECT_shift(st) SKM_sk_shift(X509_OBJECT, (st)) +#define sk_X509_OBJECT_pop(st) SKM_sk_pop(X509_OBJECT, (st)) +#define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st)) +#define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st)) + +#define sk_X509_POLICY_DATA_new(cmp) SKM_sk_new(X509_POLICY_DATA, (cmp)) +#define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA) +#define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st)) +#define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st)) +#define sk_X509_POLICY_DATA_value(st, i) SKM_sk_value(X509_POLICY_DATA, (st), (i)) +#define sk_X509_POLICY_DATA_set(st, i, val) SKM_sk_set(X509_POLICY_DATA, (st), (i), (val)) +#define sk_X509_POLICY_DATA_zero(st) SKM_sk_zero(X509_POLICY_DATA, (st)) +#define sk_X509_POLICY_DATA_push(st, val) SKM_sk_push(X509_POLICY_DATA, (st), (val)) +#define sk_X509_POLICY_DATA_unshift(st, val) SKM_sk_unshift(X509_POLICY_DATA, (st), (val)) +#define sk_X509_POLICY_DATA_find(st, val) SKM_sk_find(X509_POLICY_DATA, (st), (val)) +#define sk_X509_POLICY_DATA_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_DATA, (st), (val)) +#define sk_X509_POLICY_DATA_delete(st, i) SKM_sk_delete(X509_POLICY_DATA, (st), (i)) +#define sk_X509_POLICY_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_DATA, (st), (ptr)) +#define sk_X509_POLICY_DATA_insert(st, val, i) SKM_sk_insert(X509_POLICY_DATA, (st), (val), (i)) +#define sk_X509_POLICY_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_DATA, (st), (cmp)) +#define sk_X509_POLICY_DATA_dup(st) SKM_sk_dup(X509_POLICY_DATA, st) +#define sk_X509_POLICY_DATA_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_DATA, (st), (free_func)) +#define sk_X509_POLICY_DATA_shift(st) SKM_sk_shift(X509_POLICY_DATA, (st)) +#define sk_X509_POLICY_DATA_pop(st) SKM_sk_pop(X509_POLICY_DATA, (st)) +#define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st)) +#define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st)) + +#define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp)) +#define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE) +#define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st)) +#define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st)) +#define sk_X509_POLICY_NODE_value(st, i) SKM_sk_value(X509_POLICY_NODE, (st), (i)) +#define sk_X509_POLICY_NODE_set(st, i, val) SKM_sk_set(X509_POLICY_NODE, (st), (i), (val)) +#define sk_X509_POLICY_NODE_zero(st) SKM_sk_zero(X509_POLICY_NODE, (st)) +#define sk_X509_POLICY_NODE_push(st, val) SKM_sk_push(X509_POLICY_NODE, (st), (val)) +#define sk_X509_POLICY_NODE_unshift(st, val) SKM_sk_unshift(X509_POLICY_NODE, (st), (val)) +#define sk_X509_POLICY_NODE_find(st, val) SKM_sk_find(X509_POLICY_NODE, (st), (val)) +#define sk_X509_POLICY_NODE_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_NODE, (st), (val)) +#define sk_X509_POLICY_NODE_delete(st, i) SKM_sk_delete(X509_POLICY_NODE, (st), (i)) +#define sk_X509_POLICY_NODE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_NODE, (st), (ptr)) +#define sk_X509_POLICY_NODE_insert(st, val, i) SKM_sk_insert(X509_POLICY_NODE, (st), (val), (i)) +#define sk_X509_POLICY_NODE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_NODE, (st), (cmp)) +#define sk_X509_POLICY_NODE_dup(st) SKM_sk_dup(X509_POLICY_NODE, st) +#define sk_X509_POLICY_NODE_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_NODE, (st), (free_func)) +#define sk_X509_POLICY_NODE_shift(st) SKM_sk_shift(X509_POLICY_NODE, (st)) +#define sk_X509_POLICY_NODE_pop(st) SKM_sk_pop(X509_POLICY_NODE, (st)) +#define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st)) +#define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st)) + +#define sk_X509_PURPOSE_new(cmp) SKM_sk_new(X509_PURPOSE, (cmp)) +#define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE) +#define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st)) +#define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st)) +#define sk_X509_PURPOSE_value(st, i) SKM_sk_value(X509_PURPOSE, (st), (i)) +#define sk_X509_PURPOSE_set(st, i, val) SKM_sk_set(X509_PURPOSE, (st), (i), (val)) +#define sk_X509_PURPOSE_zero(st) SKM_sk_zero(X509_PURPOSE, (st)) +#define sk_X509_PURPOSE_push(st, val) SKM_sk_push(X509_PURPOSE, (st), (val)) +#define sk_X509_PURPOSE_unshift(st, val) SKM_sk_unshift(X509_PURPOSE, (st), (val)) +#define sk_X509_PURPOSE_find(st, val) SKM_sk_find(X509_PURPOSE, (st), (val)) +#define sk_X509_PURPOSE_find_ex(st, val) SKM_sk_find_ex(X509_PURPOSE, (st), (val)) +#define sk_X509_PURPOSE_delete(st, i) SKM_sk_delete(X509_PURPOSE, (st), (i)) +#define sk_X509_PURPOSE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_PURPOSE, (st), (ptr)) +#define sk_X509_PURPOSE_insert(st, val, i) SKM_sk_insert(X509_PURPOSE, (st), (val), (i)) +#define sk_X509_PURPOSE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_PURPOSE, (st), (cmp)) +#define sk_X509_PURPOSE_dup(st) SKM_sk_dup(X509_PURPOSE, st) +#define sk_X509_PURPOSE_pop_free(st, free_func) SKM_sk_pop_free(X509_PURPOSE, (st), (free_func)) +#define sk_X509_PURPOSE_shift(st) SKM_sk_shift(X509_PURPOSE, (st)) +#define sk_X509_PURPOSE_pop(st) SKM_sk_pop(X509_PURPOSE, (st)) +#define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st)) +#define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st)) + +#define sk_X509_REVOKED_new(cmp) SKM_sk_new(X509_REVOKED, (cmp)) +#define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED) +#define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st)) +#define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st)) +#define sk_X509_REVOKED_value(st, i) SKM_sk_value(X509_REVOKED, (st), (i)) +#define sk_X509_REVOKED_set(st, i, val) SKM_sk_set(X509_REVOKED, (st), (i), (val)) +#define sk_X509_REVOKED_zero(st) SKM_sk_zero(X509_REVOKED, (st)) +#define sk_X509_REVOKED_push(st, val) SKM_sk_push(X509_REVOKED, (st), (val)) +#define sk_X509_REVOKED_unshift(st, val) SKM_sk_unshift(X509_REVOKED, (st), (val)) +#define sk_X509_REVOKED_find(st, val) SKM_sk_find(X509_REVOKED, (st), (val)) +#define sk_X509_REVOKED_find_ex(st, val) SKM_sk_find_ex(X509_REVOKED, (st), (val)) +#define sk_X509_REVOKED_delete(st, i) SKM_sk_delete(X509_REVOKED, (st), (i)) +#define sk_X509_REVOKED_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_REVOKED, (st), (ptr)) +#define sk_X509_REVOKED_insert(st, val, i) SKM_sk_insert(X509_REVOKED, (st), (val), (i)) +#define sk_X509_REVOKED_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_REVOKED, (st), (cmp)) +#define sk_X509_REVOKED_dup(st) SKM_sk_dup(X509_REVOKED, st) +#define sk_X509_REVOKED_pop_free(st, free_func) SKM_sk_pop_free(X509_REVOKED, (st), (free_func)) +#define sk_X509_REVOKED_shift(st) SKM_sk_shift(X509_REVOKED, (st)) +#define sk_X509_REVOKED_pop(st) SKM_sk_pop(X509_REVOKED, (st)) +#define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st)) +#define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st)) + +#define sk_X509_TRUST_new(cmp) SKM_sk_new(X509_TRUST, (cmp)) +#define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST) +#define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st)) +#define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st)) +#define sk_X509_TRUST_value(st, i) SKM_sk_value(X509_TRUST, (st), (i)) +#define sk_X509_TRUST_set(st, i, val) SKM_sk_set(X509_TRUST, (st), (i), (val)) +#define sk_X509_TRUST_zero(st) SKM_sk_zero(X509_TRUST, (st)) +#define sk_X509_TRUST_push(st, val) SKM_sk_push(X509_TRUST, (st), (val)) +#define sk_X509_TRUST_unshift(st, val) SKM_sk_unshift(X509_TRUST, (st), (val)) +#define sk_X509_TRUST_find(st, val) SKM_sk_find(X509_TRUST, (st), (val)) +#define sk_X509_TRUST_find_ex(st, val) SKM_sk_find_ex(X509_TRUST, (st), (val)) +#define sk_X509_TRUST_delete(st, i) SKM_sk_delete(X509_TRUST, (st), (i)) +#define sk_X509_TRUST_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_TRUST, (st), (ptr)) +#define sk_X509_TRUST_insert(st, val, i) SKM_sk_insert(X509_TRUST, (st), (val), (i)) +#define sk_X509_TRUST_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_TRUST, (st), (cmp)) +#define sk_X509_TRUST_dup(st) SKM_sk_dup(X509_TRUST, st) +#define sk_X509_TRUST_pop_free(st, free_func) SKM_sk_pop_free(X509_TRUST, (st), (free_func)) +#define sk_X509_TRUST_shift(st) SKM_sk_shift(X509_TRUST, (st)) +#define sk_X509_TRUST_pop(st) SKM_sk_pop(X509_TRUST, (st)) +#define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st)) +#define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st)) + +#define sk_X509_VERIFY_PARAM_new(cmp) SKM_sk_new(X509_VERIFY_PARAM, (cmp)) +#define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM) +#define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st)) +#define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st)) +#define sk_X509_VERIFY_PARAM_value(st, i) SKM_sk_value(X509_VERIFY_PARAM, (st), (i)) +#define sk_X509_VERIFY_PARAM_set(st, i, val) SKM_sk_set(X509_VERIFY_PARAM, (st), (i), (val)) +#define sk_X509_VERIFY_PARAM_zero(st) SKM_sk_zero(X509_VERIFY_PARAM, (st)) +#define sk_X509_VERIFY_PARAM_push(st, val) SKM_sk_push(X509_VERIFY_PARAM, (st), (val)) +#define sk_X509_VERIFY_PARAM_unshift(st, val) SKM_sk_unshift(X509_VERIFY_PARAM, (st), (val)) +#define sk_X509_VERIFY_PARAM_find(st, val) SKM_sk_find(X509_VERIFY_PARAM, (st), (val)) +#define sk_X509_VERIFY_PARAM_find_ex(st, val) SKM_sk_find_ex(X509_VERIFY_PARAM, (st), (val)) +#define sk_X509_VERIFY_PARAM_delete(st, i) SKM_sk_delete(X509_VERIFY_PARAM, (st), (i)) +#define sk_X509_VERIFY_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_VERIFY_PARAM, (st), (ptr)) +#define sk_X509_VERIFY_PARAM_insert(st, val, i) SKM_sk_insert(X509_VERIFY_PARAM, (st), (val), (i)) +#define sk_X509_VERIFY_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_VERIFY_PARAM, (st), (cmp)) +#define sk_X509_VERIFY_PARAM_dup(st) SKM_sk_dup(X509_VERIFY_PARAM, st) +#define sk_X509_VERIFY_PARAM_pop_free(st, free_func) SKM_sk_pop_free(X509_VERIFY_PARAM, (st), (free_func)) +#define sk_X509_VERIFY_PARAM_shift(st) SKM_sk_shift(X509_VERIFY_PARAM, (st)) +#define sk_X509_VERIFY_PARAM_pop(st) SKM_sk_pop(X509_VERIFY_PARAM, (st)) +#define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st)) +#define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st)) + +#define sk_nid_triple_new(cmp) SKM_sk_new(nid_triple, (cmp)) +#define sk_nid_triple_new_null() SKM_sk_new_null(nid_triple) +#define sk_nid_triple_free(st) SKM_sk_free(nid_triple, (st)) +#define sk_nid_triple_num(st) SKM_sk_num(nid_triple, (st)) +#define sk_nid_triple_value(st, i) SKM_sk_value(nid_triple, (st), (i)) +#define sk_nid_triple_set(st, i, val) SKM_sk_set(nid_triple, (st), (i), (val)) +#define sk_nid_triple_zero(st) SKM_sk_zero(nid_triple, (st)) +#define sk_nid_triple_push(st, val) SKM_sk_push(nid_triple, (st), (val)) +#define sk_nid_triple_unshift(st, val) SKM_sk_unshift(nid_triple, (st), (val)) +#define sk_nid_triple_find(st, val) SKM_sk_find(nid_triple, (st), (val)) +#define sk_nid_triple_find_ex(st, val) SKM_sk_find_ex(nid_triple, (st), (val)) +#define sk_nid_triple_delete(st, i) SKM_sk_delete(nid_triple, (st), (i)) +#define sk_nid_triple_delete_ptr(st, ptr) SKM_sk_delete_ptr(nid_triple, (st), (ptr)) +#define sk_nid_triple_insert(st, val, i) SKM_sk_insert(nid_triple, (st), (val), (i)) +#define sk_nid_triple_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(nid_triple, (st), (cmp)) +#define sk_nid_triple_dup(st) SKM_sk_dup(nid_triple, st) +#define sk_nid_triple_pop_free(st, free_func) SKM_sk_pop_free(nid_triple, (st), (free_func)) +#define sk_nid_triple_shift(st) SKM_sk_shift(nid_triple, (st)) +#define sk_nid_triple_pop(st) SKM_sk_pop(nid_triple, (st)) +#define sk_nid_triple_sort(st) SKM_sk_sort(nid_triple, (st)) +#define sk_nid_triple_is_sorted(st) SKM_sk_is_sorted(nid_triple, (st)) + +#define sk_void_new(cmp) SKM_sk_new(void, (cmp)) +#define sk_void_new_null() SKM_sk_new_null(void) +#define sk_void_free(st) SKM_sk_free(void, (st)) +#define sk_void_num(st) SKM_sk_num(void, (st)) +#define sk_void_value(st, i) SKM_sk_value(void, (st), (i)) +#define sk_void_set(st, i, val) SKM_sk_set(void, (st), (i), (val)) +#define sk_void_zero(st) SKM_sk_zero(void, (st)) +#define sk_void_push(st, val) SKM_sk_push(void, (st), (val)) +#define sk_void_unshift(st, val) SKM_sk_unshift(void, (st), (val)) +#define sk_void_find(st, val) SKM_sk_find(void, (st), (val)) +#define sk_void_find_ex(st, val) SKM_sk_find_ex(void, (st), (val)) +#define sk_void_delete(st, i) SKM_sk_delete(void, (st), (i)) +#define sk_void_delete_ptr(st, ptr) SKM_sk_delete_ptr(void, (st), (ptr)) +#define sk_void_insert(st, val, i) SKM_sk_insert(void, (st), (val), (i)) +#define sk_void_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(void, (st), (cmp)) +#define sk_void_dup(st) SKM_sk_dup(void, st) +#define sk_void_pop_free(st, free_func) SKM_sk_pop_free(void, (st), (free_func)) +#define sk_void_shift(st) SKM_sk_shift(void, (st)) +#define sk_void_pop(st) SKM_sk_pop(void, (st)) +#define sk_void_sort(st) SKM_sk_sort(void, (st)) +#define sk_void_is_sorted(st) SKM_sk_is_sorted(void, (st)) + +#define sk_OPENSSL_STRING_new(cmp) ((STACK_OF(OPENSSL_STRING) *)sk_new(CHECKED_SK_CMP_FUNC(char, cmp))) +#define sk_OPENSSL_STRING_new_null() ((STACK_OF(OPENSSL_STRING) *)sk_new_null()) +#define sk_OPENSSL_STRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_value(st, i) ((OPENSSL_STRING)sk_value(CHECKED_STACK_OF(OPENSSL_STRING, st), i)) +#define sk_OPENSSL_STRING_num(st) SKM_sk_num(OPENSSL_STRING, st) +#define sk_OPENSSL_STRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_STRING, free_func)) +#define sk_OPENSSL_STRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val), i) +#define sk_OPENSSL_STRING_free(st) SKM_sk_free(OPENSSL_STRING, st) +#define sk_OPENSSL_STRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_STRING, st), i, CHECKED_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_zero(st) SKM_sk_zero(OPENSSL_STRING, (st)) +#define sk_OPENSSL_STRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_CONST_PTR_OF(char, val)) +#define sk_OPENSSL_STRING_delete(st, i) SKM_sk_delete(OPENSSL_STRING, (st), (i)) +#define sk_OPENSSL_STRING_delete_ptr(st, ptr) (OPENSSL_STRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, ptr)) +#define sk_OPENSSL_STRING_set_cmp_func(st, cmp) \ + ((int (*)(const char * const *,const char * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_CMP_FUNC(char, cmp))) +#define sk_OPENSSL_STRING_dup(st) SKM_sk_dup(OPENSSL_STRING, st) +#define sk_OPENSSL_STRING_shift(st) SKM_sk_shift(OPENSSL_STRING, (st)) +#define sk_OPENSSL_STRING_pop(st) (char *)sk_pop(CHECKED_STACK_OF(OPENSSL_STRING, st)) +#define sk_OPENSSL_STRING_sort(st) SKM_sk_sort(OPENSSL_STRING, (st)) +#define sk_OPENSSL_STRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_STRING, (st)) + + +#define sk_OPENSSL_BLOCK_new(cmp) ((STACK_OF(OPENSSL_BLOCK) *)sk_new(CHECKED_SK_CMP_FUNC(void, cmp))) +#define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)sk_new_null()) +#define sk_OPENSSL_BLOCK_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val)) +#define sk_OPENSSL_BLOCK_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val)) +#define sk_OPENSSL_BLOCK_value(st, i) ((OPENSSL_BLOCK)sk_value(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i)) +#define sk_OPENSSL_BLOCK_num(st) SKM_sk_num(OPENSSL_BLOCK, st) +#define sk_OPENSSL_BLOCK_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_FREE_FUNC2(OPENSSL_BLOCK, free_func)) +#define sk_OPENSSL_BLOCK_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val), i) +#define sk_OPENSSL_BLOCK_free(st) SKM_sk_free(OPENSSL_BLOCK, st) +#define sk_OPENSSL_BLOCK_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i, CHECKED_PTR_OF(void, val)) +#define sk_OPENSSL_BLOCK_zero(st) SKM_sk_zero(OPENSSL_BLOCK, (st)) +#define sk_OPENSSL_BLOCK_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val)) +#define sk_OPENSSL_BLOCK_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_CONST_PTR_OF(void, val)) +#define sk_OPENSSL_BLOCK_delete(st, i) SKM_sk_delete(OPENSSL_BLOCK, (st), (i)) +#define sk_OPENSSL_BLOCK_delete_ptr(st, ptr) (OPENSSL_BLOCK *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, ptr)) +#define sk_OPENSSL_BLOCK_set_cmp_func(st, cmp) \ + ((int (*)(const void * const *,const void * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_CMP_FUNC(void, cmp))) +#define sk_OPENSSL_BLOCK_dup(st) SKM_sk_dup(OPENSSL_BLOCK, st) +#define sk_OPENSSL_BLOCK_shift(st) SKM_sk_shift(OPENSSL_BLOCK, (st)) +#define sk_OPENSSL_BLOCK_pop(st) (void *)sk_pop(CHECKED_STACK_OF(OPENSSL_BLOCK, st)) +#define sk_OPENSSL_BLOCK_sort(st) SKM_sk_sort(OPENSSL_BLOCK, (st)) +#define sk_OPENSSL_BLOCK_is_sorted(st) SKM_sk_is_sorted(OPENSSL_BLOCK, (st)) + + +#define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp))) +#define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null()) +#define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i)) +#define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st) +#define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_PSTRING, free_func)) +#define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val), i) +#define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st) +#define sk_OPENSSL_PSTRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i, CHECKED_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st)) +#define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val)) +#define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i)) +#define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, ptr)) +#define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp) \ + ((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp))) +#define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st) +#define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st)) +#define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop(CHECKED_STACK_OF(OPENSSL_PSTRING, st)) +#define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st)) +#define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st)) + + +#define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ACCESS_DESCRIPTION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_ACCESS_DESCRIPTION(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ACCESS_DESCRIPTION, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_ACCESS_DESCRIPTION(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ACCESS_DESCRIPTION, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_ASN1_INTEGER(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_INTEGER, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_ASN1_INTEGER(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_INTEGER, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_ASN1_INTEGER(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_INTEGER, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_ASN1_INTEGER(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_INTEGER, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_ASN1_OBJECT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_OBJECT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_ASN1_OBJECT(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_OBJECT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_ASN1_OBJECT(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_OBJECT, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_ASN1_OBJECT(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_OBJECT, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_ASN1_TYPE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_TYPE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_ASN1_TYPE(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_TYPE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_ASN1_TYPE(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_TYPE, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_UTF8STRING, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_UTF8STRING, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_ASN1_UTF8STRING(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_UTF8STRING, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_ASN1_UTF8STRING(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_UTF8STRING, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(DIST_POINT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_DIST_POINT(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(DIST_POINT, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_ESS_CERT_ID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ESS_CERT_ID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_ESS_CERT_ID(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ESS_CERT_ID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_ESS_CERT_ID(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ESS_CERT_ID, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_ESS_CERT_ID(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ESS_CERT_ID, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_EVP_MD(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(EVP_MD, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_EVP_MD(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(EVP_MD, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_EVP_MD(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(EVP_MD, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_EVP_MD(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(EVP_MD, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(GENERAL_NAME, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_GENERAL_NAME(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(GENERAL_NAME, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_GENERAL_NAME(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(GENERAL_NAME, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_OCSP_ONEREQ(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(OCSP_ONEREQ, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_OCSP_ONEREQ(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(OCSP_ONEREQ, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_OCSP_ONEREQ(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(OCSP_ONEREQ, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_OCSP_ONEREQ(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(OCSP_ONEREQ, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(OCSP_SINGLERESP, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(OCSP_SINGLERESP, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_OCSP_SINGLERESP(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(OCSP_SINGLERESP, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_OCSP_SINGLERESP(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(OCSP_SINGLERESP, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS12_SAFEBAG, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS12_SAFEBAG, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_PKCS12_SAFEBAG(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS12_SAFEBAG, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_PKCS12_SAFEBAG(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS12_SAFEBAG, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_PKCS7(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS7, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_PKCS7(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS7, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_PKCS7(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS7, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_PKCS7(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS7, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS7_RECIP_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS7_RECIP_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_PKCS7_RECIP_INFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS7_RECIP_INFO, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_PKCS7_RECIP_INFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS7_RECIP_INFO, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS7_SIGNER_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS7_SIGNER_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_PKCS7_SIGNER_INFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS7_SIGNER_INFO, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_PKCS7_SIGNER_INFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS7_SIGNER_INFO, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_POLICYINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(POLICYINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_POLICYINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(POLICYINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_POLICYINFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(POLICYINFO, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_POLICYINFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(POLICYINFO, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_POLICYQUALINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(POLICYQUALINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_POLICYQUALINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(POLICYQUALINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_POLICYQUALINFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(POLICYQUALINFO, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_POLICYQUALINFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(POLICYQUALINFO, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_SXNETID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(SXNETID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_SXNETID(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(SXNETID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_SXNETID(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(SXNETID, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_SXNETID(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(SXNETID, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_X509(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_X509(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_X509(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_X509(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_X509_ALGOR(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_ALGOR, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_X509_ALGOR(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_ALGOR, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_X509_ALGOR(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_ALGOR, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_X509_ALGOR(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_ALGOR, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_ATTRIBUTE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_ATTRIBUTE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_X509_ATTRIBUTE(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_ATTRIBUTE, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_X509_ATTRIBUTE(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_ATTRIBUTE, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_X509_CRL(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_CRL, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_X509_CRL(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_CRL, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_X509_CRL(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_CRL, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_X509_CRL(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_CRL, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_X509_EXTENSION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_EXTENSION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_X509_EXTENSION(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_EXTENSION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_X509_EXTENSION(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_EXTENSION, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_X509_EXTENSION(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_EXTENSION, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_NAME_ENTRY, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_NAME_ENTRY, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_X509_NAME_ENTRY(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_NAME_ENTRY, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_X509_NAME_ENTRY(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_NAME_ENTRY, (buf), (len), (d2i_func), (free_func)) + +#define d2i_ASN1_SET_OF_X509_REVOKED(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_REVOKED, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +#define i2d_ASN1_SET_OF_X509_REVOKED(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_REVOKED, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +#define ASN1_seq_pack_X509_REVOKED(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_REVOKED, (st), (i2d_func), (buf), (len)) +#define ASN1_seq_unpack_X509_REVOKED(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_REVOKED, (buf), (len), (d2i_func), (free_func)) + +#define PKCS12_decrypt_d2i_PKCS12_SAFEBAG(algor, d2i_func, free_func, pass, passlen, oct, seq) \ + SKM_PKCS12_decrypt_d2i(PKCS12_SAFEBAG, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq)) + +#define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \ + SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq)) + +#define lh_ADDED_OBJ_new() LHM_lh_new(ADDED_OBJ,added_obj) +#define lh_ADDED_OBJ_insert(lh,inst) LHM_lh_insert(ADDED_OBJ,lh,inst) +#define lh_ADDED_OBJ_retrieve(lh,inst) LHM_lh_retrieve(ADDED_OBJ,lh,inst) +#define lh_ADDED_OBJ_delete(lh,inst) LHM_lh_delete(ADDED_OBJ,lh,inst) +#define lh_ADDED_OBJ_doall(lh,fn) LHM_lh_doall(ADDED_OBJ,lh,fn) +#define lh_ADDED_OBJ_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ADDED_OBJ,lh,fn,arg_type,arg) +#define lh_ADDED_OBJ_error(lh) LHM_lh_error(ADDED_OBJ,lh) +#define lh_ADDED_OBJ_num_items(lh) LHM_lh_num_items(ADDED_OBJ,lh) +#define lh_ADDED_OBJ_down_load(lh) LHM_lh_down_load(ADDED_OBJ,lh) +#define lh_ADDED_OBJ_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ADDED_OBJ,lh,out) +#define lh_ADDED_OBJ_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ADDED_OBJ,lh,out) +#define lh_ADDED_OBJ_stats_bio(lh,out) \ + LHM_lh_stats_bio(ADDED_OBJ,lh,out) +#define lh_ADDED_OBJ_free(lh) LHM_lh_free(ADDED_OBJ,lh) + +#define lh_APP_INFO_new() LHM_lh_new(APP_INFO,app_info) +#define lh_APP_INFO_insert(lh,inst) LHM_lh_insert(APP_INFO,lh,inst) +#define lh_APP_INFO_retrieve(lh,inst) LHM_lh_retrieve(APP_INFO,lh,inst) +#define lh_APP_INFO_delete(lh,inst) LHM_lh_delete(APP_INFO,lh,inst) +#define lh_APP_INFO_doall(lh,fn) LHM_lh_doall(APP_INFO,lh,fn) +#define lh_APP_INFO_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(APP_INFO,lh,fn,arg_type,arg) +#define lh_APP_INFO_error(lh) LHM_lh_error(APP_INFO,lh) +#define lh_APP_INFO_num_items(lh) LHM_lh_num_items(APP_INFO,lh) +#define lh_APP_INFO_down_load(lh) LHM_lh_down_load(APP_INFO,lh) +#define lh_APP_INFO_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(APP_INFO,lh,out) +#define lh_APP_INFO_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(APP_INFO,lh,out) +#define lh_APP_INFO_stats_bio(lh,out) \ + LHM_lh_stats_bio(APP_INFO,lh,out) +#define lh_APP_INFO_free(lh) LHM_lh_free(APP_INFO,lh) + +#define lh_CONF_VALUE_new() LHM_lh_new(CONF_VALUE,conf_value) +#define lh_CONF_VALUE_insert(lh,inst) LHM_lh_insert(CONF_VALUE,lh,inst) +#define lh_CONF_VALUE_retrieve(lh,inst) LHM_lh_retrieve(CONF_VALUE,lh,inst) +#define lh_CONF_VALUE_delete(lh,inst) LHM_lh_delete(CONF_VALUE,lh,inst) +#define lh_CONF_VALUE_doall(lh,fn) LHM_lh_doall(CONF_VALUE,lh,fn) +#define lh_CONF_VALUE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(CONF_VALUE,lh,fn,arg_type,arg) +#define lh_CONF_VALUE_error(lh) LHM_lh_error(CONF_VALUE,lh) +#define lh_CONF_VALUE_num_items(lh) LHM_lh_num_items(CONF_VALUE,lh) +#define lh_CONF_VALUE_down_load(lh) LHM_lh_down_load(CONF_VALUE,lh) +#define lh_CONF_VALUE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(CONF_VALUE,lh,out) +#define lh_CONF_VALUE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(CONF_VALUE,lh,out) +#define lh_CONF_VALUE_stats_bio(lh,out) \ + LHM_lh_stats_bio(CONF_VALUE,lh,out) +#define lh_CONF_VALUE_free(lh) LHM_lh_free(CONF_VALUE,lh) + +#define lh_ENGINE_PILE_new() LHM_lh_new(ENGINE_PILE,engine_pile) +#define lh_ENGINE_PILE_insert(lh,inst) LHM_lh_insert(ENGINE_PILE,lh,inst) +#define lh_ENGINE_PILE_retrieve(lh,inst) LHM_lh_retrieve(ENGINE_PILE,lh,inst) +#define lh_ENGINE_PILE_delete(lh,inst) LHM_lh_delete(ENGINE_PILE,lh,inst) +#define lh_ENGINE_PILE_doall(lh,fn) LHM_lh_doall(ENGINE_PILE,lh,fn) +#define lh_ENGINE_PILE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ENGINE_PILE,lh,fn,arg_type,arg) +#define lh_ENGINE_PILE_error(lh) LHM_lh_error(ENGINE_PILE,lh) +#define lh_ENGINE_PILE_num_items(lh) LHM_lh_num_items(ENGINE_PILE,lh) +#define lh_ENGINE_PILE_down_load(lh) LHM_lh_down_load(ENGINE_PILE,lh) +#define lh_ENGINE_PILE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ENGINE_PILE,lh,out) +#define lh_ENGINE_PILE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ENGINE_PILE,lh,out) +#define lh_ENGINE_PILE_stats_bio(lh,out) \ + LHM_lh_stats_bio(ENGINE_PILE,lh,out) +#define lh_ENGINE_PILE_free(lh) LHM_lh_free(ENGINE_PILE,lh) + +#define lh_ERR_STATE_new() LHM_lh_new(ERR_STATE,err_state) +#define lh_ERR_STATE_insert(lh,inst) LHM_lh_insert(ERR_STATE,lh,inst) +#define lh_ERR_STATE_retrieve(lh,inst) LHM_lh_retrieve(ERR_STATE,lh,inst) +#define lh_ERR_STATE_delete(lh,inst) LHM_lh_delete(ERR_STATE,lh,inst) +#define lh_ERR_STATE_doall(lh,fn) LHM_lh_doall(ERR_STATE,lh,fn) +#define lh_ERR_STATE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ERR_STATE,lh,fn,arg_type,arg) +#define lh_ERR_STATE_error(lh) LHM_lh_error(ERR_STATE,lh) +#define lh_ERR_STATE_num_items(lh) LHM_lh_num_items(ERR_STATE,lh) +#define lh_ERR_STATE_down_load(lh) LHM_lh_down_load(ERR_STATE,lh) +#define lh_ERR_STATE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ERR_STATE,lh,out) +#define lh_ERR_STATE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ERR_STATE,lh,out) +#define lh_ERR_STATE_stats_bio(lh,out) \ + LHM_lh_stats_bio(ERR_STATE,lh,out) +#define lh_ERR_STATE_free(lh) LHM_lh_free(ERR_STATE,lh) + +#define lh_ERR_STRING_DATA_new() LHM_lh_new(ERR_STRING_DATA,err_string_data) +#define lh_ERR_STRING_DATA_insert(lh,inst) LHM_lh_insert(ERR_STRING_DATA,lh,inst) +#define lh_ERR_STRING_DATA_retrieve(lh,inst) LHM_lh_retrieve(ERR_STRING_DATA,lh,inst) +#define lh_ERR_STRING_DATA_delete(lh,inst) LHM_lh_delete(ERR_STRING_DATA,lh,inst) +#define lh_ERR_STRING_DATA_doall(lh,fn) LHM_lh_doall(ERR_STRING_DATA,lh,fn) +#define lh_ERR_STRING_DATA_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ERR_STRING_DATA,lh,fn,arg_type,arg) +#define lh_ERR_STRING_DATA_error(lh) LHM_lh_error(ERR_STRING_DATA,lh) +#define lh_ERR_STRING_DATA_num_items(lh) LHM_lh_num_items(ERR_STRING_DATA,lh) +#define lh_ERR_STRING_DATA_down_load(lh) LHM_lh_down_load(ERR_STRING_DATA,lh) +#define lh_ERR_STRING_DATA_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ERR_STRING_DATA,lh,out) +#define lh_ERR_STRING_DATA_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ERR_STRING_DATA,lh,out) +#define lh_ERR_STRING_DATA_stats_bio(lh,out) \ + LHM_lh_stats_bio(ERR_STRING_DATA,lh,out) +#define lh_ERR_STRING_DATA_free(lh) LHM_lh_free(ERR_STRING_DATA,lh) + +#define lh_EX_CLASS_ITEM_new() LHM_lh_new(EX_CLASS_ITEM,ex_class_item) +#define lh_EX_CLASS_ITEM_insert(lh,inst) LHM_lh_insert(EX_CLASS_ITEM,lh,inst) +#define lh_EX_CLASS_ITEM_retrieve(lh,inst) LHM_lh_retrieve(EX_CLASS_ITEM,lh,inst) +#define lh_EX_CLASS_ITEM_delete(lh,inst) LHM_lh_delete(EX_CLASS_ITEM,lh,inst) +#define lh_EX_CLASS_ITEM_doall(lh,fn) LHM_lh_doall(EX_CLASS_ITEM,lh,fn) +#define lh_EX_CLASS_ITEM_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(EX_CLASS_ITEM,lh,fn,arg_type,arg) +#define lh_EX_CLASS_ITEM_error(lh) LHM_lh_error(EX_CLASS_ITEM,lh) +#define lh_EX_CLASS_ITEM_num_items(lh) LHM_lh_num_items(EX_CLASS_ITEM,lh) +#define lh_EX_CLASS_ITEM_down_load(lh) LHM_lh_down_load(EX_CLASS_ITEM,lh) +#define lh_EX_CLASS_ITEM_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(EX_CLASS_ITEM,lh,out) +#define lh_EX_CLASS_ITEM_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(EX_CLASS_ITEM,lh,out) +#define lh_EX_CLASS_ITEM_stats_bio(lh,out) \ + LHM_lh_stats_bio(EX_CLASS_ITEM,lh,out) +#define lh_EX_CLASS_ITEM_free(lh) LHM_lh_free(EX_CLASS_ITEM,lh) + +#define lh_FUNCTION_new() LHM_lh_new(FUNCTION,function) +#define lh_FUNCTION_insert(lh,inst) LHM_lh_insert(FUNCTION,lh,inst) +#define lh_FUNCTION_retrieve(lh,inst) LHM_lh_retrieve(FUNCTION,lh,inst) +#define lh_FUNCTION_delete(lh,inst) LHM_lh_delete(FUNCTION,lh,inst) +#define lh_FUNCTION_doall(lh,fn) LHM_lh_doall(FUNCTION,lh,fn) +#define lh_FUNCTION_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(FUNCTION,lh,fn,arg_type,arg) +#define lh_FUNCTION_error(lh) LHM_lh_error(FUNCTION,lh) +#define lh_FUNCTION_num_items(lh) LHM_lh_num_items(FUNCTION,lh) +#define lh_FUNCTION_down_load(lh) LHM_lh_down_load(FUNCTION,lh) +#define lh_FUNCTION_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(FUNCTION,lh,out) +#define lh_FUNCTION_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(FUNCTION,lh,out) +#define lh_FUNCTION_stats_bio(lh,out) \ + LHM_lh_stats_bio(FUNCTION,lh,out) +#define lh_FUNCTION_free(lh) LHM_lh_free(FUNCTION,lh) + +#define lh_MEM_new() LHM_lh_new(MEM,mem) +#define lh_MEM_insert(lh,inst) LHM_lh_insert(MEM,lh,inst) +#define lh_MEM_retrieve(lh,inst) LHM_lh_retrieve(MEM,lh,inst) +#define lh_MEM_delete(lh,inst) LHM_lh_delete(MEM,lh,inst) +#define lh_MEM_doall(lh,fn) LHM_lh_doall(MEM,lh,fn) +#define lh_MEM_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(MEM,lh,fn,arg_type,arg) +#define lh_MEM_error(lh) LHM_lh_error(MEM,lh) +#define lh_MEM_num_items(lh) LHM_lh_num_items(MEM,lh) +#define lh_MEM_down_load(lh) LHM_lh_down_load(MEM,lh) +#define lh_MEM_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(MEM,lh,out) +#define lh_MEM_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(MEM,lh,out) +#define lh_MEM_stats_bio(lh,out) \ + LHM_lh_stats_bio(MEM,lh,out) +#define lh_MEM_free(lh) LHM_lh_free(MEM,lh) + +#define lh_OBJ_NAME_new() LHM_lh_new(OBJ_NAME,obj_name) +#define lh_OBJ_NAME_insert(lh,inst) LHM_lh_insert(OBJ_NAME,lh,inst) +#define lh_OBJ_NAME_retrieve(lh,inst) LHM_lh_retrieve(OBJ_NAME,lh,inst) +#define lh_OBJ_NAME_delete(lh,inst) LHM_lh_delete(OBJ_NAME,lh,inst) +#define lh_OBJ_NAME_doall(lh,fn) LHM_lh_doall(OBJ_NAME,lh,fn) +#define lh_OBJ_NAME_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OBJ_NAME,lh,fn,arg_type,arg) +#define lh_OBJ_NAME_error(lh) LHM_lh_error(OBJ_NAME,lh) +#define lh_OBJ_NAME_num_items(lh) LHM_lh_num_items(OBJ_NAME,lh) +#define lh_OBJ_NAME_down_load(lh) LHM_lh_down_load(OBJ_NAME,lh) +#define lh_OBJ_NAME_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OBJ_NAME,lh,out) +#define lh_OBJ_NAME_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OBJ_NAME,lh,out) +#define lh_OBJ_NAME_stats_bio(lh,out) \ + LHM_lh_stats_bio(OBJ_NAME,lh,out) +#define lh_OBJ_NAME_free(lh) LHM_lh_free(OBJ_NAME,lh) + +#define lh_OPENSSL_CSTRING_new() LHM_lh_new(OPENSSL_CSTRING,openssl_cstring) +#define lh_OPENSSL_CSTRING_insert(lh,inst) LHM_lh_insert(OPENSSL_CSTRING,lh,inst) +#define lh_OPENSSL_CSTRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_CSTRING,lh,inst) +#define lh_OPENSSL_CSTRING_delete(lh,inst) LHM_lh_delete(OPENSSL_CSTRING,lh,inst) +#define lh_OPENSSL_CSTRING_doall(lh,fn) LHM_lh_doall(OPENSSL_CSTRING,lh,fn) +#define lh_OPENSSL_CSTRING_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OPENSSL_CSTRING,lh,fn,arg_type,arg) +#define lh_OPENSSL_CSTRING_error(lh) LHM_lh_error(OPENSSL_CSTRING,lh) +#define lh_OPENSSL_CSTRING_num_items(lh) LHM_lh_num_items(OPENSSL_CSTRING,lh) +#define lh_OPENSSL_CSTRING_down_load(lh) LHM_lh_down_load(OPENSSL_CSTRING,lh) +#define lh_OPENSSL_CSTRING_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OPENSSL_CSTRING,lh,out) +#define lh_OPENSSL_CSTRING_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OPENSSL_CSTRING,lh,out) +#define lh_OPENSSL_CSTRING_stats_bio(lh,out) \ + LHM_lh_stats_bio(OPENSSL_CSTRING,lh,out) +#define lh_OPENSSL_CSTRING_free(lh) LHM_lh_free(OPENSSL_CSTRING,lh) + +#define lh_OPENSSL_STRING_new() LHM_lh_new(OPENSSL_STRING,openssl_string) +#define lh_OPENSSL_STRING_insert(lh,inst) LHM_lh_insert(OPENSSL_STRING,lh,inst) +#define lh_OPENSSL_STRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_STRING,lh,inst) +#define lh_OPENSSL_STRING_delete(lh,inst) LHM_lh_delete(OPENSSL_STRING,lh,inst) +#define lh_OPENSSL_STRING_doall(lh,fn) LHM_lh_doall(OPENSSL_STRING,lh,fn) +#define lh_OPENSSL_STRING_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OPENSSL_STRING,lh,fn,arg_type,arg) +#define lh_OPENSSL_STRING_error(lh) LHM_lh_error(OPENSSL_STRING,lh) +#define lh_OPENSSL_STRING_num_items(lh) LHM_lh_num_items(OPENSSL_STRING,lh) +#define lh_OPENSSL_STRING_down_load(lh) LHM_lh_down_load(OPENSSL_STRING,lh) +#define lh_OPENSSL_STRING_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OPENSSL_STRING,lh,out) +#define lh_OPENSSL_STRING_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OPENSSL_STRING,lh,out) +#define lh_OPENSSL_STRING_stats_bio(lh,out) \ + LHM_lh_stats_bio(OPENSSL_STRING,lh,out) +#define lh_OPENSSL_STRING_free(lh) LHM_lh_free(OPENSSL_STRING,lh) + +#define lh_SSL_SESSION_new() LHM_lh_new(SSL_SESSION,ssl_session) +#define lh_SSL_SESSION_insert(lh,inst) LHM_lh_insert(SSL_SESSION,lh,inst) +#define lh_SSL_SESSION_retrieve(lh,inst) LHM_lh_retrieve(SSL_SESSION,lh,inst) +#define lh_SSL_SESSION_delete(lh,inst) LHM_lh_delete(SSL_SESSION,lh,inst) +#define lh_SSL_SESSION_doall(lh,fn) LHM_lh_doall(SSL_SESSION,lh,fn) +#define lh_SSL_SESSION_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(SSL_SESSION,lh,fn,arg_type,arg) +#define lh_SSL_SESSION_error(lh) LHM_lh_error(SSL_SESSION,lh) +#define lh_SSL_SESSION_num_items(lh) LHM_lh_num_items(SSL_SESSION,lh) +#define lh_SSL_SESSION_down_load(lh) LHM_lh_down_load(SSL_SESSION,lh) +#define lh_SSL_SESSION_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(SSL_SESSION,lh,out) +#define lh_SSL_SESSION_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(SSL_SESSION,lh,out) +#define lh_SSL_SESSION_stats_bio(lh,out) \ + LHM_lh_stats_bio(SSL_SESSION,lh,out) +#define lh_SSL_SESSION_free(lh) LHM_lh_free(SSL_SESSION,lh) +/* End of util/mkstack.pl block, you may now edit :-) */ + +#endif /* !defined HEADER_SAFESTACK_H */ diff --git a/extra_lib/include/openssl/sha.h b/extra_lib/include/openssl/sha.h new file mode 100644 index 0000000..16cacf9 --- /dev/null +++ b/extra_lib/include/openssl/sha.h @@ -0,0 +1,200 @@ +/* crypto/sha/sha.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_SHA_H +#define HEADER_SHA_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(OPENSSL_NO_SHA) || (defined(OPENSSL_NO_SHA0) && defined(OPENSSL_NO_SHA1)) +#error SHA is disabled. +#endif + +#if defined(OPENSSL_FIPS) +#define FIPS_SHA_SIZE_T size_t +#endif + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! SHA_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +#if defined(__LP32__) +#define SHA_LONG unsigned long +#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) +#define SHA_LONG unsigned long +#define SHA_LONG_LOG2 3 +#else +#define SHA_LONG unsigned int +#endif + +#define SHA_LBLOCK 16 +#define SHA_CBLOCK (SHA_LBLOCK*4) /* SHA treats input data as a + * contiguous array of 32 bit + * wide big-endian values. */ +#define SHA_LAST_BLOCK (SHA_CBLOCK-8) +#define SHA_DIGEST_LENGTH 20 + +typedef struct SHAstate_st + { + SHA_LONG h0,h1,h2,h3,h4; + SHA_LONG Nl,Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num; + } SHA_CTX; + +#ifndef OPENSSL_NO_SHA0 +int SHA_Init(SHA_CTX *c); +int SHA_Update(SHA_CTX *c, const void *data, size_t len); +int SHA_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md); +void SHA_Transform(SHA_CTX *c, const unsigned char *data); +#endif +#ifndef OPENSSL_NO_SHA1 +int SHA1_Init(SHA_CTX *c); +int SHA1_Update(SHA_CTX *c, const void *data, size_t len); +int SHA1_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md); +void SHA1_Transform(SHA_CTX *c, const unsigned char *data); +#endif + +#define SHA256_CBLOCK (SHA_LBLOCK*4) /* SHA-256 treats input data as a + * contiguous array of 32 bit + * wide big-endian values. */ +#define SHA224_DIGEST_LENGTH 28 +#define SHA256_DIGEST_LENGTH 32 + +typedef struct SHA256state_st + { + SHA_LONG h[8]; + SHA_LONG Nl,Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num,md_len; + } SHA256_CTX; + +#ifndef OPENSSL_NO_SHA256 +int SHA224_Init(SHA256_CTX *c); +int SHA224_Update(SHA256_CTX *c, const void *data, size_t len); +int SHA224_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA224(const unsigned char *d, size_t n,unsigned char *md); +int SHA256_Init(SHA256_CTX *c); +int SHA256_Update(SHA256_CTX *c, const void *data, size_t len); +int SHA256_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA256(const unsigned char *d, size_t n,unsigned char *md); +void SHA256_Transform(SHA256_CTX *c, const unsigned char *data); +#endif + +#define SHA384_DIGEST_LENGTH 48 +#define SHA512_DIGEST_LENGTH 64 + +#ifndef OPENSSL_NO_SHA512 +/* + * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64 + * being exactly 64-bit wide. See Implementation Notes in sha512.c + * for further details. + */ +#define SHA512_CBLOCK (SHA_LBLOCK*8) /* SHA-512 treats input data as a + * contiguous array of 64 bit + * wide big-endian values. */ +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +#define SHA_LONG64 unsigned __int64 +#define U64(C) C##UI64 +#elif defined(__arch64__) +#define SHA_LONG64 unsigned long +#define U64(C) C##UL +#else +#define SHA_LONG64 unsigned long long +#define U64(C) C##ULL +#endif + +typedef struct SHA512state_st + { + SHA_LONG64 h[8]; + SHA_LONG64 Nl,Nh; + union { + SHA_LONG64 d[SHA_LBLOCK]; + unsigned char p[SHA512_CBLOCK]; + } u; + unsigned int num,md_len; + } SHA512_CTX; +#endif + +#ifndef OPENSSL_NO_SHA512 +int SHA384_Init(SHA512_CTX *c); +int SHA384_Update(SHA512_CTX *c, const void *data, size_t len); +int SHA384_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA384(const unsigned char *d, size_t n,unsigned char *md); +int SHA512_Init(SHA512_CTX *c); +int SHA512_Update(SHA512_CTX *c, const void *data, size_t len); +int SHA512_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA512(const unsigned char *d, size_t n,unsigned char *md); +void SHA512_Transform(SHA512_CTX *c, const unsigned char *data); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/extra_lib/include/openssl/ssl.h b/extra_lib/include/openssl/ssl.h new file mode 100644 index 0000000..e4c3f65 --- /dev/null +++ b/extra_lib/include/openssl/ssl.h @@ -0,0 +1,2302 @@ +/* ssl/ssl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef HEADER_SSL_H +#define HEADER_SSL_H + +#include + +#ifndef OPENSSL_NO_COMP +#include +#endif +#ifndef OPENSSL_NO_BIO +#include +#endif +#ifndef OPENSSL_NO_DEPRECATED +#ifndef OPENSSL_NO_X509 +#include +#endif +#include +#include +#include +#endif +#include +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* SSLeay version number for ASN.1 encoding of the session information */ +/* Version 0 - initial version + * Version 1 - added the optional peer certificate + */ +#define SSL_SESSION_ASN1_VERSION 0x0001 + +/* text strings for the ciphers */ +#define SSL_TXT_NULL_WITH_MD5 SSL2_TXT_NULL_WITH_MD5 +#define SSL_TXT_RC4_128_WITH_MD5 SSL2_TXT_RC4_128_WITH_MD5 +#define SSL_TXT_RC4_128_EXPORT40_WITH_MD5 SSL2_TXT_RC4_128_EXPORT40_WITH_MD5 +#define SSL_TXT_RC2_128_CBC_WITH_MD5 SSL2_TXT_RC2_128_CBC_WITH_MD5 +#define SSL_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 +#define SSL_TXT_IDEA_128_CBC_WITH_MD5 SSL2_TXT_IDEA_128_CBC_WITH_MD5 +#define SSL_TXT_DES_64_CBC_WITH_MD5 SSL2_TXT_DES_64_CBC_WITH_MD5 +#define SSL_TXT_DES_64_CBC_WITH_SHA SSL2_TXT_DES_64_CBC_WITH_SHA +#define SSL_TXT_DES_192_EDE3_CBC_WITH_MD5 SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5 +#define SSL_TXT_DES_192_EDE3_CBC_WITH_SHA SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA + +/* VRS Additional Kerberos5 entries + */ +#define SSL_TXT_KRB5_DES_64_CBC_SHA SSL3_TXT_KRB5_DES_64_CBC_SHA +#define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA +#define SSL_TXT_KRB5_RC4_128_SHA SSL3_TXT_KRB5_RC4_128_SHA +#define SSL_TXT_KRB5_IDEA_128_CBC_SHA SSL3_TXT_KRB5_IDEA_128_CBC_SHA +#define SSL_TXT_KRB5_DES_64_CBC_MD5 SSL3_TXT_KRB5_DES_64_CBC_MD5 +#define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5 +#define SSL_TXT_KRB5_RC4_128_MD5 SSL3_TXT_KRB5_RC4_128_MD5 +#define SSL_TXT_KRB5_IDEA_128_CBC_MD5 SSL3_TXT_KRB5_IDEA_128_CBC_MD5 + +#define SSL_TXT_KRB5_DES_40_CBC_SHA SSL3_TXT_KRB5_DES_40_CBC_SHA +#define SSL_TXT_KRB5_RC2_40_CBC_SHA SSL3_TXT_KRB5_RC2_40_CBC_SHA +#define SSL_TXT_KRB5_RC4_40_SHA SSL3_TXT_KRB5_RC4_40_SHA +#define SSL_TXT_KRB5_DES_40_CBC_MD5 SSL3_TXT_KRB5_DES_40_CBC_MD5 +#define SSL_TXT_KRB5_RC2_40_CBC_MD5 SSL3_TXT_KRB5_RC2_40_CBC_MD5 +#define SSL_TXT_KRB5_RC4_40_MD5 SSL3_TXT_KRB5_RC4_40_MD5 + +#define SSL_TXT_KRB5_DES_40_CBC_SHA SSL3_TXT_KRB5_DES_40_CBC_SHA +#define SSL_TXT_KRB5_DES_40_CBC_MD5 SSL3_TXT_KRB5_DES_40_CBC_MD5 +#define SSL_TXT_KRB5_DES_64_CBC_SHA SSL3_TXT_KRB5_DES_64_CBC_SHA +#define SSL_TXT_KRB5_DES_64_CBC_MD5 SSL3_TXT_KRB5_DES_64_CBC_MD5 +#define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA +#define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5 +#define SSL_MAX_KRB5_PRINCIPAL_LENGTH 256 + +#define SSL_MAX_SSL_SESSION_ID_LENGTH 32 +#define SSL_MAX_SID_CTX_LENGTH 32 + +#define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES (512/8) +#define SSL_MAX_KEY_ARG_LENGTH 8 +#define SSL_MAX_MASTER_KEY_LENGTH 48 + + +/* These are used to specify which ciphers to use and not to use */ + +#define SSL_TXT_EXP40 "EXPORT40" +#define SSL_TXT_EXP56 "EXPORT56" +#define SSL_TXT_LOW "LOW" +#define SSL_TXT_MEDIUM "MEDIUM" +#define SSL_TXT_HIGH "HIGH" +#define SSL_TXT_FIPS "FIPS" + +#define SSL_TXT_kFZA "kFZA" /* unused! */ +#define SSL_TXT_aFZA "aFZA" /* unused! */ +#define SSL_TXT_eFZA "eFZA" /* unused! */ +#define SSL_TXT_FZA "FZA" /* unused! */ + +#define SSL_TXT_aNULL "aNULL" +#define SSL_TXT_eNULL "eNULL" +#define SSL_TXT_NULL "NULL" + +#define SSL_TXT_kRSA "kRSA" +#define SSL_TXT_kDHr "kDHr" /* no such ciphersuites supported! */ +#define SSL_TXT_kDHd "kDHd" /* no such ciphersuites supported! */ +#define SSL_TXT_kDH "kDH" /* no such ciphersuites supported! */ +#define SSL_TXT_kEDH "kEDH" +#define SSL_TXT_kKRB5 "kKRB5" +#define SSL_TXT_kECDHr "kECDHr" +#define SSL_TXT_kECDHe "kECDHe" +#define SSL_TXT_kECDH "kECDH" +#define SSL_TXT_kEECDH "kEECDH" +#define SSL_TXT_kPSK "kPSK" +#define SSL_TXT_kGOST "kGOST" + +#define SSL_TXT_aRSA "aRSA" +#define SSL_TXT_aDSS "aDSS" +#define SSL_TXT_aDH "aDH" /* no such ciphersuites supported! */ +#define SSL_TXT_aECDH "aECDH" +#define SSL_TXT_aKRB5 "aKRB5" +#define SSL_TXT_aECDSA "aECDSA" +#define SSL_TXT_aPSK "aPSK" +#define SSL_TXT_aGOST94 "aGOST94" +#define SSL_TXT_aGOST01 "aGOST01" +#define SSL_TXT_aGOST "aGOST" + +#define SSL_TXT_DSS "DSS" +#define SSL_TXT_DH "DH" +#define SSL_TXT_EDH "EDH" /* same as "kEDH:-ADH" */ +#define SSL_TXT_ADH "ADH" +#define SSL_TXT_RSA "RSA" +#define SSL_TXT_ECDH "ECDH" +#define SSL_TXT_EECDH "EECDH" /* same as "kEECDH:-AECDH" */ +#define SSL_TXT_AECDH "AECDH" +#define SSL_TXT_ECDSA "ECDSA" +#define SSL_TXT_KRB5 "KRB5" +#define SSL_TXT_PSK "PSK" + +#define SSL_TXT_DES "DES" +#define SSL_TXT_3DES "3DES" +#define SSL_TXT_RC4 "RC4" +#define SSL_TXT_RC2 "RC2" +#define SSL_TXT_IDEA "IDEA" +#define SSL_TXT_SEED "SEED" +#define SSL_TXT_AES128 "AES128" +#define SSL_TXT_AES256 "AES256" +#define SSL_TXT_AES "AES" +#define SSL_TXT_CAMELLIA128 "CAMELLIA128" +#define SSL_TXT_CAMELLIA256 "CAMELLIA256" +#define SSL_TXT_CAMELLIA "CAMELLIA" + +#define SSL_TXT_MD5 "MD5" +#define SSL_TXT_SHA1 "SHA1" +#define SSL_TXT_SHA "SHA" /* same as "SHA1" */ +#define SSL_TXT_GOST94 "GOST94" +#define SSL_TXT_GOST89MAC "GOST89MAC" + +#define SSL_TXT_SSLV2 "SSLv2" +#define SSL_TXT_SSLV3 "SSLv3" +#define SSL_TXT_TLSV1 "TLSv1" + +#define SSL_TXT_EXP "EXP" +#define SSL_TXT_EXPORT "EXPORT" + +#define SSL_TXT_ALL "ALL" + +/* + * COMPLEMENTOF* definitions. These identifiers are used to (de-select) + * ciphers normally not being used. + * Example: "RC4" will activate all ciphers using RC4 including ciphers + * without authentication, which would normally disabled by DEFAULT (due + * the "!ADH" being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT" + * will make sure that it is also disabled in the specific selection. + * COMPLEMENTOF* identifiers are portable between version, as adjustments + * to the default cipher setup will also be included here. + * + * COMPLEMENTOFDEFAULT does not experience the same special treatment that + * DEFAULT gets, as only selection is being done and no sorting as needed + * for DEFAULT. + */ +#define SSL_TXT_CMPALL "COMPLEMENTOFALL" +#define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT" + +/* The following cipher list is used by default. + * It also is substituted when an application-defined cipher list string + * starts with 'DEFAULT'. */ +#define SSL_DEFAULT_CIPHER_LIST "ALL:!aNULL:!eNULL:!SSLv2" +/* As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always + * starts with a reasonable order, and all we have to do for DEFAULT is + * throwing out anonymous and unencrypted ciphersuites! + * (The latter are not actually enabled by ALL, but "ALL:RSA" would enable + * some of them.) + */ + +/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ +#define SSL_SENT_SHUTDOWN 1 +#define SSL_RECEIVED_SHUTDOWN 2 + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if (defined(OPENSSL_NO_RSA) || defined(OPENSSL_NO_MD5)) && !defined(OPENSSL_NO_SSL2) +#define OPENSSL_NO_SSL2 +#endif + +#define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1 +#define SSL_FILETYPE_PEM X509_FILETYPE_PEM + +/* This is needed to stop compilers complaining about the + * 'struct ssl_st *' function parameters used to prototype callbacks + * in SSL_CTX. */ +typedef struct ssl_st *ssl_crock_st; +typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT; + +/* used to hold info on the particular ciphers used */ +typedef struct ssl_cipher_st + { + int valid; + const char *name; /* text name */ + unsigned long id; /* id, 4 bytes, first is version */ + + /* changed in 0.9.9: these four used to be portions of a single value 'algorithms' */ + unsigned long algorithm_mkey; /* key exchange algorithm */ + unsigned long algorithm_auth; /* server authentication */ + unsigned long algorithm_enc; /* symmetric encryption */ + unsigned long algorithm_mac; /* symmetric authentication */ + unsigned long algorithm_ssl; /* (major) protocol version */ + + unsigned long algo_strength; /* strength and export flags */ + unsigned long algorithm2; /* Extra flags */ + int strength_bits; /* Number of bits really used */ + int alg_bits; /* Number of bits for algorithm */ + } SSL_CIPHER; + +DECLARE_STACK_OF(SSL_CIPHER) + +typedef int (*tls_session_ticket_ext_cb_fn)(SSL *s, const unsigned char *data, int len, void *arg); +typedef int (*tls_session_secret_cb_fn)(SSL *s, void *secret, int *secret_len, STACK_OF(SSL_CIPHER) *peer_ciphers, SSL_CIPHER **cipher, void *arg); + +/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */ +typedef struct ssl_method_st + { + int version; + int (*ssl_new)(SSL *s); + void (*ssl_clear)(SSL *s); + void (*ssl_free)(SSL *s); + int (*ssl_accept)(SSL *s); + int (*ssl_connect)(SSL *s); + int (*ssl_read)(SSL *s,void *buf,int len); + int (*ssl_peek)(SSL *s,void *buf,int len); + int (*ssl_write)(SSL *s,const void *buf,int len); + int (*ssl_shutdown)(SSL *s); + int (*ssl_renegotiate)(SSL *s); + int (*ssl_renegotiate_check)(SSL *s); + long (*ssl_get_message)(SSL *s, int st1, int stn, int mt, long + max, int *ok); + int (*ssl_read_bytes)(SSL *s, int type, unsigned char *buf, int len, + int peek); + int (*ssl_write_bytes)(SSL *s, int type, const void *buf_, int len); + int (*ssl_dispatch_alert)(SSL *s); + long (*ssl_ctrl)(SSL *s,int cmd,long larg,void *parg); + long (*ssl_ctx_ctrl)(SSL_CTX *ctx,int cmd,long larg,void *parg); + const SSL_CIPHER *(*get_cipher_by_char)(const unsigned char *ptr); + int (*put_cipher_by_char)(const SSL_CIPHER *cipher,unsigned char *ptr); + int (*ssl_pending)(const SSL *s); + int (*num_ciphers)(void); + const SSL_CIPHER *(*get_cipher)(unsigned ncipher); + const struct ssl_method_st *(*get_ssl_method)(int version); + long (*get_timeout)(void); + struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */ + int (*ssl_version)(void); + long (*ssl_callback_ctrl)(SSL *s, int cb_id, void (*fp)(void)); + long (*ssl_ctx_callback_ctrl)(SSL_CTX *s, int cb_id, void (*fp)(void)); + } SSL_METHOD; + +/* Lets make this into an ASN.1 type structure as follows + * SSL_SESSION_ID ::= SEQUENCE { + * version INTEGER, -- structure version number + * SSLversion INTEGER, -- SSL version number + * Cipher OCTET STRING, -- the 3 byte cipher ID + * Session_ID OCTET STRING, -- the Session ID + * Master_key OCTET STRING, -- the master key + * KRB5_principal OCTET STRING -- optional Kerberos principal + * Key_Arg [ 0 ] IMPLICIT OCTET STRING, -- the optional Key argument + * Time [ 1 ] EXPLICIT INTEGER, -- optional Start Time + * Timeout [ 2 ] EXPLICIT INTEGER, -- optional Timeout ins seconds + * Peer [ 3 ] EXPLICIT X509, -- optional Peer Certificate + * Session_ID_context [ 4 ] EXPLICIT OCTET STRING, -- the Session ID context + * Verify_result [ 5 ] EXPLICIT INTEGER, -- X509_V_... code for `Peer' + * HostName [ 6 ] EXPLICIT OCTET STRING, -- optional HostName from servername TLS extension + * ECPointFormatList [ 7 ] OCTET STRING, -- optional EC point format list from TLS extension + * PSK_identity_hint [ 8 ] EXPLICIT OCTET STRING, -- optional PSK identity hint + * PSK_identity [ 9 ] EXPLICIT OCTET STRING -- optional PSK identity + * } + * Look in ssl/ssl_asn1.c for more details + * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-). + */ +typedef struct ssl_session_st + { + int ssl_version; /* what ssl version session info is + * being kept in here? */ + + /* only really used in SSLv2 */ + unsigned int key_arg_length; + unsigned char key_arg[SSL_MAX_KEY_ARG_LENGTH]; + int master_key_length; + unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH]; + /* session_id - valid? */ + unsigned int session_id_length; + unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH]; + /* this is used to determine whether the session is being reused in + * the appropriate context. It is up to the application to set this, + * via SSL_new */ + unsigned int sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + +#ifndef OPENSSL_NO_KRB5 + unsigned int krb5_client_princ_len; + unsigned char krb5_client_princ[SSL_MAX_KRB5_PRINCIPAL_LENGTH]; +#endif /* OPENSSL_NO_KRB5 */ +#ifndef OPENSSL_NO_PSK + char *psk_identity_hint; + char *psk_identity; +#endif + int not_resumable; + + /* The cert is the certificate used to establish this connection */ + struct sess_cert_st /* SESS_CERT */ *sess_cert; + + /* This is the cert for the other end. + * On clients, it will be the same as sess_cert->peer_key->x509 + * (the latter is not enough as sess_cert is not retained + * in the external representation of sessions, see ssl_asn1.c). */ + X509 *peer; + /* when app_verify_callback accepts a session where the peer's certificate + * is not ok, we must remember the error for session reuse: */ + long verify_result; /* only for servers */ + + int references; + long timeout; + long time; + + unsigned int compress_meth; /* Need to lookup the method */ + + const SSL_CIPHER *cipher; + unsigned long cipher_id; /* when ASN.1 loaded, this + * needs to be used to load + * the 'cipher' structure */ + + STACK_OF(SSL_CIPHER) *ciphers; /* shared ciphers? */ + + CRYPTO_EX_DATA ex_data; /* application specific data */ + + /* These are used to make removal of session-ids more + * efficient and to implement a maximum cache size. */ + struct ssl_session_st *prev,*next; +#ifndef OPENSSL_NO_TLSEXT + char *tlsext_hostname; +#ifndef OPENSSL_NO_EC + size_t tlsext_ecpointformatlist_length; + unsigned char *tlsext_ecpointformatlist; /* peer's list */ + size_t tlsext_ellipticcurvelist_length; + unsigned char *tlsext_ellipticcurvelist; /* peer's list */ +#endif /* OPENSSL_NO_EC */ + /* RFC4507 info */ + unsigned char *tlsext_tick; /* Session ticket */ + size_t tlsext_ticklen; /* Session ticket length */ + long tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */ +#endif + } SSL_SESSION; + + +#define SSL_OP_MICROSOFT_SESS_ID_BUG 0x00000001L +#define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x00000002L +/* Allow initial connection to servers that don't support RI */ +#define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L +#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L +#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x00000010L +#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L +#define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x00000040L /* no effect since 0.9.7h and 0.9.8b */ +#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0x00000080L +#define SSL_OP_TLS_D5_BUG 0x00000100L +#define SSL_OP_TLS_BLOCK_PADDING_BUG 0x00000200L + +/* Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added + * in OpenSSL 0.9.6d. Usually (depending on the application protocol) + * the workaround is not needed. Unfortunately some broken SSL/TLS + * implementations cannot handle it at all, which is why we include + * it in SSL_OP_ALL. */ +#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0x00000800L /* added in 0.9.6e */ + +/* SSL_OP_ALL: various bug workarounds that should be rather harmless. + * This used to be 0x000FFFFFL before 0.9.7. */ +#define SSL_OP_ALL 0x80000FFFL + +/* DTLS options */ +#define SSL_OP_NO_QUERY_MTU 0x00001000L +/* Turn on Cookie Exchange (on relevant for servers) */ +#define SSL_OP_COOKIE_EXCHANGE 0x00002000L +/* Don't use RFC4507 ticket extension */ +#define SSL_OP_NO_TICKET 0x00004000L +/* Use Cisco's "speshul" version of DTLS_BAD_VER (as client) */ +#define SSL_OP_CISCO_ANYCONNECT 0x00008000L + +/* As server, disallow session resumption on renegotiation */ +#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000L +/* Don't use compression even if supported */ +#define SSL_OP_NO_COMPRESSION 0x00020000L +/* Permit unsafe legacy renegotiation */ +#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000L +/* If set, always create a new key when using tmp_ecdh parameters */ +#define SSL_OP_SINGLE_ECDH_USE 0x00080000L +/* If set, always create a new key when using tmp_dh parameters */ +#define SSL_OP_SINGLE_DH_USE 0x00100000L +/* Set to always use the tmp_rsa key when doing RSA operations, + * even when this violates protocol specs */ +#define SSL_OP_EPHEMERAL_RSA 0x00200000L +/* Set on servers to choose the cipher according to the server's + * preferences */ +#define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L +/* If set, a server will allow a client to issue a SSLv3.0 version number + * as latest version supported in the premaster secret, even when TLSv1.0 + * (version 3.1) was announced in the client hello. Normally this is + * forbidden to prevent version rollback attacks. */ +#define SSL_OP_TLS_ROLLBACK_BUG 0x00800000L + +#define SSL_OP_NO_SSLv2 0x01000000L +#define SSL_OP_NO_SSLv3 0x02000000L +#define SSL_OP_NO_TLSv1 0x04000000L + +/* The next flag deliberately changes the ciphertest, this is a check + * for the PKCS#1 attack */ +#define SSL_OP_PKCS1_CHECK_1 0x08000000L +#define SSL_OP_PKCS1_CHECK_2 0x10000000L +#define SSL_OP_NETSCAPE_CA_DN_BUG 0x20000000L +#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x40000000L +/* Make server add server-hello extension from early version of + * cryptopro draft, when GOST ciphersuite is negotiated. + * Required for interoperability with CryptoPro CSP 3.x + */ +#define SSL_OP_CRYPTOPRO_TLSEXT_BUG 0x80000000L + +/* Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success + * when just a single record has been written): */ +#define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001L +/* Make it possible to retry SSL_write() with changed buffer location + * (buffer contents must stay the same!); this is not the default to avoid + * the misconception that non-blocking SSL_write() behaves like + * non-blocking write(): */ +#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L +/* Never bother the application with retries if the transport + * is blocking: */ +#define SSL_MODE_AUTO_RETRY 0x00000004L +/* Don't attempt to automatically build certificate chain */ +#define SSL_MODE_NO_AUTO_CHAIN 0x00000008L +/* Save RAM by releasing read and write buffers when they're empty. (SSL3 and + * TLS only.) "Released" buffers are put onto a free-list in the context + * or just freed (depending on the context's setting for freelist_max_len). */ +#define SSL_MODE_RELEASE_BUFFERS 0x00000010L + +/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, + * they cannot be used to clear bits. */ + +#define SSL_CTX_set_options(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL) +#define SSL_CTX_clear_options(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_OPTIONS,(op),NULL) +#define SSL_CTX_get_options(ctx) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,0,NULL) +#define SSL_set_options(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),NULL) +#define SSL_clear_options(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_OPTIONS,(op),NULL) +#define SSL_get_options(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_OPTIONS,0,NULL) + +#define SSL_CTX_set_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL) +#define SSL_CTX_clear_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL) +#define SSL_CTX_get_mode(ctx) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL) +#define SSL_clear_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL) +#define SSL_set_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL) +#define SSL_get_mode(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL) +#define SSL_set_mtu(ssl, mtu) \ + SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL) + +#define SSL_get_secure_renegotiation_support(ssl) \ + SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL) + +void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)); +void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)); +#define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) +#define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) + + + +#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32) +#define SSL_MAX_CERT_LIST_DEFAULT 1024*30 /* 30k max cert list :-) */ +#else +#define SSL_MAX_CERT_LIST_DEFAULT 1024*100 /* 100k max cert list :-) */ +#endif + +#define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024*20) + +/* This callback type is used inside SSL_CTX, SSL, and in the functions that set + * them. It is used to override the generation of SSL/TLS session IDs in a + * server. Return value should be zero on an error, non-zero to proceed. Also, + * callbacks should themselves check if the id they generate is unique otherwise + * the SSL handshake will fail with an error - callbacks can do this using the + * 'ssl' value they're passed by; + * SSL_has_matching_session_id(ssl, id, *id_len) + * The length value passed in is set at the maximum size the session ID can be. + * In SSLv2 this is 16 bytes, whereas SSLv3/TLSv1 it is 32 bytes. The callback + * can alter this length to be less if desired, but under SSLv2 session IDs are + * supposed to be fixed at 16 bytes so the id will be padded after the callback + * returns in this case. It is also an error for the callback to set the size to + * zero. */ +typedef int (*GEN_SESSION_CB)(const SSL *ssl, unsigned char *id, + unsigned int *id_len); + +typedef struct ssl_comp_st + { + int id; + const char *name; +#ifndef OPENSSL_NO_COMP + COMP_METHOD *method; +#else + char *method; +#endif + } SSL_COMP; + +DECLARE_STACK_OF(SSL_COMP) +DECLARE_LHASH_OF(SSL_SESSION); + +struct ssl_ctx_st + { + const SSL_METHOD *method; + + STACK_OF(SSL_CIPHER) *cipher_list; + /* same as above but sorted for lookup */ + STACK_OF(SSL_CIPHER) *cipher_list_by_id; + + struct x509_store_st /* X509_STORE */ *cert_store; + LHASH_OF(SSL_SESSION) *sessions; + /* Most session-ids that will be cached, default is + * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited. */ + unsigned long session_cache_size; + struct ssl_session_st *session_cache_head; + struct ssl_session_st *session_cache_tail; + + /* This can have one of 2 values, ored together, + * SSL_SESS_CACHE_CLIENT, + * SSL_SESS_CACHE_SERVER, + * Default is SSL_SESSION_CACHE_SERVER, which means only + * SSL_accept which cache SSL_SESSIONS. */ + int session_cache_mode; + + /* If timeout is not 0, it is the default timeout value set + * when SSL_new() is called. This has been put in to make + * life easier to set things up */ + long session_timeout; + + /* If this callback is not null, it will be called each + * time a session id is added to the cache. If this function + * returns 1, it means that the callback will do a + * SSL_SESSION_free() when it has finished using it. Otherwise, + * on 0, it means the callback has finished with it. + * If remove_session_cb is not null, it will be called when + * a session-id is removed from the cache. After the call, + * OpenSSL will SSL_SESSION_free() it. */ + int (*new_session_cb)(struct ssl_st *ssl,SSL_SESSION *sess); + void (*remove_session_cb)(struct ssl_ctx_st *ctx,SSL_SESSION *sess); + SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl, + unsigned char *data,int len,int *copy); + + struct + { + int sess_connect; /* SSL new conn - started */ + int sess_connect_renegotiate;/* SSL reneg - requested */ + int sess_connect_good; /* SSL new conne/reneg - finished */ + int sess_accept; /* SSL new accept - started */ + int sess_accept_renegotiate;/* SSL reneg - requested */ + int sess_accept_good; /* SSL accept/reneg - finished */ + int sess_miss; /* session lookup misses */ + int sess_timeout; /* reuse attempt on timeouted session */ + int sess_cache_full; /* session removed due to full cache */ + int sess_hit; /* session reuse actually done */ + int sess_cb_hit; /* session-id that was not + * in the cache was + * passed back via the callback. This + * indicates that the application is + * supplying session-id's from other + * processes - spooky :-) */ + } stats; + + int references; + + /* if defined, these override the X509_verify_cert() calls */ + int (*app_verify_callback)(X509_STORE_CTX *, void *); + void *app_verify_arg; + /* before OpenSSL 0.9.7, 'app_verify_arg' was ignored + * ('app_verify_callback' was called with just one argument) */ + + /* Default password callback. */ + pem_password_cb *default_passwd_callback; + + /* Default password callback user data. */ + void *default_passwd_callback_userdata; + + /* get client cert callback */ + int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey); + + /* cookie generate callback */ + int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, + unsigned int *cookie_len); + + /* verify cookie callback */ + int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, + unsigned int cookie_len); + + CRYPTO_EX_DATA ex_data; + + const EVP_MD *rsa_md5;/* For SSLv2 - name is 'ssl2-md5' */ + const EVP_MD *md5; /* For SSLv3/TLSv1 'ssl3-md5' */ + const EVP_MD *sha1; /* For SSLv3/TLSv1 'ssl3->sha1' */ + + STACK_OF(X509) *extra_certs; + STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSv1 */ + + + /* Default values used when no per-SSL value is defined follow */ + + void (*info_callback)(const SSL *ssl,int type,int val); /* used if SSL's info_callback is NULL */ + + /* what we put in client cert requests */ + STACK_OF(X509_NAME) *client_CA; + + + /* Default values to use in SSL structures follow (these are copied by SSL_new) */ + + unsigned long options; + unsigned long mode; + long max_cert_list; + + struct cert_st /* CERT */ *cert; + int read_ahead; + + /* callback that allows applications to peek at protocol messages */ + void (*msg_callback)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg); + void *msg_callback_arg; + + int verify_mode; + unsigned int sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + int (*default_verify_callback)(int ok,X509_STORE_CTX *ctx); /* called 'verify_callback' in the SSL */ + + /* Default generate session ID callback. */ + GEN_SESSION_CB generate_session_id; + + X509_VERIFY_PARAM *param; + +#if 0 + int purpose; /* Purpose setting */ + int trust; /* Trust setting */ +#endif + + int quiet_shutdown; + + /* Maximum amount of data to send in one fragment. + * actual record size can be more than this due to + * padding and MAC overheads. + */ + unsigned int max_send_fragment; + +#ifndef OPENSSL_ENGINE + /* Engine to pass requests for client certs to + */ + ENGINE *client_cert_engine; +#endif + +#ifndef OPENSSL_NO_TLSEXT + /* TLS extensions servername callback */ + int (*tlsext_servername_callback)(SSL*, int *, void *); + void *tlsext_servername_arg; + /* RFC 4507 session ticket keys */ + unsigned char tlsext_tick_key_name[16]; + unsigned char tlsext_tick_hmac_key[16]; + unsigned char tlsext_tick_aes_key[16]; + /* Callback to support customisation of ticket key setting */ + int (*tlsext_ticket_key_cb)(SSL *ssl, + unsigned char *name, unsigned char *iv, + EVP_CIPHER_CTX *ectx, + HMAC_CTX *hctx, int enc); + + /* certificate status request info */ + /* Callback for status request */ + int (*tlsext_status_cb)(SSL *ssl, void *arg); + void *tlsext_status_arg; + + /* draft-rescorla-tls-opaque-prf-input-00.txt information */ + int (*tlsext_opaque_prf_input_callback)(SSL *, void *peerinput, size_t len, void *arg); + void *tlsext_opaque_prf_input_callback_arg; +#endif + +#ifndef OPENSSL_NO_PSK + char *psk_identity_hint; + unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, char *identity, + unsigned int max_identity_len, unsigned char *psk, + unsigned int max_psk_len); + unsigned int (*psk_server_callback)(SSL *ssl, const char *identity, + unsigned char *psk, unsigned int max_psk_len); +#endif + +#ifndef OPENSSL_NO_BUF_FREELISTS +#define SSL_MAX_BUF_FREELIST_LEN_DEFAULT 32 + unsigned int freelist_max_len; + struct ssl3_buf_freelist_st *wbuf_freelist; + struct ssl3_buf_freelist_st *rbuf_freelist; +#endif + }; + +#define SSL_SESS_CACHE_OFF 0x0000 +#define SSL_SESS_CACHE_CLIENT 0x0001 +#define SSL_SESS_CACHE_SERVER 0x0002 +#define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER) +#define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080 +/* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */ +#define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100 +#define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200 +#define SSL_SESS_CACHE_NO_INTERNAL \ + (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE) + +LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx); +#define SSL_CTX_sess_number(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL) +#define SSL_CTX_sess_connect(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT,0,NULL) +#define SSL_CTX_sess_connect_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_GOOD,0,NULL) +#define SSL_CTX_sess_connect_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_RENEGOTIATE,0,NULL) +#define SSL_CTX_sess_accept(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT,0,NULL) +#define SSL_CTX_sess_accept_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_RENEGOTIATE,0,NULL) +#define SSL_CTX_sess_accept_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_GOOD,0,NULL) +#define SSL_CTX_sess_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_HIT,0,NULL) +#define SSL_CTX_sess_cb_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CB_HIT,0,NULL) +#define SSL_CTX_sess_misses(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_MISSES,0,NULL) +#define SSL_CTX_sess_timeouts(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL) +#define SSL_CTX_sess_cache_full(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL) + +void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, int (*new_session_cb)(struct ssl_st *ssl,SSL_SESSION *sess)); +int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(struct ssl_st *ssl, SSL_SESSION *sess); +void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, void (*remove_session_cb)(struct ssl_ctx_st *ctx,SSL_SESSION *sess)); +void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(struct ssl_ctx_st *ctx, SSL_SESSION *sess); +void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl, unsigned char *data,int len,int *copy)); +SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(struct ssl_st *ssl, unsigned char *Data, int len, int *copy); +void SSL_CTX_set_info_callback(SSL_CTX *ctx, void (*cb)(const SSL *ssl,int type,int val)); +void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,int type,int val); +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey)); +int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl, X509 **x509, EVP_PKEY **pkey); +#ifndef OPENSSL_NO_ENGINE +int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e); +#endif +void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)); +void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, unsigned int cookie_len)); + +#ifndef OPENSSL_NO_PSK +/* the maximum length of the buffer given to callbacks containing the + * resulting identity/psk */ +#define PSK_MAX_IDENTITY_LEN 128 +#define PSK_MAX_PSK_LEN 256 +void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, + unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, + char *identity, unsigned int max_identity_len, unsigned char *psk, + unsigned int max_psk_len)); +void SSL_set_psk_client_callback(SSL *ssl, + unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, + char *identity, unsigned int max_identity_len, unsigned char *psk, + unsigned int max_psk_len)); +void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, + unsigned int (*psk_server_callback)(SSL *ssl, const char *identity, + unsigned char *psk, unsigned int max_psk_len)); +void SSL_set_psk_server_callback(SSL *ssl, + unsigned int (*psk_server_callback)(SSL *ssl, const char *identity, + unsigned char *psk, unsigned int max_psk_len)); +int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint); +int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint); +const char *SSL_get_psk_identity_hint(const SSL *s); +const char *SSL_get_psk_identity(const SSL *s); +#endif + +#define SSL_NOTHING 1 +#define SSL_WRITING 2 +#define SSL_READING 3 +#define SSL_X509_LOOKUP 4 + +/* These will only be used when doing non-blocking IO */ +#define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING) +#define SSL_want_read(s) (SSL_want(s) == SSL_READING) +#define SSL_want_write(s) (SSL_want(s) == SSL_WRITING) +#define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP) + +#define SSL_MAC_FLAG_READ_MAC_STREAM 1 +#define SSL_MAC_FLAG_WRITE_MAC_STREAM 2 + +struct ssl_st + { + /* protocol version + * (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION, DTLS1_VERSION) + */ + int version; + int type; /* SSL_ST_CONNECT or SSL_ST_ACCEPT */ + + const SSL_METHOD *method; /* SSLv3 */ + + /* There are 2 BIO's even though they are normally both the + * same. This is so data can be read and written to different + * handlers */ + +#ifndef OPENSSL_NO_BIO + BIO *rbio; /* used by SSL_read */ + BIO *wbio; /* used by SSL_write */ + BIO *bbio; /* used during session-id reuse to concatenate + * messages */ +#else + char *rbio; /* used by SSL_read */ + char *wbio; /* used by SSL_write */ + char *bbio; +#endif + /* This holds a variable that indicates what we were doing + * when a 0 or -1 is returned. This is needed for + * non-blocking IO so we know what request needs re-doing when + * in SSL_accept or SSL_connect */ + int rwstate; + + /* true when we are actually in SSL_accept() or SSL_connect() */ + int in_handshake; + int (*handshake_func)(SSL *); + + /* Imagine that here's a boolean member "init" that is + * switched as soon as SSL_set_{accept/connect}_state + * is called for the first time, so that "state" and + * "handshake_func" are properly initialized. But as + * handshake_func is == 0 until then, we use this + * test instead of an "init" member. + */ + + int server; /* are we the server side? - mostly used by SSL_clear*/ + + int new_session;/* 1 if we are to use a new session. + * 2 if we are a server and are inside a handshake + * (i.e. not just sending a HelloRequest) + * NB: For servers, the 'new' session may actually be a previously + * cached session or even the previous session unless + * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */ + int quiet_shutdown;/* don't send shutdown packets */ + int shutdown; /* we have shut things down, 0x01 sent, 0x02 + * for received */ + int state; /* where we are */ + int rstate; /* where we are when reading */ + + BUF_MEM *init_buf; /* buffer used during init */ + void *init_msg; /* pointer to handshake message body, set by ssl3_get_message() */ + int init_num; /* amount read/written */ + int init_off; /* amount read/written */ + + /* used internally to point at a raw packet */ + unsigned char *packet; + unsigned int packet_length; + + struct ssl2_state_st *s2; /* SSLv2 variables */ + struct ssl3_state_st *s3; /* SSLv3 variables */ + struct dtls1_state_st *d1; /* DTLSv1 variables */ + + int read_ahead; /* Read as many input bytes as possible + * (for non-blocking reads) */ + + /* callback that allows applications to peek at protocol messages */ + void (*msg_callback)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg); + void *msg_callback_arg; + + int hit; /* reusing a previous session */ + + X509_VERIFY_PARAM *param; + +#if 0 + int purpose; /* Purpose setting */ + int trust; /* Trust setting */ +#endif + + /* crypto */ + STACK_OF(SSL_CIPHER) *cipher_list; + STACK_OF(SSL_CIPHER) *cipher_list_by_id; + + /* These are the ones being used, the ones in SSL_SESSION are + * the ones to be 'copied' into these ones */ + int mac_flags; + EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */ + EVP_MD_CTX *read_hash; /* used for mac generation */ +#ifndef OPENSSL_NO_COMP + COMP_CTX *expand; /* uncompress */ +#else + char *expand; +#endif + + EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ + EVP_MD_CTX *write_hash; /* used for mac generation */ +#ifndef OPENSSL_NO_COMP + COMP_CTX *compress; /* compression */ +#else + char *compress; +#endif + + /* session info */ + + /* client cert? */ + /* This is used to hold the server certificate used */ + struct cert_st /* CERT */ *cert; + + /* the session_id_context is used to ensure sessions are only reused + * in the appropriate context */ + unsigned int sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + + /* This can also be in the session once a session is established */ + SSL_SESSION *session; + + /* Default generate session ID callback. */ + GEN_SESSION_CB generate_session_id; + + /* Used in SSL2 and SSL3 */ + int verify_mode; /* 0 don't care about verify failure. + * 1 fail if verify fails */ + int (*verify_callback)(int ok,X509_STORE_CTX *ctx); /* fail if callback returns 0 */ + + void (*info_callback)(const SSL *ssl,int type,int val); /* optional informational callback */ + + int error; /* error bytes to be written */ + int error_code; /* actual code */ + +#ifndef OPENSSL_NO_KRB5 + KSSL_CTX *kssl_ctx; /* Kerberos 5 context */ +#endif /* OPENSSL_NO_KRB5 */ + +#ifndef OPENSSL_NO_PSK + unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, char *identity, + unsigned int max_identity_len, unsigned char *psk, + unsigned int max_psk_len); + unsigned int (*psk_server_callback)(SSL *ssl, const char *identity, + unsigned char *psk, unsigned int max_psk_len); +#endif + + SSL_CTX *ctx; + /* set this flag to 1 and a sleep(1) is put into all SSL_read() + * and SSL_write() calls, good for nbio debuging :-) */ + int debug; + + /* extra application data */ + long verify_result; + CRYPTO_EX_DATA ex_data; + + /* for server side, keep the list of CA_dn we can use */ + STACK_OF(X509_NAME) *client_CA; + + int references; + unsigned long options; /* protocol behaviour */ + unsigned long mode; /* API behaviour */ + long max_cert_list; + int first_packet; + int client_version; /* what was passed, used for + * SSLv3/TLS rollback check */ + unsigned int max_send_fragment; +#ifndef OPENSSL_NO_TLSEXT + /* TLS extension debug callback */ + void (*tlsext_debug_cb)(SSL *s, int client_server, int type, + unsigned char *data, int len, + void *arg); + void *tlsext_debug_arg; + char *tlsext_hostname; + int servername_done; /* no further mod of servername + 0 : call the servername extension callback. + 1 : prepare 2, allow last ack just after in server callback. + 2 : don't call servername callback, no ack in server hello + */ + /* certificate status request info */ + /* Status type or -1 if no status type */ + int tlsext_status_type; + /* Expect OCSP CertificateStatus message */ + int tlsext_status_expected; + /* OCSP status request only */ + STACK_OF(OCSP_RESPID) *tlsext_ocsp_ids; + X509_EXTENSIONS *tlsext_ocsp_exts; + /* OCSP response received or to be sent */ + unsigned char *tlsext_ocsp_resp; + int tlsext_ocsp_resplen; + + /* RFC4507 session ticket expected to be received or sent */ + int tlsext_ticket_expected; +#ifndef OPENSSL_NO_EC + size_t tlsext_ecpointformatlist_length; + unsigned char *tlsext_ecpointformatlist; /* our list */ + size_t tlsext_ellipticcurvelist_length; + unsigned char *tlsext_ellipticcurvelist; /* our list */ +#endif /* OPENSSL_NO_EC */ + + /* draft-rescorla-tls-opaque-prf-input-00.txt information to be used for handshakes */ + void *tlsext_opaque_prf_input; + size_t tlsext_opaque_prf_input_len; + + /* TLS Session Ticket extension override */ + TLS_SESSION_TICKET_EXT *tlsext_session_ticket; + + /* TLS Session Ticket extension callback */ + tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb; + void *tls_session_ticket_ext_cb_arg; + + /* TLS pre-shared secret session resumption */ + tls_session_secret_cb_fn tls_session_secret_cb; + void *tls_session_secret_cb_arg; + + SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */ +#define session_ctx initial_ctx +#else +#define session_ctx ctx +#endif /* OPENSSL_NO_TLSEXT */ + }; + +#ifdef __cplusplus +} +#endif + +#include +#include +#include /* This is mostly sslv3 with a few tweaks */ +#include /* Datagram TLS */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* compatibility */ +#define SSL_set_app_data(s,arg) (SSL_set_ex_data(s,0,(char *)arg)) +#define SSL_get_app_data(s) (SSL_get_ex_data(s,0)) +#define SSL_SESSION_set_app_data(s,a) (SSL_SESSION_set_ex_data(s,0,(char *)a)) +#define SSL_SESSION_get_app_data(s) (SSL_SESSION_get_ex_data(s,0)) +#define SSL_CTX_get_app_data(ctx) (SSL_CTX_get_ex_data(ctx,0)) +#define SSL_CTX_set_app_data(ctx,arg) (SSL_CTX_set_ex_data(ctx,0,(char *)arg)) + +/* The following are the possible values for ssl->state are are + * used to indicate where we are up to in the SSL connection establishment. + * The macros that follow are about the only things you should need to use + * and even then, only when using non-blocking IO. + * It can also be useful to work out where you were when the connection + * failed */ + +#define SSL_ST_CONNECT 0x1000 +#define SSL_ST_ACCEPT 0x2000 +#define SSL_ST_MASK 0x0FFF +#define SSL_ST_INIT (SSL_ST_CONNECT|SSL_ST_ACCEPT) +#define SSL_ST_BEFORE 0x4000 +#define SSL_ST_OK 0x03 +#define SSL_ST_RENEGOTIATE (0x04|SSL_ST_INIT) + +#define SSL_CB_LOOP 0x01 +#define SSL_CB_EXIT 0x02 +#define SSL_CB_READ 0x04 +#define SSL_CB_WRITE 0x08 +#define SSL_CB_ALERT 0x4000 /* used in callback */ +#define SSL_CB_READ_ALERT (SSL_CB_ALERT|SSL_CB_READ) +#define SSL_CB_WRITE_ALERT (SSL_CB_ALERT|SSL_CB_WRITE) +#define SSL_CB_ACCEPT_LOOP (SSL_ST_ACCEPT|SSL_CB_LOOP) +#define SSL_CB_ACCEPT_EXIT (SSL_ST_ACCEPT|SSL_CB_EXIT) +#define SSL_CB_CONNECT_LOOP (SSL_ST_CONNECT|SSL_CB_LOOP) +#define SSL_CB_CONNECT_EXIT (SSL_ST_CONNECT|SSL_CB_EXIT) +#define SSL_CB_HANDSHAKE_START 0x10 +#define SSL_CB_HANDSHAKE_DONE 0x20 + +/* Is the SSL_connection established? */ +#define SSL_get_state(a) SSL_state(a) +#define SSL_is_init_finished(a) (SSL_state(a) == SSL_ST_OK) +#define SSL_in_init(a) (SSL_state(a)&SSL_ST_INIT) +#define SSL_in_before(a) (SSL_state(a)&SSL_ST_BEFORE) +#define SSL_in_connect_init(a) (SSL_state(a)&SSL_ST_CONNECT) +#define SSL_in_accept_init(a) (SSL_state(a)&SSL_ST_ACCEPT) + +/* The following 2 states are kept in ssl->rstate when reads fail, + * you should not need these */ +#define SSL_ST_READ_HEADER 0xF0 +#define SSL_ST_READ_BODY 0xF1 +#define SSL_ST_READ_DONE 0xF2 + +/* Obtain latest Finished message + * -- that we sent (SSL_get_finished) + * -- that we expected from peer (SSL_get_peer_finished). + * Returns length (0 == no Finished so far), copies up to 'count' bytes. */ +size_t SSL_get_finished(const SSL *s, void *buf, size_t count); +size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count); + +/* use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 2 options + * are 'ored' with SSL_VERIFY_PEER if they are desired */ +#define SSL_VERIFY_NONE 0x00 +#define SSL_VERIFY_PEER 0x01 +#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 +#define SSL_VERIFY_CLIENT_ONCE 0x04 + +#define OpenSSL_add_ssl_algorithms() SSL_library_init() +#define SSLeay_add_ssl_algorithms() SSL_library_init() + +/* this is for backward compatibility */ +#if 0 /* NEW_SSLEAY */ +#define SSL_CTX_set_default_verify(a,b,c) SSL_CTX_set_verify(a,b,c) +#define SSL_set_pref_cipher(c,n) SSL_set_cipher_list(c,n) +#define SSL_add_session(a,b) SSL_CTX_add_session((a),(b)) +#define SSL_remove_session(a,b) SSL_CTX_remove_session((a),(b)) +#define SSL_flush_sessions(a,b) SSL_CTX_flush_sessions((a),(b)) +#endif +/* More backward compatibility */ +#define SSL_get_cipher(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +#define SSL_get_cipher_bits(s,np) \ + SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np) +#define SSL_get_cipher_version(s) \ + SSL_CIPHER_get_version(SSL_get_current_cipher(s)) +#define SSL_get_cipher_name(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +#define SSL_get_time(a) SSL_SESSION_get_time(a) +#define SSL_set_time(a,b) SSL_SESSION_set_time((a),(b)) +#define SSL_get_timeout(a) SSL_SESSION_get_timeout(a) +#define SSL_set_timeout(a,b) SSL_SESSION_set_timeout((a),(b)) + +#define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id) +#define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id) + +DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) + +#define SSL_AD_REASON_OFFSET 1000 /* offset to get SSL_R_... value from SSL_AD_... */ + +/* These alert types are for SSLv3 and TLSv1 */ +#define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY +#define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE /* fatal */ +#define SSL_AD_BAD_RECORD_MAC SSL3_AD_BAD_RECORD_MAC /* fatal */ +#define SSL_AD_DECRYPTION_FAILED TLS1_AD_DECRYPTION_FAILED +#define SSL_AD_RECORD_OVERFLOW TLS1_AD_RECORD_OVERFLOW +#define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE/* fatal */ +#define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE/* fatal */ +#define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE /* Not for TLS */ +#define SSL_AD_BAD_CERTIFICATE SSL3_AD_BAD_CERTIFICATE +#define SSL_AD_UNSUPPORTED_CERTIFICATE SSL3_AD_UNSUPPORTED_CERTIFICATE +#define SSL_AD_CERTIFICATE_REVOKED SSL3_AD_CERTIFICATE_REVOKED +#define SSL_AD_CERTIFICATE_EXPIRED SSL3_AD_CERTIFICATE_EXPIRED +#define SSL_AD_CERTIFICATE_UNKNOWN SSL3_AD_CERTIFICATE_UNKNOWN +#define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER /* fatal */ +#define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA /* fatal */ +#define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED /* fatal */ +#define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR /* fatal */ +#define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR +#define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION/* fatal */ +#define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION /* fatal */ +#define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY/* fatal */ +#define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR /* fatal */ +#define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED +#define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION +#define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION +#define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE +#define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME +#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE +#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE +#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */ + +#define SSL_ERROR_NONE 0 +#define SSL_ERROR_SSL 1 +#define SSL_ERROR_WANT_READ 2 +#define SSL_ERROR_WANT_WRITE 3 +#define SSL_ERROR_WANT_X509_LOOKUP 4 +#define SSL_ERROR_SYSCALL 5 /* look at error stack/return value/errno */ +#define SSL_ERROR_ZERO_RETURN 6 +#define SSL_ERROR_WANT_CONNECT 7 +#define SSL_ERROR_WANT_ACCEPT 8 + +#define SSL_CTRL_NEED_TMP_RSA 1 +#define SSL_CTRL_SET_TMP_RSA 2 +#define SSL_CTRL_SET_TMP_DH 3 +#define SSL_CTRL_SET_TMP_ECDH 4 +#define SSL_CTRL_SET_TMP_RSA_CB 5 +#define SSL_CTRL_SET_TMP_DH_CB 6 +#define SSL_CTRL_SET_TMP_ECDH_CB 7 + +#define SSL_CTRL_GET_SESSION_REUSED 8 +#define SSL_CTRL_GET_CLIENT_CERT_REQUEST 9 +#define SSL_CTRL_GET_NUM_RENEGOTIATIONS 10 +#define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS 11 +#define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS 12 +#define SSL_CTRL_GET_FLAGS 13 +#define SSL_CTRL_EXTRA_CHAIN_CERT 14 + +#define SSL_CTRL_SET_MSG_CALLBACK 15 +#define SSL_CTRL_SET_MSG_CALLBACK_ARG 16 + +/* only applies to datagram connections */ +#define SSL_CTRL_SET_MTU 17 +/* Stats */ +#define SSL_CTRL_SESS_NUMBER 20 +#define SSL_CTRL_SESS_CONNECT 21 +#define SSL_CTRL_SESS_CONNECT_GOOD 22 +#define SSL_CTRL_SESS_CONNECT_RENEGOTIATE 23 +#define SSL_CTRL_SESS_ACCEPT 24 +#define SSL_CTRL_SESS_ACCEPT_GOOD 25 +#define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE 26 +#define SSL_CTRL_SESS_HIT 27 +#define SSL_CTRL_SESS_CB_HIT 28 +#define SSL_CTRL_SESS_MISSES 29 +#define SSL_CTRL_SESS_TIMEOUTS 30 +#define SSL_CTRL_SESS_CACHE_FULL 31 +#define SSL_CTRL_OPTIONS 32 +#define SSL_CTRL_MODE 33 + +#define SSL_CTRL_GET_READ_AHEAD 40 +#define SSL_CTRL_SET_READ_AHEAD 41 +#define SSL_CTRL_SET_SESS_CACHE_SIZE 42 +#define SSL_CTRL_GET_SESS_CACHE_SIZE 43 +#define SSL_CTRL_SET_SESS_CACHE_MODE 44 +#define SSL_CTRL_GET_SESS_CACHE_MODE 45 + +#define SSL_CTRL_GET_MAX_CERT_LIST 50 +#define SSL_CTRL_SET_MAX_CERT_LIST 51 + +#define SSL_CTRL_SET_MAX_SEND_FRAGMENT 52 + +/* see tls1.h for macros based on these */ +#ifndef OPENSSL_NO_TLSEXT +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 53 +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54 +#define SSL_CTRL_SET_TLSEXT_HOSTNAME 55 +#define SSL_CTRL_SET_TLSEXT_DEBUG_CB 56 +#define SSL_CTRL_SET_TLSEXT_DEBUG_ARG 57 +#define SSL_CTRL_GET_TLSEXT_TICKET_KEYS 58 +#define SSL_CTRL_SET_TLSEXT_TICKET_KEYS 59 +#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT 60 +#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB 61 +#define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG 62 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB 63 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG 64 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE 65 +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS 66 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS 67 +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS 68 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS 69 +#define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP 70 +#define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71 + +#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72 +#endif + +#define DTLS_CTRL_GET_TIMEOUT 73 +#define DTLS_CTRL_HANDLE_TIMEOUT 74 +#define DTLS_CTRL_LISTEN 75 + +#define SSL_CTRL_GET_RI_SUPPORT 76 +#define SSL_CTRL_CLEAR_OPTIONS 77 +#define SSL_CTRL_CLEAR_MODE 78 + +#define DTLSv1_get_timeout(ssl, arg) \ + SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg) +#define DTLSv1_handle_timeout(ssl) \ + SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL) +#define DTLSv1_listen(ssl, peer) \ + SSL_ctrl(ssl,DTLS_CTRL_LISTEN,0, (void *)peer) + +#define SSL_session_reused(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL) +#define SSL_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL) +#define SSL_clear_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL) +#define SSL_total_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL) + +#define SSL_CTX_need_tmp_RSA(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_NEED_TMP_RSA,0,NULL) +#define SSL_CTX_set_tmp_rsa(ctx,rsa) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa) +#define SSL_CTX_set_tmp_dh(ctx,dh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)dh) +#define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) + +#define SSL_need_tmp_RSA(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_NEED_TMP_RSA,0,NULL) +#define SSL_set_tmp_rsa(ssl,rsa) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa) +#define SSL_set_tmp_dh(ssl,dh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)dh) +#define SSL_set_tmp_ecdh(ssl,ecdh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) + +#define SSL_CTX_add_extra_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509) + +#ifndef OPENSSL_NO_BIO +BIO_METHOD *BIO_f_ssl(void); +BIO *BIO_new_ssl(SSL_CTX *ctx,int client); +BIO *BIO_new_ssl_connect(SSL_CTX *ctx); +BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx); +int BIO_ssl_copy_session_id(BIO *to,BIO *from); +void BIO_ssl_shutdown(BIO *ssl_bio); + +#endif + +int SSL_CTX_set_cipher_list(SSL_CTX *,const char *str); +SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth); +void SSL_CTX_free(SSL_CTX *); +long SSL_CTX_set_timeout(SSL_CTX *ctx,long t); +long SSL_CTX_get_timeout(const SSL_CTX *ctx); +X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *); +void SSL_CTX_set_cert_store(SSL_CTX *,X509_STORE *); +int SSL_want(const SSL *s); +int SSL_clear(SSL *s); + +void SSL_CTX_flush_sessions(SSL_CTX *ctx,long tm); + +const SSL_CIPHER *SSL_get_current_cipher(const SSL *s); +int SSL_CIPHER_get_bits(const SSL_CIPHER *c,int *alg_bits); +char * SSL_CIPHER_get_version(const SSL_CIPHER *c); +const char * SSL_CIPHER_get_name(const SSL_CIPHER *c); + +int SSL_get_fd(const SSL *s); +int SSL_get_rfd(const SSL *s); +int SSL_get_wfd(const SSL *s); +const char * SSL_get_cipher_list(const SSL *s,int n); +char * SSL_get_shared_ciphers(const SSL *s, char *buf, int len); +int SSL_get_read_ahead(const SSL * s); +int SSL_pending(const SSL *s); +#ifndef OPENSSL_NO_SOCK +int SSL_set_fd(SSL *s, int fd); +int SSL_set_rfd(SSL *s, int fd); +int SSL_set_wfd(SSL *s, int fd); +#endif +#ifndef OPENSSL_NO_BIO +void SSL_set_bio(SSL *s, BIO *rbio,BIO *wbio); +BIO * SSL_get_rbio(const SSL *s); +BIO * SSL_get_wbio(const SSL *s); +#endif +int SSL_set_cipher_list(SSL *s, const char *str); +void SSL_set_read_ahead(SSL *s, int yes); +int SSL_get_verify_mode(const SSL *s); +int SSL_get_verify_depth(const SSL *s); +int (*SSL_get_verify_callback(const SSL *s))(int,X509_STORE_CTX *); +void SSL_set_verify(SSL *s, int mode, + int (*callback)(int ok,X509_STORE_CTX *ctx)); +void SSL_set_verify_depth(SSL *s, int depth); +#ifndef OPENSSL_NO_RSA +int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa); +#endif +int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len); +int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey); +int SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, const unsigned char *d, long len); +int SSL_use_certificate(SSL *ssl, X509 *x); +int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len); + +#ifndef OPENSSL_NO_STDIO +int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type); +int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type); +int SSL_use_certificate_file(SSL *ssl, const char *file, int type); +int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type); +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type); +int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type); +int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); /* PEM type */ +STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file); +int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *file); +#ifndef OPENSSL_SYS_VMS +#ifndef OPENSSL_SYS_MACINTOSH_CLASSIC /* XXXXX: Better scheme needed! [was: #ifndef MAC_OS_pre_X] */ +int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *dir); +#endif +#endif + +#endif + +void SSL_load_error_strings(void ); +const char *SSL_state_string(const SSL *s); +const char *SSL_rstate_string(const SSL *s); +const char *SSL_state_string_long(const SSL *s); +const char *SSL_rstate_string_long(const SSL *s); +long SSL_SESSION_get_time(const SSL_SESSION *s); +long SSL_SESSION_set_time(SSL_SESSION *s, long t); +long SSL_SESSION_get_timeout(const SSL_SESSION *s); +long SSL_SESSION_set_timeout(SSL_SESSION *s, long t); +void SSL_copy_session_id(SSL *to,const SSL *from); + +SSL_SESSION *SSL_SESSION_new(void); +const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, + unsigned int *len); +#ifndef OPENSSL_NO_FP_API +int SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses); +#endif +#ifndef OPENSSL_NO_BIO +int SSL_SESSION_print(BIO *fp,const SSL_SESSION *ses); +#endif +void SSL_SESSION_free(SSL_SESSION *ses); +int i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp); +int SSL_set_session(SSL *to, SSL_SESSION *session); +int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c); +int SSL_CTX_remove_session(SSL_CTX *,SSL_SESSION *c); +int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB); +int SSL_set_generate_session_id(SSL *, GEN_SESSION_CB); +int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, + unsigned int id_len); +SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a,const unsigned char **pp, + long length); + +#ifdef HEADER_X509_H +X509 * SSL_get_peer_certificate(const SSL *s); +#endif + +STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s); + +int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); +int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); +int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int,X509_STORE_CTX *); +void SSL_CTX_set_verify(SSL_CTX *ctx,int mode, + int (*callback)(int, X509_STORE_CTX *)); +void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth); +void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *,void *), void *arg); +#ifndef OPENSSL_NO_RSA +int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); +#endif +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len); +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); +int SSL_CTX_use_PrivateKey_ASN1(int pk,SSL_CTX *ctx, + const unsigned char *d, long len); +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d); + +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb); +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u); + +int SSL_CTX_check_private_key(const SSL_CTX *ctx); +int SSL_check_private_key(const SSL *ctx); + +int SSL_CTX_set_session_id_context(SSL_CTX *ctx,const unsigned char *sid_ctx, + unsigned int sid_ctx_len); + +SSL * SSL_new(SSL_CTX *ctx); +int SSL_set_session_id_context(SSL *ssl,const unsigned char *sid_ctx, + unsigned int sid_ctx_len); + +int SSL_CTX_set_purpose(SSL_CTX *s, int purpose); +int SSL_set_purpose(SSL *s, int purpose); +int SSL_CTX_set_trust(SSL_CTX *s, int trust); +int SSL_set_trust(SSL *s, int trust); + +int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm); +int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm); + +void SSL_free(SSL *ssl); +int SSL_accept(SSL *ssl); +int SSL_connect(SSL *ssl); +int SSL_read(SSL *ssl,void *buf,int num); +int SSL_peek(SSL *ssl,void *buf,int num); +int SSL_write(SSL *ssl,const void *buf,int num); +long SSL_ctrl(SSL *ssl,int cmd, long larg, void *parg); +long SSL_callback_ctrl(SSL *, int, void (*)(void)); +long SSL_CTX_ctrl(SSL_CTX *ctx,int cmd, long larg, void *parg); +long SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void)); + +int SSL_get_error(const SSL *s,int ret_code); +const char *SSL_get_version(const SSL *s); + +/* This sets the 'default' SSL version that SSL_new() will create */ +int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); + +#ifndef OPENSSL_NO_SSL2 +const SSL_METHOD *SSLv2_method(void); /* SSLv2 */ +const SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */ +const SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */ +#endif + +const SSL_METHOD *SSLv3_method(void); /* SSLv3 */ +const SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */ +const SSL_METHOD *SSLv3_client_method(void); /* SSLv3 */ + +const SSL_METHOD *SSLv23_method(void); /* SSLv3 but can rollback to v2 */ +const SSL_METHOD *SSLv23_server_method(void); /* SSLv3 but can rollback to v2 */ +const SSL_METHOD *SSLv23_client_method(void); /* SSLv3 but can rollback to v2 */ + +const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */ +const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */ +const SSL_METHOD *TLSv1_client_method(void); /* TLSv1.0 */ + +const SSL_METHOD *DTLSv1_method(void); /* DTLSv1.0 */ +const SSL_METHOD *DTLSv1_server_method(void); /* DTLSv1.0 */ +const SSL_METHOD *DTLSv1_client_method(void); /* DTLSv1.0 */ + +STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s); + +int SSL_do_handshake(SSL *s); +int SSL_renegotiate(SSL *s); +int SSL_renegotiate_pending(SSL *s); +int SSL_shutdown(SSL *s); + +const SSL_METHOD *SSL_get_ssl_method(SSL *s); +int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method); +const char *SSL_alert_type_string_long(int value); +const char *SSL_alert_type_string(int value); +const char *SSL_alert_desc_string_long(int value); +const char *SSL_alert_desc_string(int value); + +void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list); +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); +STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s); +STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s); +int SSL_add_client_CA(SSL *ssl,X509 *x); +int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x); + +void SSL_set_connect_state(SSL *s); +void SSL_set_accept_state(SSL *s); + +long SSL_get_default_timeout(const SSL *s); + +int SSL_library_init(void ); + +char *SSL_CIPHER_description(const SSL_CIPHER *,char *buf,int size); +STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk); + +SSL *SSL_dup(SSL *ssl); + +X509 *SSL_get_certificate(const SSL *ssl); +/* EVP_PKEY */ struct evp_pkey_st *SSL_get_privatekey(SSL *ssl); + +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx,int mode); +int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); +void SSL_set_quiet_shutdown(SSL *ssl,int mode); +int SSL_get_quiet_shutdown(const SSL *ssl); +void SSL_set_shutdown(SSL *ssl,int mode); +int SSL_get_shutdown(const SSL *ssl); +int SSL_version(const SSL *ssl); +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, + const char *CApath); +#define SSL_get0_session SSL_get_session /* just peek at pointer */ +SSL_SESSION *SSL_get_session(const SSL *ssl); +SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */ +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX* ctx); +void SSL_set_info_callback(SSL *ssl, + void (*cb)(const SSL *ssl,int type,int val)); +void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl,int type,int val); +int SSL_state(const SSL *ssl); + +void SSL_set_verify_result(SSL *ssl,long v); +long SSL_get_verify_result(const SSL *ssl); + +int SSL_set_ex_data(SSL *ssl,int idx,void *data); +void *SSL_get_ex_data(const SSL *ssl,int idx); +int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); + +int SSL_SESSION_set_ex_data(SSL_SESSION *ss,int idx,void *data); +void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss,int idx); +int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); + +int SSL_CTX_set_ex_data(SSL_CTX *ssl,int idx,void *data); +void *SSL_CTX_get_ex_data(const SSL_CTX *ssl,int idx); +int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); + +int SSL_get_ex_data_X509_STORE_CTX_idx(void ); + +#define SSL_CTX_sess_set_cache_size(ctx,t) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL) +#define SSL_CTX_sess_get_cache_size(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL) +#define SSL_CTX_set_session_cache_mode(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL) +#define SSL_CTX_get_session_cache_mode(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL) + +#define SSL_CTX_get_default_read_ahead(ctx) SSL_CTX_get_read_ahead(ctx) +#define SSL_CTX_set_default_read_ahead(ctx,m) SSL_CTX_set_read_ahead(ctx,m) +#define SSL_CTX_get_read_ahead(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL) +#define SSL_CTX_set_read_ahead(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL) +#define SSL_CTX_get_max_cert_list(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +#define SSL_CTX_set_max_cert_list(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) +#define SSL_get_max_cert_list(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +#define SSL_set_max_cert_list(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) + +#define SSL_CTX_set_max_send_fragment(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) +#define SSL_set_max_send_fragment(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) + + /* NB: the keylength is only applicable when is_export is true */ +#ifndef OPENSSL_NO_RSA +void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx, + RSA *(*cb)(SSL *ssl,int is_export, + int keylength)); + +void SSL_set_tmp_rsa_callback(SSL *ssl, + RSA *(*cb)(SSL *ssl,int is_export, + int keylength)); +#endif +#ifndef OPENSSL_NO_DH +void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, + DH *(*dh)(SSL *ssl,int is_export, + int keylength)); +void SSL_set_tmp_dh_callback(SSL *ssl, + DH *(*dh)(SSL *ssl,int is_export, + int keylength)); +#endif +#ifndef OPENSSL_NO_ECDH +void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx, + EC_KEY *(*ecdh)(SSL *ssl,int is_export, + int keylength)); +void SSL_set_tmp_ecdh_callback(SSL *ssl, + EC_KEY *(*ecdh)(SSL *ssl,int is_export, + int keylength)); +#endif + +#ifndef OPENSSL_NO_COMP +const COMP_METHOD *SSL_get_current_compression(SSL *s); +const COMP_METHOD *SSL_get_current_expansion(SSL *s); +const char *SSL_COMP_get_name(const COMP_METHOD *comp); +STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void); +int SSL_COMP_add_compression_method(int id,COMP_METHOD *cm); +#else +const void *SSL_get_current_compression(SSL *s); +const void *SSL_get_current_expansion(SSL *s); +const char *SSL_COMP_get_name(const void *comp); +void *SSL_COMP_get_compression_methods(void); +int SSL_COMP_add_compression_method(int id,void *cm); +#endif + +/* TLS extensions functions */ +int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len); + +int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb, + void *arg); + +/* Pre-shared secret session resumption functions */ +int SSL_set_session_secret_cb(SSL *s, tls_session_secret_cb_fn tls_session_secret_cb, void *arg); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_SSL_strings(void); + +/* Error codes for the SSL functions. */ + +/* Function codes. */ +#define SSL_F_CLIENT_CERTIFICATE 100 +#define SSL_F_CLIENT_FINISHED 167 +#define SSL_F_CLIENT_HELLO 101 +#define SSL_F_CLIENT_MASTER_KEY 102 +#define SSL_F_D2I_SSL_SESSION 103 +#define SSL_F_DO_DTLS1_WRITE 245 +#define SSL_F_DO_SSL3_WRITE 104 +#define SSL_F_DTLS1_ACCEPT 246 +#define SSL_F_DTLS1_ADD_CERT_TO_BUF 295 +#define SSL_F_DTLS1_BUFFER_RECORD 247 +#define SSL_F_DTLS1_CLIENT_HELLO 248 +#define SSL_F_DTLS1_CONNECT 249 +#define SSL_F_DTLS1_ENC 250 +#define SSL_F_DTLS1_GET_HELLO_VERIFY 251 +#define SSL_F_DTLS1_GET_MESSAGE 252 +#define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT 253 +#define SSL_F_DTLS1_GET_RECORD 254 +#define SSL_F_DTLS1_HANDLE_TIMEOUT 297 +#define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255 +#define SSL_F_DTLS1_PREPROCESS_FRAGMENT 288 +#define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256 +#define SSL_F_DTLS1_PROCESS_RECORD 257 +#define SSL_F_DTLS1_READ_BYTES 258 +#define SSL_F_DTLS1_READ_FAILED 259 +#define SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST 260 +#define SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE 261 +#define SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE 262 +#define SSL_F_DTLS1_SEND_CLIENT_VERIFY 263 +#define SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST 264 +#define SSL_F_DTLS1_SEND_SERVER_CERTIFICATE 265 +#define SSL_F_DTLS1_SEND_SERVER_HELLO 266 +#define SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE 267 +#define SSL_F_DTLS1_WRITE_APP_DATA_BYTES 268 +#define SSL_F_GET_CLIENT_FINISHED 105 +#define SSL_F_GET_CLIENT_HELLO 106 +#define SSL_F_GET_CLIENT_MASTER_KEY 107 +#define SSL_F_GET_SERVER_FINISHED 108 +#define SSL_F_GET_SERVER_HELLO 109 +#define SSL_F_GET_SERVER_VERIFY 110 +#define SSL_F_I2D_SSL_SESSION 111 +#define SSL_F_READ_N 112 +#define SSL_F_REQUEST_CERTIFICATE 113 +#define SSL_F_SERVER_FINISH 239 +#define SSL_F_SERVER_HELLO 114 +#define SSL_F_SERVER_VERIFY 240 +#define SSL_F_SSL23_ACCEPT 115 +#define SSL_F_SSL23_CLIENT_HELLO 116 +#define SSL_F_SSL23_CONNECT 117 +#define SSL_F_SSL23_GET_CLIENT_HELLO 118 +#define SSL_F_SSL23_GET_SERVER_HELLO 119 +#define SSL_F_SSL23_PEEK 237 +#define SSL_F_SSL23_READ 120 +#define SSL_F_SSL23_WRITE 121 +#define SSL_F_SSL2_ACCEPT 122 +#define SSL_F_SSL2_CONNECT 123 +#define SSL_F_SSL2_ENC_INIT 124 +#define SSL_F_SSL2_GENERATE_KEY_MATERIAL 241 +#define SSL_F_SSL2_PEEK 234 +#define SSL_F_SSL2_READ 125 +#define SSL_F_SSL2_READ_INTERNAL 236 +#define SSL_F_SSL2_SET_CERTIFICATE 126 +#define SSL_F_SSL2_WRITE 127 +#define SSL_F_SSL3_ACCEPT 128 +#define SSL_F_SSL3_ADD_CERT_TO_BUF 296 +#define SSL_F_SSL3_CALLBACK_CTRL 233 +#define SSL_F_SSL3_CHANGE_CIPHER_STATE 129 +#define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM 130 +#define SSL_F_SSL3_CLIENT_HELLO 131 +#define SSL_F_SSL3_CONNECT 132 +#define SSL_F_SSL3_CTRL 213 +#define SSL_F_SSL3_CTX_CTRL 133 +#define SSL_F_SSL3_DIGEST_CACHED_RECORDS 293 +#define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC 292 +#define SSL_F_SSL3_ENC 134 +#define SSL_F_SSL3_GENERATE_KEY_BLOCK 238 +#define SSL_F_SSL3_GET_CERTIFICATE_REQUEST 135 +#define SSL_F_SSL3_GET_CERT_STATUS 289 +#define SSL_F_SSL3_GET_CERT_VERIFY 136 +#define SSL_F_SSL3_GET_CLIENT_CERTIFICATE 137 +#define SSL_F_SSL3_GET_CLIENT_HELLO 138 +#define SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE 139 +#define SSL_F_SSL3_GET_FINISHED 140 +#define SSL_F_SSL3_GET_KEY_EXCHANGE 141 +#define SSL_F_SSL3_GET_MESSAGE 142 +#define SSL_F_SSL3_GET_NEW_SESSION_TICKET 283 +#define SSL_F_SSL3_GET_RECORD 143 +#define SSL_F_SSL3_GET_SERVER_CERTIFICATE 144 +#define SSL_F_SSL3_GET_SERVER_DONE 145 +#define SSL_F_SSL3_GET_SERVER_HELLO 146 +#define SSL_F_SSL3_HANDSHAKE_MAC 285 +#define SSL_F_SSL3_NEW_SESSION_TICKET 287 +#define SSL_F_SSL3_OUTPUT_CERT_CHAIN 147 +#define SSL_F_SSL3_PEEK 235 +#define SSL_F_SSL3_READ_BYTES 148 +#define SSL_F_SSL3_READ_N 149 +#define SSL_F_SSL3_SEND_CERTIFICATE_REQUEST 150 +#define SSL_F_SSL3_SEND_CLIENT_CERTIFICATE 151 +#define SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE 152 +#define SSL_F_SSL3_SEND_CLIENT_VERIFY 153 +#define SSL_F_SSL3_SEND_SERVER_CERTIFICATE 154 +#define SSL_F_SSL3_SEND_SERVER_HELLO 242 +#define SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE 155 +#define SSL_F_SSL3_SETUP_KEY_BLOCK 157 +#define SSL_F_SSL3_SETUP_READ_BUFFER 156 +#define SSL_F_SSL3_SETUP_WRITE_BUFFER 291 +#define SSL_F_SSL3_WRITE_BYTES 158 +#define SSL_F_SSL3_WRITE_PENDING 159 +#define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT 298 +#define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT 277 +#define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK 215 +#define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK 216 +#define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT 299 +#define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 278 +#define SSL_F_SSL_BAD_METHOD 160 +#define SSL_F_SSL_BYTES_TO_CIPHER_LIST 161 +#define SSL_F_SSL_CERT_DUP 221 +#define SSL_F_SSL_CERT_INST 222 +#define SSL_F_SSL_CERT_INSTANTIATE 214 +#define SSL_F_SSL_CERT_NEW 162 +#define SSL_F_SSL_CHECK_PRIVATE_KEY 163 +#define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT 280 +#define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG 279 +#define SSL_F_SSL_CIPHER_PROCESS_RULESTR 230 +#define SSL_F_SSL_CIPHER_STRENGTH_SORT 231 +#define SSL_F_SSL_CLEAR 164 +#define SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD 165 +#define SSL_F_SSL_CREATE_CIPHER_LIST 166 +#define SSL_F_SSL_CTRL 232 +#define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY 168 +#define SSL_F_SSL_CTX_NEW 169 +#define SSL_F_SSL_CTX_SET_CIPHER_LIST 269 +#define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE 290 +#define SSL_F_SSL_CTX_SET_PURPOSE 226 +#define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT 219 +#define SSL_F_SSL_CTX_SET_SSL_VERSION 170 +#define SSL_F_SSL_CTX_SET_TRUST 229 +#define SSL_F_SSL_CTX_USE_CERTIFICATE 171 +#define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172 +#define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE 220 +#define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE 173 +#define SSL_F_SSL_CTX_USE_PRIVATEKEY 174 +#define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1 175 +#define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE 176 +#define SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT 272 +#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY 177 +#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1 178 +#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE 179 +#define SSL_F_SSL_DO_HANDSHAKE 180 +#define SSL_F_SSL_GET_NEW_SESSION 181 +#define SSL_F_SSL_GET_PREV_SESSION 217 +#define SSL_F_SSL_GET_SERVER_SEND_CERT 182 +#define SSL_F_SSL_GET_SIGN_PKEY 183 +#define SSL_F_SSL_INIT_WBIO_BUFFER 184 +#define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185 +#define SSL_F_SSL_NEW 186 +#define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT 300 +#define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT 302 +#define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT 301 +#define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT 303 +#define SSL_F_SSL_PEEK 270 +#define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT 281 +#define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT 282 +#define SSL_F_SSL_READ 223 +#define SSL_F_SSL_RSA_PRIVATE_DECRYPT 187 +#define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 188 +#define SSL_F_SSL_SESSION_NEW 189 +#define SSL_F_SSL_SESSION_PRINT_FP 190 +#define SSL_F_SSL_SESS_CERT_NEW 225 +#define SSL_F_SSL_SET_CERT 191 +#define SSL_F_SSL_SET_CIPHER_LIST 271 +#define SSL_F_SSL_SET_FD 192 +#define SSL_F_SSL_SET_PKEY 193 +#define SSL_F_SSL_SET_PURPOSE 227 +#define SSL_F_SSL_SET_RFD 194 +#define SSL_F_SSL_SET_SESSION 195 +#define SSL_F_SSL_SET_SESSION_ID_CONTEXT 218 +#define SSL_F_SSL_SET_SESSION_TICKET_EXT 294 +#define SSL_F_SSL_SET_TRUST 228 +#define SSL_F_SSL_SET_WFD 196 +#define SSL_F_SSL_SHUTDOWN 224 +#define SSL_F_SSL_UNDEFINED_CONST_FUNCTION 243 +#define SSL_F_SSL_UNDEFINED_FUNCTION 197 +#define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244 +#define SSL_F_SSL_USE_CERTIFICATE 198 +#define SSL_F_SSL_USE_CERTIFICATE_ASN1 199 +#define SSL_F_SSL_USE_CERTIFICATE_FILE 200 +#define SSL_F_SSL_USE_PRIVATEKEY 201 +#define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202 +#define SSL_F_SSL_USE_PRIVATEKEY_FILE 203 +#define SSL_F_SSL_USE_PSK_IDENTITY_HINT 273 +#define SSL_F_SSL_USE_RSAPRIVATEKEY 204 +#define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1 205 +#define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE 206 +#define SSL_F_SSL_VERIFY_CERT_CHAIN 207 +#define SSL_F_SSL_WRITE 208 +#define SSL_F_TLS1_CERT_VERIFY_MAC 286 +#define SSL_F_TLS1_CHANGE_CIPHER_STATE 209 +#define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT 274 +#define SSL_F_TLS1_ENC 210 +#define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT 275 +#define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT 276 +#define SSL_F_TLS1_PRF 284 +#define SSL_F_TLS1_SETUP_KEY_BLOCK 211 +#define SSL_F_WRITE_PENDING 212 + +/* Reason codes. */ +#define SSL_R_APP_DATA_IN_HANDSHAKE 100 +#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272 +#define SSL_R_BAD_ALERT_RECORD 101 +#define SSL_R_BAD_AUTHENTICATION_TYPE 102 +#define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 +#define SSL_R_BAD_CHECKSUM 104 +#define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK 106 +#define SSL_R_BAD_DECOMPRESSION 107 +#define SSL_R_BAD_DH_G_LENGTH 108 +#define SSL_R_BAD_DH_PUB_KEY_LENGTH 109 +#define SSL_R_BAD_DH_P_LENGTH 110 +#define SSL_R_BAD_DIGEST_LENGTH 111 +#define SSL_R_BAD_DSA_SIGNATURE 112 +#define SSL_R_BAD_ECC_CERT 304 +#define SSL_R_BAD_ECDSA_SIGNATURE 305 +#define SSL_R_BAD_ECPOINT 306 +#define SSL_R_BAD_HANDSHAKE_LENGTH 332 +#define SSL_R_BAD_HELLO_REQUEST 105 +#define SSL_R_BAD_LENGTH 271 +#define SSL_R_BAD_MAC_DECODE 113 +#define SSL_R_BAD_MAC_LENGTH 333 +#define SSL_R_BAD_MESSAGE_TYPE 114 +#define SSL_R_BAD_PACKET_LENGTH 115 +#define SSL_R_BAD_PROTOCOL_VERSION_NUMBER 116 +#define SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH 316 +#define SSL_R_BAD_RESPONSE_ARGUMENT 117 +#define SSL_R_BAD_RSA_DECRYPT 118 +#define SSL_R_BAD_RSA_ENCRYPT 119 +#define SSL_R_BAD_RSA_E_LENGTH 120 +#define SSL_R_BAD_RSA_MODULUS_LENGTH 121 +#define SSL_R_BAD_RSA_SIGNATURE 122 +#define SSL_R_BAD_SIGNATURE 123 +#define SSL_R_BAD_SSL_FILETYPE 124 +#define SSL_R_BAD_SSL_SESSION_ID_LENGTH 125 +#define SSL_R_BAD_STATE 126 +#define SSL_R_BAD_WRITE_RETRY 127 +#define SSL_R_BIO_NOT_SET 128 +#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 129 +#define SSL_R_BN_LIB 130 +#define SSL_R_CA_DN_LENGTH_MISMATCH 131 +#define SSL_R_CA_DN_TOO_LONG 132 +#define SSL_R_CCS_RECEIVED_EARLY 133 +#define SSL_R_CERTIFICATE_VERIFY_FAILED 134 +#define SSL_R_CERT_LENGTH_MISMATCH 135 +#define SSL_R_CHALLENGE_IS_DIFFERENT 136 +#define SSL_R_CIPHER_CODE_WRONG_LENGTH 137 +#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138 +#define SSL_R_CIPHER_TABLE_SRC_ERROR 139 +#define SSL_R_CLIENTHELLO_TLSEXT 226 +#define SSL_R_COMPRESSED_LENGTH_TOO_LONG 140 +#define SSL_R_COMPRESSION_DISABLED 343 +#define SSL_R_COMPRESSION_FAILURE 141 +#define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE 307 +#define SSL_R_COMPRESSION_LIBRARY_ERROR 142 +#define SSL_R_CONNECTION_ID_IS_DIFFERENT 143 +#define SSL_R_CONNECTION_TYPE_NOT_SET 144 +#define SSL_R_COOKIE_MISMATCH 308 +#define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 145 +#define SSL_R_DATA_LENGTH_TOO_LONG 146 +#define SSL_R_DECRYPTION_FAILED 147 +#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 281 +#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148 +#define SSL_R_DIGEST_CHECK_FAILED 149 +#define SSL_R_DTLS_MESSAGE_TOO_BIG 334 +#define SSL_R_DUPLICATE_COMPRESSION_ID 309 +#define SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT 317 +#define SSL_R_ECC_CERT_NOT_FOR_SIGNING 318 +#define SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE 322 +#define SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE 323 +#define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER 310 +#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150 +#define SSL_R_ERROR_GENERATING_TMP_RSA_KEY 282 +#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 151 +#define SSL_R_EXCESSIVE_MESSAGE_SIZE 152 +#define SSL_R_EXTRA_DATA_IN_MESSAGE 153 +#define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154 +#define SSL_R_HTTPS_PROXY_REQUEST 155 +#define SSL_R_HTTP_REQUEST 156 +#define SSL_R_ILLEGAL_PADDING 283 +#define SSL_R_INCONSISTENT_COMPRESSION 340 +#define SSL_R_INVALID_CHALLENGE_LENGTH 158 +#define SSL_R_INVALID_COMMAND 280 +#define SSL_R_INVALID_COMPRESSION_ALGORITHM 341 +#define SSL_R_INVALID_PURPOSE 278 +#define SSL_R_INVALID_STATUS_RESPONSE 328 +#define SSL_R_INVALID_TICKET_KEYS_LENGTH 325 +#define SSL_R_INVALID_TRUST 279 +#define SSL_R_KEY_ARG_TOO_LONG 284 +#define SSL_R_KRB5 285 +#define SSL_R_KRB5_C_CC_PRINC 286 +#define SSL_R_KRB5_C_GET_CRED 287 +#define SSL_R_KRB5_C_INIT 288 +#define SSL_R_KRB5_C_MK_REQ 289 +#define SSL_R_KRB5_S_BAD_TICKET 290 +#define SSL_R_KRB5_S_INIT 291 +#define SSL_R_KRB5_S_RD_REQ 292 +#define SSL_R_KRB5_S_TKT_EXPIRED 293 +#define SSL_R_KRB5_S_TKT_NYV 294 +#define SSL_R_KRB5_S_TKT_SKEW 295 +#define SSL_R_LENGTH_MISMATCH 159 +#define SSL_R_LENGTH_TOO_SHORT 160 +#define SSL_R_LIBRARY_BUG 274 +#define SSL_R_LIBRARY_HAS_NO_CIPHERS 161 +#define SSL_R_MESSAGE_TOO_LONG 296 +#define SSL_R_MISSING_DH_DSA_CERT 162 +#define SSL_R_MISSING_DH_KEY 163 +#define SSL_R_MISSING_DH_RSA_CERT 164 +#define SSL_R_MISSING_DSA_SIGNING_CERT 165 +#define SSL_R_MISSING_EXPORT_TMP_DH_KEY 166 +#define SSL_R_MISSING_EXPORT_TMP_RSA_KEY 167 +#define SSL_R_MISSING_RSA_CERTIFICATE 168 +#define SSL_R_MISSING_RSA_ENCRYPTING_CERT 169 +#define SSL_R_MISSING_RSA_SIGNING_CERT 170 +#define SSL_R_MISSING_TMP_DH_KEY 171 +#define SSL_R_MISSING_TMP_ECDH_KEY 311 +#define SSL_R_MISSING_TMP_RSA_KEY 172 +#define SSL_R_MISSING_TMP_RSA_PKEY 173 +#define SSL_R_MISSING_VERIFY_MESSAGE 174 +#define SSL_R_NON_SSLV2_INITIAL_PACKET 175 +#define SSL_R_NO_CERTIFICATES_RETURNED 176 +#define SSL_R_NO_CERTIFICATE_ASSIGNED 177 +#define SSL_R_NO_CERTIFICATE_RETURNED 178 +#define SSL_R_NO_CERTIFICATE_SET 179 +#define SSL_R_NO_CERTIFICATE_SPECIFIED 180 +#define SSL_R_NO_CIPHERS_AVAILABLE 181 +#define SSL_R_NO_CIPHERS_PASSED 182 +#define SSL_R_NO_CIPHERS_SPECIFIED 183 +#define SSL_R_NO_CIPHER_LIST 184 +#define SSL_R_NO_CIPHER_MATCH 185 +#define SSL_R_NO_CLIENT_CERT_METHOD 331 +#define SSL_R_NO_CLIENT_CERT_RECEIVED 186 +#define SSL_R_NO_COMPRESSION_SPECIFIED 187 +#define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER 330 +#define SSL_R_NO_METHOD_SPECIFIED 188 +#define SSL_R_NO_PRIVATEKEY 189 +#define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190 +#define SSL_R_NO_PROTOCOLS_AVAILABLE 191 +#define SSL_R_NO_PUBLICKEY 192 +#define SSL_R_NO_RENEGOTIATION 339 +#define SSL_R_NO_REQUIRED_DIGEST 324 +#define SSL_R_NO_SHARED_CIPHER 193 +#define SSL_R_NO_VERIFY_CALLBACK 194 +#define SSL_R_NULL_SSL_CTX 195 +#define SSL_R_NULL_SSL_METHOD_PASSED 196 +#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 197 +#define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344 +#define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE 297 +#define SSL_R_OPAQUE_PRF_INPUT_TOO_LONG 327 +#define SSL_R_PACKET_LENGTH_TOO_LONG 198 +#define SSL_R_PARSE_TLSEXT 227 +#define SSL_R_PATH_TOO_LONG 270 +#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 199 +#define SSL_R_PEER_ERROR 200 +#define SSL_R_PEER_ERROR_CERTIFICATE 201 +#define SSL_R_PEER_ERROR_NO_CERTIFICATE 202 +#define SSL_R_PEER_ERROR_NO_CIPHER 203 +#define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 204 +#define SSL_R_PRE_MAC_LENGTH_TOO_LONG 205 +#define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS 206 +#define SSL_R_PROTOCOL_IS_SHUTDOWN 207 +#define SSL_R_PSK_IDENTITY_NOT_FOUND 223 +#define SSL_R_PSK_NO_CLIENT_CB 224 +#define SSL_R_PSK_NO_SERVER_CB 225 +#define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR 208 +#define SSL_R_PUBLIC_KEY_IS_NOT_RSA 209 +#define SSL_R_PUBLIC_KEY_NOT_RSA 210 +#define SSL_R_READ_BIO_NOT_SET 211 +#define SSL_R_READ_TIMEOUT_EXPIRED 312 +#define SSL_R_READ_WRONG_PACKET_TYPE 212 +#define SSL_R_RECORD_LENGTH_MISMATCH 213 +#define SSL_R_RECORD_TOO_LARGE 214 +#define SSL_R_RECORD_TOO_SMALL 298 +#define SSL_R_RENEGOTIATE_EXT_TOO_LONG 335 +#define SSL_R_RENEGOTIATION_ENCODING_ERR 336 +#define SSL_R_RENEGOTIATION_MISMATCH 337 +#define SSL_R_REQUIRED_CIPHER_MISSING 215 +#define SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING 342 +#define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO 216 +#define SSL_R_REUSE_CERT_TYPE_NOT_ZERO 217 +#define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO 218 +#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345 +#define SSL_R_SERVERHELLO_TLSEXT 275 +#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 +#define SSL_R_SHORT_READ 219 +#define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220 +#define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221 +#define SSL_R_SSL2_CONNECTION_ID_TOO_LONG 299 +#define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT 321 +#define SSL_R_SSL3_EXT_INVALID_SERVERNAME 319 +#define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE 320 +#define SSL_R_SSL3_SESSION_ID_TOO_LONG 300 +#define SSL_R_SSL3_SESSION_ID_TOO_SHORT 222 +#define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 +#define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED 1044 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN 1046 +#define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE 1030 +#define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040 +#define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047 +#define SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041 +#define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 +#define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043 +#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 228 +#define SSL_R_SSL_HANDSHAKE_FAILURE 229 +#define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS 230 +#define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED 301 +#define SSL_R_SSL_SESSION_ID_CONFLICT 302 +#define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG 273 +#define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH 303 +#define SSL_R_SSL_SESSION_ID_IS_DIFFERENT 231 +#define SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049 +#define SSL_R_TLSV1_ALERT_DECODE_ERROR 1050 +#define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 +#define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 +#define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 +#define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 +#define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 +#define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 +#define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070 +#define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022 +#define SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 +#define SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 +#define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 +#define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 +#define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111 +#define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112 +#define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110 +#define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER 232 +#define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157 +#define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233 +#define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 234 +#define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER 235 +#define SSL_R_UNABLE_TO_DECODE_DH_CERTS 236 +#define SSL_R_UNABLE_TO_DECODE_ECDH_CERTS 313 +#define SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY 237 +#define SSL_R_UNABLE_TO_FIND_DH_PARAMETERS 238 +#define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 314 +#define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 239 +#define SSL_R_UNABLE_TO_FIND_SSL_METHOD 240 +#define SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES 241 +#define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES 242 +#define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES 243 +#define SSL_R_UNEXPECTED_MESSAGE 244 +#define SSL_R_UNEXPECTED_RECORD 245 +#define SSL_R_UNINITIALIZED 276 +#define SSL_R_UNKNOWN_ALERT_TYPE 246 +#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 247 +#define SSL_R_UNKNOWN_CIPHER_RETURNED 248 +#define SSL_R_UNKNOWN_CIPHER_TYPE 249 +#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 250 +#define SSL_R_UNKNOWN_PKEY_TYPE 251 +#define SSL_R_UNKNOWN_PROTOCOL 252 +#define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE 253 +#define SSL_R_UNKNOWN_SSL_VERSION 254 +#define SSL_R_UNKNOWN_STATE 255 +#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 338 +#define SSL_R_UNSUPPORTED_CIPHER 256 +#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 257 +#define SSL_R_UNSUPPORTED_DIGEST_TYPE 326 +#define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 315 +#define SSL_R_UNSUPPORTED_PROTOCOL 258 +#define SSL_R_UNSUPPORTED_SSL_VERSION 259 +#define SSL_R_UNSUPPORTED_STATUS_TYPE 329 +#define SSL_R_WRITE_BIO_NOT_SET 260 +#define SSL_R_WRONG_CIPHER_RETURNED 261 +#define SSL_R_WRONG_MESSAGE_TYPE 262 +#define SSL_R_WRONG_NUMBER_OF_KEY_BITS 263 +#define SSL_R_WRONG_SIGNATURE_LENGTH 264 +#define SSL_R_WRONG_SIGNATURE_SIZE 265 +#define SSL_R_WRONG_SSL_VERSION 266 +#define SSL_R_WRONG_VERSION_NUMBER 267 +#define SSL_R_X509_LIB 268 +#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 269 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/ssl2.h b/extra_lib/include/openssl/ssl2.h new file mode 100644 index 0000000..99a52ea --- /dev/null +++ b/extra_lib/include/openssl/ssl2.h @@ -0,0 +1,268 @@ +/* ssl/ssl2.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_SSL2_H +#define HEADER_SSL2_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Protocol Version Codes */ +#define SSL2_VERSION 0x0002 +#define SSL2_VERSION_MAJOR 0x00 +#define SSL2_VERSION_MINOR 0x02 +/* #define SSL2_CLIENT_VERSION 0x0002 */ +/* #define SSL2_SERVER_VERSION 0x0002 */ + +/* Protocol Message Codes */ +#define SSL2_MT_ERROR 0 +#define SSL2_MT_CLIENT_HELLO 1 +#define SSL2_MT_CLIENT_MASTER_KEY 2 +#define SSL2_MT_CLIENT_FINISHED 3 +#define SSL2_MT_SERVER_HELLO 4 +#define SSL2_MT_SERVER_VERIFY 5 +#define SSL2_MT_SERVER_FINISHED 6 +#define SSL2_MT_REQUEST_CERTIFICATE 7 +#define SSL2_MT_CLIENT_CERTIFICATE 8 + +/* Error Message Codes */ +#define SSL2_PE_UNDEFINED_ERROR 0x0000 +#define SSL2_PE_NO_CIPHER 0x0001 +#define SSL2_PE_NO_CERTIFICATE 0x0002 +#define SSL2_PE_BAD_CERTIFICATE 0x0004 +#define SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006 + +/* Cipher Kind Values */ +#define SSL2_CK_NULL_WITH_MD5 0x02000000 /* v3 */ +#define SSL2_CK_RC4_128_WITH_MD5 0x02010080 +#define SSL2_CK_RC4_128_EXPORT40_WITH_MD5 0x02020080 +#define SSL2_CK_RC2_128_CBC_WITH_MD5 0x02030080 +#define SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5 0x02040080 +#define SSL2_CK_IDEA_128_CBC_WITH_MD5 0x02050080 +#define SSL2_CK_DES_64_CBC_WITH_MD5 0x02060040 +#define SSL2_CK_DES_64_CBC_WITH_SHA 0x02060140 /* v3 */ +#define SSL2_CK_DES_192_EDE3_CBC_WITH_MD5 0x020700c0 +#define SSL2_CK_DES_192_EDE3_CBC_WITH_SHA 0x020701c0 /* v3 */ +#define SSL2_CK_RC4_64_WITH_MD5 0x02080080 /* MS hack */ + +#define SSL2_CK_DES_64_CFB64_WITH_MD5_1 0x02ff0800 /* SSLeay */ +#define SSL2_CK_NULL 0x02ff0810 /* SSLeay */ + +#define SSL2_TXT_DES_64_CFB64_WITH_MD5_1 "DES-CFB-M1" +#define SSL2_TXT_NULL_WITH_MD5 "NULL-MD5" +#define SSL2_TXT_RC4_128_WITH_MD5 "RC4-MD5" +#define SSL2_TXT_RC4_128_EXPORT40_WITH_MD5 "EXP-RC4-MD5" +#define SSL2_TXT_RC2_128_CBC_WITH_MD5 "RC2-CBC-MD5" +#define SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 "EXP-RC2-CBC-MD5" +#define SSL2_TXT_IDEA_128_CBC_WITH_MD5 "IDEA-CBC-MD5" +#define SSL2_TXT_DES_64_CBC_WITH_MD5 "DES-CBC-MD5" +#define SSL2_TXT_DES_64_CBC_WITH_SHA "DES-CBC-SHA" +#define SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5 "DES-CBC3-MD5" +#define SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA "DES-CBC3-SHA" +#define SSL2_TXT_RC4_64_WITH_MD5 "RC4-64-MD5" + +#define SSL2_TXT_NULL "NULL" + +/* Flags for the SSL_CIPHER.algorithm2 field */ +#define SSL2_CF_5_BYTE_ENC 0x01 +#define SSL2_CF_8_BYTE_ENC 0x02 + +/* Certificate Type Codes */ +#define SSL2_CT_X509_CERTIFICATE 0x01 + +/* Authentication Type Code */ +#define SSL2_AT_MD5_WITH_RSA_ENCRYPTION 0x01 + +#define SSL2_MAX_SSL_SESSION_ID_LENGTH 32 + +/* Upper/Lower Bounds */ +#define SSL2_MAX_MASTER_KEY_LENGTH_IN_BITS 256 +#ifdef OPENSSL_SYS_MPE +#define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER 29998u +#else +#define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER 32767u /* 2^15-1 */ +#endif +#define SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER 16383 /* 2^14-1 */ + +#define SSL2_CHALLENGE_LENGTH 16 +/*#define SSL2_CHALLENGE_LENGTH 32 */ +#define SSL2_MIN_CHALLENGE_LENGTH 16 +#define SSL2_MAX_CHALLENGE_LENGTH 32 +#define SSL2_CONNECTION_ID_LENGTH 16 +#define SSL2_MAX_CONNECTION_ID_LENGTH 16 +#define SSL2_SSL_SESSION_ID_LENGTH 16 +#define SSL2_MAX_CERT_CHALLENGE_LENGTH 32 +#define SSL2_MIN_CERT_CHALLENGE_LENGTH 16 +#define SSL2_MAX_KEY_MATERIAL_LENGTH 24 + +#ifndef HEADER_SSL_LOCL_H +#define CERT char +#endif + +typedef struct ssl2_state_st + { + int three_byte_header; + int clear_text; /* clear text */ + int escape; /* not used in SSLv2 */ + int ssl2_rollback; /* used if SSLv23 rolled back to SSLv2 */ + + /* non-blocking io info, used to make sure the same + * args were passwd */ + unsigned int wnum; /* number of bytes sent so far */ + int wpend_tot; + const unsigned char *wpend_buf; + + int wpend_off; /* offset to data to write */ + int wpend_len; /* number of bytes passwd to write */ + int wpend_ret; /* number of bytes to return to caller */ + + /* buffer raw data */ + int rbuf_left; + int rbuf_offs; + unsigned char *rbuf; + unsigned char *wbuf; + + unsigned char *write_ptr;/* used to point to the start due to + * 2/3 byte header. */ + + unsigned int padding; + unsigned int rlength; /* passed to ssl2_enc */ + int ract_data_length; /* Set when things are encrypted. */ + unsigned int wlength; /* passed to ssl2_enc */ + int wact_data_length; /* Set when things are decrypted. */ + unsigned char *ract_data; + unsigned char *wact_data; + unsigned char *mac_data; + + unsigned char *read_key; + unsigned char *write_key; + + /* Stuff specifically to do with this SSL session */ + unsigned int challenge_length; + unsigned char challenge[SSL2_MAX_CHALLENGE_LENGTH]; + unsigned int conn_id_length; + unsigned char conn_id[SSL2_MAX_CONNECTION_ID_LENGTH]; + unsigned int key_material_length; + unsigned char key_material[SSL2_MAX_KEY_MATERIAL_LENGTH*2]; + + unsigned long read_sequence; + unsigned long write_sequence; + + struct { + unsigned int conn_id_length; + unsigned int cert_type; + unsigned int cert_length; + unsigned int csl; + unsigned int clear; + unsigned int enc; + unsigned char ccl[SSL2_MAX_CERT_CHALLENGE_LENGTH]; + unsigned int cipher_spec_length; + unsigned int session_id_length; + unsigned int clen; + unsigned int rlen; + } tmp; + } SSL2_STATE; + +/* SSLv2 */ +/* client */ +#define SSL2_ST_SEND_CLIENT_HELLO_A (0x10|SSL_ST_CONNECT) +#define SSL2_ST_SEND_CLIENT_HELLO_B (0x11|SSL_ST_CONNECT) +#define SSL2_ST_GET_SERVER_HELLO_A (0x20|SSL_ST_CONNECT) +#define SSL2_ST_GET_SERVER_HELLO_B (0x21|SSL_ST_CONNECT) +#define SSL2_ST_SEND_CLIENT_MASTER_KEY_A (0x30|SSL_ST_CONNECT) +#define SSL2_ST_SEND_CLIENT_MASTER_KEY_B (0x31|SSL_ST_CONNECT) +#define SSL2_ST_SEND_CLIENT_FINISHED_A (0x40|SSL_ST_CONNECT) +#define SSL2_ST_SEND_CLIENT_FINISHED_B (0x41|SSL_ST_CONNECT) +#define SSL2_ST_SEND_CLIENT_CERTIFICATE_A (0x50|SSL_ST_CONNECT) +#define SSL2_ST_SEND_CLIENT_CERTIFICATE_B (0x51|SSL_ST_CONNECT) +#define SSL2_ST_SEND_CLIENT_CERTIFICATE_C (0x52|SSL_ST_CONNECT) +#define SSL2_ST_SEND_CLIENT_CERTIFICATE_D (0x53|SSL_ST_CONNECT) +#define SSL2_ST_GET_SERVER_VERIFY_A (0x60|SSL_ST_CONNECT) +#define SSL2_ST_GET_SERVER_VERIFY_B (0x61|SSL_ST_CONNECT) +#define SSL2_ST_GET_SERVER_FINISHED_A (0x70|SSL_ST_CONNECT) +#define SSL2_ST_GET_SERVER_FINISHED_B (0x71|SSL_ST_CONNECT) +#define SSL2_ST_CLIENT_START_ENCRYPTION (0x80|SSL_ST_CONNECT) +#define SSL2_ST_X509_GET_CLIENT_CERTIFICATE (0x90|SSL_ST_CONNECT) +/* server */ +#define SSL2_ST_GET_CLIENT_HELLO_A (0x10|SSL_ST_ACCEPT) +#define SSL2_ST_GET_CLIENT_HELLO_B (0x11|SSL_ST_ACCEPT) +#define SSL2_ST_GET_CLIENT_HELLO_C (0x12|SSL_ST_ACCEPT) +#define SSL2_ST_SEND_SERVER_HELLO_A (0x20|SSL_ST_ACCEPT) +#define SSL2_ST_SEND_SERVER_HELLO_B (0x21|SSL_ST_ACCEPT) +#define SSL2_ST_GET_CLIENT_MASTER_KEY_A (0x30|SSL_ST_ACCEPT) +#define SSL2_ST_GET_CLIENT_MASTER_KEY_B (0x31|SSL_ST_ACCEPT) +#define SSL2_ST_SEND_SERVER_VERIFY_A (0x40|SSL_ST_ACCEPT) +#define SSL2_ST_SEND_SERVER_VERIFY_B (0x41|SSL_ST_ACCEPT) +#define SSL2_ST_SEND_SERVER_VERIFY_C (0x42|SSL_ST_ACCEPT) +#define SSL2_ST_GET_CLIENT_FINISHED_A (0x50|SSL_ST_ACCEPT) +#define SSL2_ST_GET_CLIENT_FINISHED_B (0x51|SSL_ST_ACCEPT) +#define SSL2_ST_SEND_SERVER_FINISHED_A (0x60|SSL_ST_ACCEPT) +#define SSL2_ST_SEND_SERVER_FINISHED_B (0x61|SSL_ST_ACCEPT) +#define SSL2_ST_SEND_REQUEST_CERTIFICATE_A (0x70|SSL_ST_ACCEPT) +#define SSL2_ST_SEND_REQUEST_CERTIFICATE_B (0x71|SSL_ST_ACCEPT) +#define SSL2_ST_SEND_REQUEST_CERTIFICATE_C (0x72|SSL_ST_ACCEPT) +#define SSL2_ST_SEND_REQUEST_CERTIFICATE_D (0x73|SSL_ST_ACCEPT) +#define SSL2_ST_SERVER_START_ENCRYPTION (0x80|SSL_ST_ACCEPT) +#define SSL2_ST_X509_GET_SERVER_CERTIFICATE (0x90|SSL_ST_ACCEPT) + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/extra_lib/include/openssl/ssl23.h b/extra_lib/include/openssl/ssl23.h new file mode 100644 index 0000000..d322898 --- /dev/null +++ b/extra_lib/include/openssl/ssl23.h @@ -0,0 +1,83 @@ +/* ssl/ssl23.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_SSL23_H +#define HEADER_SSL23_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*client */ +/* write to server */ +#define SSL23_ST_CW_CLNT_HELLO_A (0x210|SSL_ST_CONNECT) +#define SSL23_ST_CW_CLNT_HELLO_B (0x211|SSL_ST_CONNECT) +/* read from server */ +#define SSL23_ST_CR_SRVR_HELLO_A (0x220|SSL_ST_CONNECT) +#define SSL23_ST_CR_SRVR_HELLO_B (0x221|SSL_ST_CONNECT) + +/* server */ +/* read from client */ +#define SSL23_ST_SR_CLNT_HELLO_A (0x210|SSL_ST_ACCEPT) +#define SSL23_ST_SR_CLNT_HELLO_B (0x211|SSL_ST_ACCEPT) + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/extra_lib/include/openssl/ssl3.h b/extra_lib/include/openssl/ssl3.h new file mode 100644 index 0000000..baaa89e --- /dev/null +++ b/extra_lib/include/openssl/ssl3.h @@ -0,0 +1,637 @@ +/* ssl/ssl3.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_SSL3_H +#define HEADER_SSL3_H + +#ifndef OPENSSL_NO_COMP +#include +#endif +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Signalling cipher suite value: from draft-ietf-tls-renegotiation-03.txt */ +#define SSL3_CK_SCSV 0x030000FF + +#define SSL3_CK_RSA_NULL_MD5 0x03000001 +#define SSL3_CK_RSA_NULL_SHA 0x03000002 +#define SSL3_CK_RSA_RC4_40_MD5 0x03000003 +#define SSL3_CK_RSA_RC4_128_MD5 0x03000004 +#define SSL3_CK_RSA_RC4_128_SHA 0x03000005 +#define SSL3_CK_RSA_RC2_40_MD5 0x03000006 +#define SSL3_CK_RSA_IDEA_128_SHA 0x03000007 +#define SSL3_CK_RSA_DES_40_CBC_SHA 0x03000008 +#define SSL3_CK_RSA_DES_64_CBC_SHA 0x03000009 +#define SSL3_CK_RSA_DES_192_CBC3_SHA 0x0300000A + +#define SSL3_CK_DH_DSS_DES_40_CBC_SHA 0x0300000B +#define SSL3_CK_DH_DSS_DES_64_CBC_SHA 0x0300000C +#define SSL3_CK_DH_DSS_DES_192_CBC3_SHA 0x0300000D +#define SSL3_CK_DH_RSA_DES_40_CBC_SHA 0x0300000E +#define SSL3_CK_DH_RSA_DES_64_CBC_SHA 0x0300000F +#define SSL3_CK_DH_RSA_DES_192_CBC3_SHA 0x03000010 + +#define SSL3_CK_EDH_DSS_DES_40_CBC_SHA 0x03000011 +#define SSL3_CK_EDH_DSS_DES_64_CBC_SHA 0x03000012 +#define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA 0x03000013 +#define SSL3_CK_EDH_RSA_DES_40_CBC_SHA 0x03000014 +#define SSL3_CK_EDH_RSA_DES_64_CBC_SHA 0x03000015 +#define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA 0x03000016 + +#define SSL3_CK_ADH_RC4_40_MD5 0x03000017 +#define SSL3_CK_ADH_RC4_128_MD5 0x03000018 +#define SSL3_CK_ADH_DES_40_CBC_SHA 0x03000019 +#define SSL3_CK_ADH_DES_64_CBC_SHA 0x0300001A +#define SSL3_CK_ADH_DES_192_CBC_SHA 0x0300001B + +#if 0 + #define SSL3_CK_FZA_DMS_NULL_SHA 0x0300001C + #define SSL3_CK_FZA_DMS_FZA_SHA 0x0300001D + #if 0 /* Because it clashes with KRB5, is never used any more, and is safe + to remove according to David Hopwood + of the ietf-tls list */ + #define SSL3_CK_FZA_DMS_RC4_SHA 0x0300001E + #endif +#endif + +/* VRS Additional Kerberos5 entries + */ +#define SSL3_CK_KRB5_DES_64_CBC_SHA 0x0300001E +#define SSL3_CK_KRB5_DES_192_CBC3_SHA 0x0300001F +#define SSL3_CK_KRB5_RC4_128_SHA 0x03000020 +#define SSL3_CK_KRB5_IDEA_128_CBC_SHA 0x03000021 +#define SSL3_CK_KRB5_DES_64_CBC_MD5 0x03000022 +#define SSL3_CK_KRB5_DES_192_CBC3_MD5 0x03000023 +#define SSL3_CK_KRB5_RC4_128_MD5 0x03000024 +#define SSL3_CK_KRB5_IDEA_128_CBC_MD5 0x03000025 + +#define SSL3_CK_KRB5_DES_40_CBC_SHA 0x03000026 +#define SSL3_CK_KRB5_RC2_40_CBC_SHA 0x03000027 +#define SSL3_CK_KRB5_RC4_40_SHA 0x03000028 +#define SSL3_CK_KRB5_DES_40_CBC_MD5 0x03000029 +#define SSL3_CK_KRB5_RC2_40_CBC_MD5 0x0300002A +#define SSL3_CK_KRB5_RC4_40_MD5 0x0300002B + +#define SSL3_TXT_RSA_NULL_MD5 "NULL-MD5" +#define SSL3_TXT_RSA_NULL_SHA "NULL-SHA" +#define SSL3_TXT_RSA_RC4_40_MD5 "EXP-RC4-MD5" +#define SSL3_TXT_RSA_RC4_128_MD5 "RC4-MD5" +#define SSL3_TXT_RSA_RC4_128_SHA "RC4-SHA" +#define SSL3_TXT_RSA_RC2_40_MD5 "EXP-RC2-CBC-MD5" +#define SSL3_TXT_RSA_IDEA_128_SHA "IDEA-CBC-SHA" +#define SSL3_TXT_RSA_DES_40_CBC_SHA "EXP-DES-CBC-SHA" +#define SSL3_TXT_RSA_DES_64_CBC_SHA "DES-CBC-SHA" +#define SSL3_TXT_RSA_DES_192_CBC3_SHA "DES-CBC3-SHA" + +#define SSL3_TXT_DH_DSS_DES_40_CBC_SHA "EXP-DH-DSS-DES-CBC-SHA" +#define SSL3_TXT_DH_DSS_DES_64_CBC_SHA "DH-DSS-DES-CBC-SHA" +#define SSL3_TXT_DH_DSS_DES_192_CBC3_SHA "DH-DSS-DES-CBC3-SHA" +#define SSL3_TXT_DH_RSA_DES_40_CBC_SHA "EXP-DH-RSA-DES-CBC-SHA" +#define SSL3_TXT_DH_RSA_DES_64_CBC_SHA "DH-RSA-DES-CBC-SHA" +#define SSL3_TXT_DH_RSA_DES_192_CBC3_SHA "DH-RSA-DES-CBC3-SHA" + +#define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA "EXP-EDH-DSS-DES-CBC-SHA" +#define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA "EDH-DSS-DES-CBC-SHA" +#define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA "EDH-DSS-DES-CBC3-SHA" +#define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA "EXP-EDH-RSA-DES-CBC-SHA" +#define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA "EDH-RSA-DES-CBC-SHA" +#define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA "EDH-RSA-DES-CBC3-SHA" + +#define SSL3_TXT_ADH_RC4_40_MD5 "EXP-ADH-RC4-MD5" +#define SSL3_TXT_ADH_RC4_128_MD5 "ADH-RC4-MD5" +#define SSL3_TXT_ADH_DES_40_CBC_SHA "EXP-ADH-DES-CBC-SHA" +#define SSL3_TXT_ADH_DES_64_CBC_SHA "ADH-DES-CBC-SHA" +#define SSL3_TXT_ADH_DES_192_CBC_SHA "ADH-DES-CBC3-SHA" + +#if 0 + #define SSL3_TXT_FZA_DMS_NULL_SHA "FZA-NULL-SHA" + #define SSL3_TXT_FZA_DMS_FZA_SHA "FZA-FZA-CBC-SHA" + #define SSL3_TXT_FZA_DMS_RC4_SHA "FZA-RC4-SHA" +#endif + +#define SSL3_TXT_KRB5_DES_64_CBC_SHA "KRB5-DES-CBC-SHA" +#define SSL3_TXT_KRB5_DES_192_CBC3_SHA "KRB5-DES-CBC3-SHA" +#define SSL3_TXT_KRB5_RC4_128_SHA "KRB5-RC4-SHA" +#define SSL3_TXT_KRB5_IDEA_128_CBC_SHA "KRB5-IDEA-CBC-SHA" +#define SSL3_TXT_KRB5_DES_64_CBC_MD5 "KRB5-DES-CBC-MD5" +#define SSL3_TXT_KRB5_DES_192_CBC3_MD5 "KRB5-DES-CBC3-MD5" +#define SSL3_TXT_KRB5_RC4_128_MD5 "KRB5-RC4-MD5" +#define SSL3_TXT_KRB5_IDEA_128_CBC_MD5 "KRB5-IDEA-CBC-MD5" + +#define SSL3_TXT_KRB5_DES_40_CBC_SHA "EXP-KRB5-DES-CBC-SHA" +#define SSL3_TXT_KRB5_RC2_40_CBC_SHA "EXP-KRB5-RC2-CBC-SHA" +#define SSL3_TXT_KRB5_RC4_40_SHA "EXP-KRB5-RC4-SHA" +#define SSL3_TXT_KRB5_DES_40_CBC_MD5 "EXP-KRB5-DES-CBC-MD5" +#define SSL3_TXT_KRB5_RC2_40_CBC_MD5 "EXP-KRB5-RC2-CBC-MD5" +#define SSL3_TXT_KRB5_RC4_40_MD5 "EXP-KRB5-RC4-MD5" + +#define SSL3_SSL_SESSION_ID_LENGTH 32 +#define SSL3_MAX_SSL_SESSION_ID_LENGTH 32 + +#define SSL3_MASTER_SECRET_SIZE 48 +#define SSL3_RANDOM_SIZE 32 +#define SSL3_SESSION_ID_SIZE 32 +#define SSL3_RT_HEADER_LENGTH 5 + +#ifndef SSL3_ALIGN_PAYLOAD + /* Some will argue that this increases memory footprint, but it's + * not actually true. Point is that malloc has to return at least + * 64-bit aligned pointers, meaning that allocating 5 bytes wastes + * 3 bytes in either case. Suggested pre-gaping simply moves these + * wasted bytes from the end of allocated region to its front, + * but makes data payload aligned, which improves performance:-) */ +# define SSL3_ALIGN_PAYLOAD 8 +#else +# if (SSL3_ALIGN_PAYLOAD&(SSL3_ALIGN_PAYLOAD-1))!=0 +# error "insane SSL3_ALIGN_PAYLOAD" +# undef SSL3_ALIGN_PAYLOAD +# endif +#endif + +/* This is the maximum MAC (digest) size used by the SSL library. + * Currently maximum of 20 is used by SHA1, but we reserve for + * future extension for 512-bit hashes. + */ + +#define SSL3_RT_MAX_MD_SIZE 64 + +/* Maximum block size used in all ciphersuites. Currently 16 for AES. + */ + +#define SSL_RT_MAX_CIPHER_BLOCK_SIZE 16 + +#define SSL3_RT_MAX_EXTRA (16384) + +/* Maximum plaintext length: defined by SSL/TLS standards */ +#define SSL3_RT_MAX_PLAIN_LENGTH 16384 +/* Maximum compression overhead: defined by SSL/TLS standards */ +#define SSL3_RT_MAX_COMPRESSED_OVERHEAD 1024 + +/* The standards give a maximum encryption overhead of 1024 bytes. + * In practice the value is lower than this. The overhead is the maximum + * number of padding bytes (256) plus the mac size. + */ +#define SSL3_RT_MAX_ENCRYPTED_OVERHEAD (256 + SSL3_RT_MAX_MD_SIZE) + +/* OpenSSL currently only uses a padding length of at most one block so + * the send overhead is smaller. + */ + +#define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \ + (SSL_RT_MAX_CIPHER_BLOCK_SIZE + SSL3_RT_MAX_MD_SIZE) + +/* If compression isn't used don't include the compression overhead */ + +#ifdef OPENSSL_NO_COMP +#define SSL3_RT_MAX_COMPRESSED_LENGTH SSL3_RT_MAX_PLAIN_LENGTH +#else +#define SSL3_RT_MAX_COMPRESSED_LENGTH \ + (SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD) +#endif +#define SSL3_RT_MAX_ENCRYPTED_LENGTH \ + (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH) +#define SSL3_RT_MAX_PACKET_SIZE \ + (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH) + +#define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54" +#define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52" + +#define SSL3_VERSION 0x0300 +#define SSL3_VERSION_MAJOR 0x03 +#define SSL3_VERSION_MINOR 0x00 + +#define SSL3_RT_CHANGE_CIPHER_SPEC 20 +#define SSL3_RT_ALERT 21 +#define SSL3_RT_HANDSHAKE 22 +#define SSL3_RT_APPLICATION_DATA 23 + +#define SSL3_AL_WARNING 1 +#define SSL3_AL_FATAL 2 + +#define SSL3_AD_CLOSE_NOTIFY 0 +#define SSL3_AD_UNEXPECTED_MESSAGE 10 /* fatal */ +#define SSL3_AD_BAD_RECORD_MAC 20 /* fatal */ +#define SSL3_AD_DECOMPRESSION_FAILURE 30 /* fatal */ +#define SSL3_AD_HANDSHAKE_FAILURE 40 /* fatal */ +#define SSL3_AD_NO_CERTIFICATE 41 +#define SSL3_AD_BAD_CERTIFICATE 42 +#define SSL3_AD_UNSUPPORTED_CERTIFICATE 43 +#define SSL3_AD_CERTIFICATE_REVOKED 44 +#define SSL3_AD_CERTIFICATE_EXPIRED 45 +#define SSL3_AD_CERTIFICATE_UNKNOWN 46 +#define SSL3_AD_ILLEGAL_PARAMETER 47 /* fatal */ + +typedef struct ssl3_record_st + { +/*r */ int type; /* type of record */ +/*rw*/ unsigned int length; /* How many bytes available */ +/*r */ unsigned int off; /* read/write offset into 'buf' */ +/*rw*/ unsigned char *data; /* pointer to the record data */ +/*rw*/ unsigned char *input; /* where the decode bytes are */ +/*r */ unsigned char *comp; /* only used with decompression - malloc()ed */ +/*r */ unsigned long epoch; /* epoch number, needed by DTLS1 */ +/*r */ unsigned char seq_num[8]; /* sequence number, needed by DTLS1 */ + } SSL3_RECORD; + +typedef struct ssl3_buffer_st + { + unsigned char *buf; /* at least SSL3_RT_MAX_PACKET_SIZE bytes, + * see ssl3_setup_buffers() */ + size_t len; /* buffer size */ + int offset; /* where to 'copy from' */ + int left; /* how many bytes left */ + } SSL3_BUFFER; + +#define SSL3_CT_RSA_SIGN 1 +#define SSL3_CT_DSS_SIGN 2 +#define SSL3_CT_RSA_FIXED_DH 3 +#define SSL3_CT_DSS_FIXED_DH 4 +#define SSL3_CT_RSA_EPHEMERAL_DH 5 +#define SSL3_CT_DSS_EPHEMERAL_DH 6 +#define SSL3_CT_FORTEZZA_DMS 20 +/* SSL3_CT_NUMBER is used to size arrays and it must be large + * enough to contain all of the cert types defined either for + * SSLv3 and TLSv1. + */ +#define SSL3_CT_NUMBER 9 + + +#define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001 +#define SSL3_FLAGS_DELAY_CLIENT_FINISHED 0x0002 +#define SSL3_FLAGS_POP_BUFFER 0x0004 +#define TLS1_FLAGS_TLS_PADDING_BUG 0x0008 +#define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010 + +typedef struct ssl3_state_st + { + long flags; + int delay_buf_pop_ret; + + unsigned char read_sequence[8]; + int read_mac_secret_size; + unsigned char read_mac_secret[EVP_MAX_MD_SIZE]; + unsigned char write_sequence[8]; + int write_mac_secret_size; + unsigned char write_mac_secret[EVP_MAX_MD_SIZE]; + + unsigned char server_random[SSL3_RANDOM_SIZE]; + unsigned char client_random[SSL3_RANDOM_SIZE]; + + /* flags for countermeasure against known-IV weakness */ + int need_empty_fragments; + int empty_fragment_done; + + /* The value of 'extra' when the buffers were initialized */ + int init_extra; + + SSL3_BUFFER rbuf; /* read IO goes into here */ + SSL3_BUFFER wbuf; /* write IO goes into here */ + + SSL3_RECORD rrec; /* each decoded record goes in here */ + SSL3_RECORD wrec; /* goes out from here */ + + /* storage for Alert/Handshake protocol data received but not + * yet processed by ssl3_read_bytes: */ + unsigned char alert_fragment[2]; + unsigned int alert_fragment_len; + unsigned char handshake_fragment[4]; + unsigned int handshake_fragment_len; + + /* partial write - check the numbers match */ + unsigned int wnum; /* number of bytes sent so far */ + int wpend_tot; /* number bytes written */ + int wpend_type; + int wpend_ret; /* number of bytes submitted */ + const unsigned char *wpend_buf; + + /* used during startup, digest all incoming/outgoing packets */ + BIO *handshake_buffer; + /* When set of handshake digests is determined, buffer is hashed + * and freed and MD_CTX-es for all required digests are stored in + * this array */ + EVP_MD_CTX **handshake_dgst; + /* this is set whenerver we see a change_cipher_spec message + * come in when we are not looking for one */ + int change_cipher_spec; + + int warn_alert; + int fatal_alert; + /* we allow one fatal and one warning alert to be outstanding, + * send close alert via the warning alert */ + int alert_dispatch; + unsigned char send_alert[2]; + + /* This flag is set when we should renegotiate ASAP, basically when + * there is no more data in the read or write buffers */ + int renegotiate; + int total_renegotiations; + int num_renegotiations; + + int in_read_app_data; + + /* Opaque PRF input as used for the current handshake. + * These fields are used only if TLSEXT_TYPE_opaque_prf_input is defined + * (otherwise, they are merely present to improve binary compatibility) */ + void *client_opaque_prf_input; + size_t client_opaque_prf_input_len; + void *server_opaque_prf_input; + size_t server_opaque_prf_input_len; + + struct { + /* actually only needs to be 16+20 */ + unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2]; + + /* actually only need to be 16+20 for SSLv3 and 12 for TLS */ + unsigned char finish_md[EVP_MAX_MD_SIZE*2]; + int finish_md_len; + unsigned char peer_finish_md[EVP_MAX_MD_SIZE*2]; + int peer_finish_md_len; + + unsigned long message_size; + int message_type; + + /* used to hold the new cipher we are going to use */ + const SSL_CIPHER *new_cipher; +#ifndef OPENSSL_NO_DH + DH *dh; +#endif + +#ifndef OPENSSL_NO_ECDH + EC_KEY *ecdh; /* holds short lived ECDH key */ +#endif + + /* used when SSL_ST_FLUSH_DATA is entered */ + int next_state; + + int reuse_message; + + /* used for certificate requests */ + int cert_req; + int ctype_num; + char ctype[SSL3_CT_NUMBER]; + STACK_OF(X509_NAME) *ca_names; + + int use_rsa_tmp; + + int key_block_length; + unsigned char *key_block; + + const EVP_CIPHER *new_sym_enc; + const EVP_MD *new_hash; + int new_mac_pkey_type; + int new_mac_secret_size; +#ifndef OPENSSL_NO_COMP + const SSL_COMP *new_compression; +#else + char *new_compression; +#endif + int cert_request; + } tmp; + + /* Connection binding to prevent renegotiation attacks */ + unsigned char previous_client_finished[EVP_MAX_MD_SIZE]; + unsigned char previous_client_finished_len; + unsigned char previous_server_finished[EVP_MAX_MD_SIZE]; + unsigned char previous_server_finished_len; + int send_connection_binding; /* TODOEKR */ + } SSL3_STATE; + + +/* SSLv3 */ +/*client */ +/* extra state */ +#define SSL3_ST_CW_FLUSH (0x100|SSL_ST_CONNECT) +/* write to server */ +#define SSL3_ST_CW_CLNT_HELLO_A (0x110|SSL_ST_CONNECT) +#define SSL3_ST_CW_CLNT_HELLO_B (0x111|SSL_ST_CONNECT) +/* read from server */ +#define SSL3_ST_CR_SRVR_HELLO_A (0x120|SSL_ST_CONNECT) +#define SSL3_ST_CR_SRVR_HELLO_B (0x121|SSL_ST_CONNECT) +#define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A (0x126|SSL_ST_CONNECT) +#define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B (0x127|SSL_ST_CONNECT) +#define SSL3_ST_CR_CERT_A (0x130|SSL_ST_CONNECT) +#define SSL3_ST_CR_CERT_B (0x131|SSL_ST_CONNECT) +#define SSL3_ST_CR_KEY_EXCH_A (0x140|SSL_ST_CONNECT) +#define SSL3_ST_CR_KEY_EXCH_B (0x141|SSL_ST_CONNECT) +#define SSL3_ST_CR_CERT_REQ_A (0x150|SSL_ST_CONNECT) +#define SSL3_ST_CR_CERT_REQ_B (0x151|SSL_ST_CONNECT) +#define SSL3_ST_CR_SRVR_DONE_A (0x160|SSL_ST_CONNECT) +#define SSL3_ST_CR_SRVR_DONE_B (0x161|SSL_ST_CONNECT) +/* write to server */ +#define SSL3_ST_CW_CERT_A (0x170|SSL_ST_CONNECT) +#define SSL3_ST_CW_CERT_B (0x171|SSL_ST_CONNECT) +#define SSL3_ST_CW_CERT_C (0x172|SSL_ST_CONNECT) +#define SSL3_ST_CW_CERT_D (0x173|SSL_ST_CONNECT) +#define SSL3_ST_CW_KEY_EXCH_A (0x180|SSL_ST_CONNECT) +#define SSL3_ST_CW_KEY_EXCH_B (0x181|SSL_ST_CONNECT) +#define SSL3_ST_CW_CERT_VRFY_A (0x190|SSL_ST_CONNECT) +#define SSL3_ST_CW_CERT_VRFY_B (0x191|SSL_ST_CONNECT) +#define SSL3_ST_CW_CHANGE_A (0x1A0|SSL_ST_CONNECT) +#define SSL3_ST_CW_CHANGE_B (0x1A1|SSL_ST_CONNECT) +#define SSL3_ST_CW_FINISHED_A (0x1B0|SSL_ST_CONNECT) +#define SSL3_ST_CW_FINISHED_B (0x1B1|SSL_ST_CONNECT) +/* read from server */ +#define SSL3_ST_CR_CHANGE_A (0x1C0|SSL_ST_CONNECT) +#define SSL3_ST_CR_CHANGE_B (0x1C1|SSL_ST_CONNECT) +#define SSL3_ST_CR_FINISHED_A (0x1D0|SSL_ST_CONNECT) +#define SSL3_ST_CR_FINISHED_B (0x1D1|SSL_ST_CONNECT) +#define SSL3_ST_CR_SESSION_TICKET_A (0x1E0|SSL_ST_CONNECT) +#define SSL3_ST_CR_SESSION_TICKET_B (0x1E1|SSL_ST_CONNECT) +#define SSL3_ST_CR_CERT_STATUS_A (0x1F0|SSL_ST_CONNECT) +#define SSL3_ST_CR_CERT_STATUS_B (0x1F1|SSL_ST_CONNECT) + +/* server */ +/* extra state */ +#define SSL3_ST_SW_FLUSH (0x100|SSL_ST_ACCEPT) +/* read from client */ +/* Do not change the number values, they do matter */ +#define SSL3_ST_SR_CLNT_HELLO_A (0x110|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT) +/* write to client */ +#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT) +#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT) +#define SSL3_ST_SW_HELLO_REQ_A (0x120|SSL_ST_ACCEPT) +#define SSL3_ST_SW_HELLO_REQ_B (0x121|SSL_ST_ACCEPT) +#define SSL3_ST_SW_HELLO_REQ_C (0x122|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SRVR_HELLO_A (0x130|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SRVR_HELLO_B (0x131|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CERT_A (0x140|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CERT_B (0x141|SSL_ST_ACCEPT) +#define SSL3_ST_SW_KEY_EXCH_A (0x150|SSL_ST_ACCEPT) +#define SSL3_ST_SW_KEY_EXCH_B (0x151|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CERT_REQ_A (0x160|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CERT_REQ_B (0x161|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SRVR_DONE_A (0x170|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SRVR_DONE_B (0x171|SSL_ST_ACCEPT) +/* read from client */ +#define SSL3_ST_SR_CERT_A (0x180|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CERT_B (0x181|SSL_ST_ACCEPT) +#define SSL3_ST_SR_KEY_EXCH_A (0x190|SSL_ST_ACCEPT) +#define SSL3_ST_SR_KEY_EXCH_B (0x191|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CERT_VRFY_A (0x1A0|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CERT_VRFY_B (0x1A1|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CHANGE_A (0x1B0|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CHANGE_B (0x1B1|SSL_ST_ACCEPT) +#define SSL3_ST_SR_FINISHED_A (0x1C0|SSL_ST_ACCEPT) +#define SSL3_ST_SR_FINISHED_B (0x1C1|SSL_ST_ACCEPT) +/* write to client */ +#define SSL3_ST_SW_CHANGE_A (0x1D0|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CHANGE_B (0x1D1|SSL_ST_ACCEPT) +#define SSL3_ST_SW_FINISHED_A (0x1E0|SSL_ST_ACCEPT) +#define SSL3_ST_SW_FINISHED_B (0x1E1|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SESSION_TICKET_A (0x1F0|SSL_ST_ACCEPT) +#define SSL3_ST_SW_SESSION_TICKET_B (0x1F1|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CERT_STATUS_A (0x200|SSL_ST_ACCEPT) +#define SSL3_ST_SW_CERT_STATUS_B (0x201|SSL_ST_ACCEPT) + +#define SSL3_MT_HELLO_REQUEST 0 +#define SSL3_MT_CLIENT_HELLO 1 +#define SSL3_MT_SERVER_HELLO 2 +#define SSL3_MT_NEWSESSION_TICKET 4 +#define SSL3_MT_CERTIFICATE 11 +#define SSL3_MT_SERVER_KEY_EXCHANGE 12 +#define SSL3_MT_CERTIFICATE_REQUEST 13 +#define SSL3_MT_SERVER_DONE 14 +#define SSL3_MT_CERTIFICATE_VERIFY 15 +#define SSL3_MT_CLIENT_KEY_EXCHANGE 16 +#define SSL3_MT_FINISHED 20 +#define SSL3_MT_CERTIFICATE_STATUS 22 +#define DTLS1_MT_HELLO_VERIFY_REQUEST 3 + + +#define SSL3_MT_CCS 1 + +/* These are used when changing over to a new cipher */ +#define SSL3_CC_READ 0x01 +#define SSL3_CC_WRITE 0x02 +#define SSL3_CC_CLIENT 0x10 +#define SSL3_CC_SERVER 0x20 +#define SSL3_CHANGE_CIPHER_CLIENT_WRITE (SSL3_CC_CLIENT|SSL3_CC_WRITE) +#define SSL3_CHANGE_CIPHER_SERVER_READ (SSL3_CC_SERVER|SSL3_CC_READ) +#define SSL3_CHANGE_CIPHER_CLIENT_READ (SSL3_CC_CLIENT|SSL3_CC_READ) +#define SSL3_CHANGE_CIPHER_SERVER_WRITE (SSL3_CC_SERVER|SSL3_CC_WRITE) + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/extra_lib/include/openssl/stack.h b/extra_lib/include/openssl/stack.h new file mode 100644 index 0000000..ce35e55 --- /dev/null +++ b/extra_lib/include/openssl/stack.h @@ -0,0 +1,108 @@ +/* crypto/stack/stack.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_STACK_H +#define HEADER_STACK_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct stack_st + { + int num; + char **data; + int sorted; + + int num_alloc; + int (*comp)(const void *, const void *); + } _STACK; /* Use STACK_OF(...) instead */ + +#define M_sk_num(sk) ((sk) ? (sk)->num:-1) +#define M_sk_value(sk,n) ((sk) ? (sk)->data[n] : NULL) + +int sk_num(const _STACK *); +void *sk_value(const _STACK *, int); + +void *sk_set(_STACK *, int, void *); + +_STACK *sk_new(int (*cmp)(const void *, const void *)); +_STACK *sk_new_null(void); +void sk_free(_STACK *); +void sk_pop_free(_STACK *st, void (*func)(void *)); +int sk_insert(_STACK *sk, void *data, int where); +void *sk_delete(_STACK *st, int loc); +void *sk_delete_ptr(_STACK *st, void *p); +int sk_find(_STACK *st, void *data); +int sk_find_ex(_STACK *st, void *data); +int sk_push(_STACK *st, void *data); +int sk_unshift(_STACK *st, void *data); +void *sk_shift(_STACK *st); +void *sk_pop(_STACK *st); +void sk_zero(_STACK *st); +int (*sk_set_cmp_func(_STACK *sk, int (*c)(const void *, const void *))) + (const void *, const void *); +_STACK *sk_dup(_STACK *st); +void sk_sort(_STACK *st); +int sk_is_sorted(const _STACK *st); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/extra_lib/include/openssl/symhacks.h b/extra_lib/include/openssl/symhacks.h new file mode 100644 index 0000000..3fd4a81 --- /dev/null +++ b/extra_lib/include/openssl/symhacks.h @@ -0,0 +1,449 @@ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_SYMHACKS_H +#define HEADER_SYMHACKS_H + +#include + +/* Hacks to solve the problem with linkers incapable of handling very long + symbol names. In the case of VMS, the limit is 31 characters on VMS for + VAX. */ +/* Note that this affects util/libeay.num and util/ssleay.num... you may + change those manually, but that's not recommended, as those files are + controlled centrally and updated on Unix, and the central definition + may disagree with yours, which in turn may come with shareable library + incompatibilities. */ +#ifdef OPENSSL_SYS_VMS + +/* Hack a long name in crypto/ex_data.c */ +#undef CRYPTO_get_ex_data_implementation +#define CRYPTO_get_ex_data_implementation CRYPTO_get_ex_data_impl +#undef CRYPTO_set_ex_data_implementation +#define CRYPTO_set_ex_data_implementation CRYPTO_set_ex_data_impl + +/* Hack a long name in crypto/asn1/a_mbstr.c */ +#undef ASN1_STRING_set_default_mask_asc +#define ASN1_STRING_set_default_mask_asc ASN1_STRING_set_def_mask_asc + +#if 0 /* No longer needed, since safestack macro magic does the job */ +/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO) */ +#undef i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO +#define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO i2d_ASN1_SET_OF_PKCS7_SIGINF +#undef d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO +#define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO d2i_ASN1_SET_OF_PKCS7_SIGINF +#endif + +#if 0 /* No longer needed, since safestack macro magic does the job */ +/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO) */ +#undef i2d_ASN1_SET_OF_PKCS7_RECIP_INFO +#define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO i2d_ASN1_SET_OF_PKCS7_RECINF +#undef d2i_ASN1_SET_OF_PKCS7_RECIP_INFO +#define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO d2i_ASN1_SET_OF_PKCS7_RECINF +#endif + +#if 0 /* No longer needed, since safestack macro magic does the job */ +/* Hack the names created with DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) */ +#undef i2d_ASN1_SET_OF_ACCESS_DESCRIPTION +#define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION i2d_ASN1_SET_OF_ACC_DESC +#undef d2i_ASN1_SET_OF_ACCESS_DESCRIPTION +#define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION d2i_ASN1_SET_OF_ACC_DESC +#endif + +/* Hack the names created with DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE) */ +#undef PEM_read_NETSCAPE_CERT_SEQUENCE +#define PEM_read_NETSCAPE_CERT_SEQUENCE PEM_read_NS_CERT_SEQ +#undef PEM_write_NETSCAPE_CERT_SEQUENCE +#define PEM_write_NETSCAPE_CERT_SEQUENCE PEM_write_NS_CERT_SEQ +#undef PEM_read_bio_NETSCAPE_CERT_SEQUENCE +#define PEM_read_bio_NETSCAPE_CERT_SEQUENCE PEM_read_bio_NS_CERT_SEQ +#undef PEM_write_bio_NETSCAPE_CERT_SEQUENCE +#define PEM_write_bio_NETSCAPE_CERT_SEQUENCE PEM_write_bio_NS_CERT_SEQ +#undef PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE +#define PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE PEM_write_cb_bio_NS_CERT_SEQ + +/* Hack the names created with DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO) */ +#undef PEM_read_PKCS8_PRIV_KEY_INFO +#define PEM_read_PKCS8_PRIV_KEY_INFO PEM_read_P8_PRIV_KEY_INFO +#undef PEM_write_PKCS8_PRIV_KEY_INFO +#define PEM_write_PKCS8_PRIV_KEY_INFO PEM_write_P8_PRIV_KEY_INFO +#undef PEM_read_bio_PKCS8_PRIV_KEY_INFO +#define PEM_read_bio_PKCS8_PRIV_KEY_INFO PEM_read_bio_P8_PRIV_KEY_INFO +#undef PEM_write_bio_PKCS8_PRIV_KEY_INFO +#define PEM_write_bio_PKCS8_PRIV_KEY_INFO PEM_write_bio_P8_PRIV_KEY_INFO +#undef PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO +#define PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO PEM_wrt_cb_bio_P8_PRIV_KEY_INFO + +/* Hack other PEM names */ +#undef PEM_write_bio_PKCS8PrivateKey_nid +#define PEM_write_bio_PKCS8PrivateKey_nid PEM_write_bio_PKCS8PrivKey_nid + +/* Hack some long X509 names */ +#undef X509_REVOKED_get_ext_by_critical +#define X509_REVOKED_get_ext_by_critical X509_REVOKED_get_ext_by_critic +#undef X509_policy_tree_get0_user_policies +#define X509_policy_tree_get0_user_policies X509_pcy_tree_get0_usr_policies +#undef X509_policy_node_get0_qualifiers +#define X509_policy_node_get0_qualifiers X509_pcy_node_get0_qualifiers +#undef X509_STORE_CTX_get_explicit_policy +#define X509_STORE_CTX_get_explicit_policy X509_STORE_CTX_get_expl_policy +#undef X509_STORE_CTX_get0_current_issuer +#define X509_STORE_CTX_get0_current_issuer X509_STORE_CTX_get0_cur_issuer + +/* Hack some long CRYPTO names */ +#undef CRYPTO_set_dynlock_destroy_callback +#define CRYPTO_set_dynlock_destroy_callback CRYPTO_set_dynlock_destroy_cb +#undef CRYPTO_set_dynlock_create_callback +#define CRYPTO_set_dynlock_create_callback CRYPTO_set_dynlock_create_cb +#undef CRYPTO_set_dynlock_lock_callback +#define CRYPTO_set_dynlock_lock_callback CRYPTO_set_dynlock_lock_cb +#undef CRYPTO_get_dynlock_lock_callback +#define CRYPTO_get_dynlock_lock_callback CRYPTO_get_dynlock_lock_cb +#undef CRYPTO_get_dynlock_destroy_callback +#define CRYPTO_get_dynlock_destroy_callback CRYPTO_get_dynlock_destroy_cb +#undef CRYPTO_get_dynlock_create_callback +#define CRYPTO_get_dynlock_create_callback CRYPTO_get_dynlock_create_cb +#undef CRYPTO_set_locked_mem_ex_functions +#define CRYPTO_set_locked_mem_ex_functions CRYPTO_set_locked_mem_ex_funcs +#undef CRYPTO_get_locked_mem_ex_functions +#define CRYPTO_get_locked_mem_ex_functions CRYPTO_get_locked_mem_ex_funcs + +/* Hack some long SSL names */ +#undef SSL_CTX_set_default_verify_paths +#define SSL_CTX_set_default_verify_paths SSL_CTX_set_def_verify_paths +#undef SSL_get_ex_data_X509_STORE_CTX_idx +#define SSL_get_ex_data_X509_STORE_CTX_idx SSL_get_ex_d_X509_STORE_CTX_idx +#undef SSL_add_file_cert_subjects_to_stack +#define SSL_add_file_cert_subjects_to_stack SSL_add_file_cert_subjs_to_stk +#undef SSL_add_dir_cert_subjects_to_stack +#define SSL_add_dir_cert_subjects_to_stack SSL_add_dir_cert_subjs_to_stk +#undef SSL_CTX_use_certificate_chain_file +#define SSL_CTX_use_certificate_chain_file SSL_CTX_use_cert_chain_file +#undef SSL_CTX_set_cert_verify_callback +#define SSL_CTX_set_cert_verify_callback SSL_CTX_set_cert_verify_cb +#undef SSL_CTX_set_default_passwd_cb_userdata +#define SSL_CTX_set_default_passwd_cb_userdata SSL_CTX_set_def_passwd_cb_ud +#undef SSL_COMP_get_compression_methods +#define SSL_COMP_get_compression_methods SSL_COMP_get_compress_methods + +#undef ssl_add_clienthello_renegotiate_ext +#define ssl_add_clienthello_renegotiate_ext ssl_add_clienthello_reneg_ext +#undef ssl_add_serverhello_renegotiate_ext +#define ssl_add_serverhello_renegotiate_ext ssl_add_serverhello_reneg_ext +#undef ssl_parse_clienthello_renegotiate_ext +#define ssl_parse_clienthello_renegotiate_ext ssl_parse_clienthello_reneg_ext +#undef ssl_parse_serverhello_renegotiate_ext +#define ssl_parse_serverhello_renegotiate_ext ssl_parse_serverhello_reneg_ext + +/* Hack some long ENGINE names */ +#undef ENGINE_get_default_BN_mod_exp_crt +#define ENGINE_get_default_BN_mod_exp_crt ENGINE_get_def_BN_mod_exp_crt +#undef ENGINE_set_default_BN_mod_exp_crt +#define ENGINE_set_default_BN_mod_exp_crt ENGINE_set_def_BN_mod_exp_crt +#undef ENGINE_set_load_privkey_function +#define ENGINE_set_load_privkey_function ENGINE_set_load_privkey_fn +#undef ENGINE_get_load_privkey_function +#define ENGINE_get_load_privkey_function ENGINE_get_load_privkey_fn +#undef ENGINE_unregister_pkey_asn1_meths +#define ENGINE_unregister_pkey_asn1_meths ENGINE_unreg_pkey_asn1_meths +#undef ENGINE_register_all_pkey_asn1_meths +#define ENGINE_register_all_pkey_asn1_meths ENGINE_reg_all_pkey_asn1_meths +#undef ENGINE_set_default_pkey_asn1_meths +#define ENGINE_set_default_pkey_asn1_meths ENGINE_set_def_pkey_asn1_meths +#undef ENGINE_get_pkey_asn1_meth_engine +#define ENGINE_get_pkey_asn1_meth_engine ENGINE_get_pkey_asn1_meth_eng +#undef ENGINE_set_load_ssl_client_cert_function +#define ENGINE_set_load_ssl_client_cert_function \ + ENGINE_set_ld_ssl_clnt_cert_fn +#undef ENGINE_get_ssl_client_cert_function +#define ENGINE_get_ssl_client_cert_function ENGINE_get_ssl_client_cert_fn + +/* Hack some long OCSP names */ +#undef OCSP_REQUEST_get_ext_by_critical +#define OCSP_REQUEST_get_ext_by_critical OCSP_REQUEST_get_ext_by_crit +#undef OCSP_BASICRESP_get_ext_by_critical +#define OCSP_BASICRESP_get_ext_by_critical OCSP_BASICRESP_get_ext_by_crit +#undef OCSP_SINGLERESP_get_ext_by_critical +#define OCSP_SINGLERESP_get_ext_by_critical OCSP_SINGLERESP_get_ext_by_crit + +/* Hack some long DES names */ +#undef _ossl_old_des_ede3_cfb64_encrypt +#define _ossl_old_des_ede3_cfb64_encrypt _ossl_odes_ede3_cfb64_encrypt +#undef _ossl_old_des_ede3_ofb64_encrypt +#define _ossl_old_des_ede3_ofb64_encrypt _ossl_odes_ede3_ofb64_encrypt + +/* Hack some long EVP names */ +#undef OPENSSL_add_all_algorithms_noconf +#define OPENSSL_add_all_algorithms_noconf OPENSSL_add_all_algo_noconf +#undef OPENSSL_add_all_algorithms_conf +#define OPENSSL_add_all_algorithms_conf OPENSSL_add_all_algo_conf +#undef EVP_PKEY_meth_set_verify_recover +#define EVP_PKEY_meth_set_verify_recover EVP_PKEY_meth_set_vrfy_recover + +/* Hack some long EC names */ +#undef EC_GROUP_set_point_conversion_form +#define EC_GROUP_set_point_conversion_form EC_GROUP_set_point_conv_form +#undef EC_GROUP_get_point_conversion_form +#define EC_GROUP_get_point_conversion_form EC_GROUP_get_point_conv_form +#undef EC_GROUP_clear_free_all_extra_data +#define EC_GROUP_clear_free_all_extra_data EC_GROUP_clr_free_all_xtra_data +#undef EC_POINT_set_Jprojective_coordinates_GFp +#define EC_POINT_set_Jprojective_coordinates_GFp \ + EC_POINT_set_Jproj_coords_GFp +#undef EC_POINT_get_Jprojective_coordinates_GFp +#define EC_POINT_get_Jprojective_coordinates_GFp \ + EC_POINT_get_Jproj_coords_GFp +#undef EC_POINT_set_affine_coordinates_GFp +#define EC_POINT_set_affine_coordinates_GFp EC_POINT_set_affine_coords_GFp +#undef EC_POINT_get_affine_coordinates_GFp +#define EC_POINT_get_affine_coordinates_GFp EC_POINT_get_affine_coords_GFp +#undef EC_POINT_set_compressed_coordinates_GFp +#define EC_POINT_set_compressed_coordinates_GFp EC_POINT_set_compr_coords_GFp +#undef EC_POINT_set_affine_coordinates_GF2m +#define EC_POINT_set_affine_coordinates_GF2m EC_POINT_set_affine_coords_GF2m +#undef EC_POINT_get_affine_coordinates_GF2m +#define EC_POINT_get_affine_coordinates_GF2m EC_POINT_get_affine_coords_GF2m +#undef EC_POINT_set_compressed_coordinates_GF2m +#define EC_POINT_set_compressed_coordinates_GF2m \ + EC_POINT_set_compr_coords_GF2m +#undef ec_GF2m_simple_group_clear_finish +#define ec_GF2m_simple_group_clear_finish ec_GF2m_simple_grp_clr_finish +#undef ec_GF2m_simple_group_check_discriminant +#define ec_GF2m_simple_group_check_discriminant ec_GF2m_simple_grp_chk_discrim +#undef ec_GF2m_simple_point_clear_finish +#define ec_GF2m_simple_point_clear_finish ec_GF2m_simple_pt_clr_finish +#undef ec_GF2m_simple_point_set_to_infinity +#define ec_GF2m_simple_point_set_to_infinity ec_GF2m_simple_pt_set_to_inf +#undef ec_GF2m_simple_points_make_affine +#define ec_GF2m_simple_points_make_affine ec_GF2m_simple_pts_make_affine +#undef ec_GF2m_simple_point_set_affine_coordinates +#define ec_GF2m_simple_point_set_affine_coordinates \ + ec_GF2m_smp_pt_set_af_coords +#undef ec_GF2m_simple_point_get_affine_coordinates +#define ec_GF2m_simple_point_get_affine_coordinates \ + ec_GF2m_smp_pt_get_af_coords +#undef ec_GF2m_simple_set_compressed_coordinates +#define ec_GF2m_simple_set_compressed_coordinates \ + ec_GF2m_smp_set_compr_coords +#undef ec_GFp_simple_group_set_curve_GFp +#define ec_GFp_simple_group_set_curve_GFp ec_GFp_simple_grp_set_curve_GFp +#undef ec_GFp_simple_group_get_curve_GFp +#define ec_GFp_simple_group_get_curve_GFp ec_GFp_simple_grp_get_curve_GFp +#undef ec_GFp_simple_group_clear_finish +#define ec_GFp_simple_group_clear_finish ec_GFp_simple_grp_clear_finish +#undef ec_GFp_simple_group_set_generator +#define ec_GFp_simple_group_set_generator ec_GFp_simple_grp_set_generator +#undef ec_GFp_simple_group_get0_generator +#define ec_GFp_simple_group_get0_generator ec_GFp_simple_grp_gt0_generator +#undef ec_GFp_simple_group_get_cofactor +#define ec_GFp_simple_group_get_cofactor ec_GFp_simple_grp_get_cofactor +#undef ec_GFp_simple_point_clear_finish +#define ec_GFp_simple_point_clear_finish ec_GFp_simple_pt_clear_finish +#undef ec_GFp_simple_point_set_to_infinity +#define ec_GFp_simple_point_set_to_infinity ec_GFp_simple_pt_set_to_inf +#undef ec_GFp_simple_points_make_affine +#define ec_GFp_simple_points_make_affine ec_GFp_simple_pts_make_affine +#undef ec_GFp_simple_group_get_curve_GFp +#define ec_GFp_simple_group_get_curve_GFp ec_GFp_simple_grp_get_curve_GFp +#undef ec_GFp_simple_set_Jprojective_coordinates_GFp +#define ec_GFp_simple_set_Jprojective_coordinates_GFp \ + ec_GFp_smp_set_Jproj_coords_GFp +#undef ec_GFp_simple_get_Jprojective_coordinates_GFp +#define ec_GFp_simple_get_Jprojective_coordinates_GFp \ + ec_GFp_smp_get_Jproj_coords_GFp +#undef ec_GFp_simple_point_set_affine_coordinates_GFp +#define ec_GFp_simple_point_set_affine_coordinates_GFp \ + ec_GFp_smp_pt_set_af_coords_GFp +#undef ec_GFp_simple_point_get_affine_coordinates_GFp +#define ec_GFp_simple_point_get_affine_coordinates_GFp \ + ec_GFp_smp_pt_get_af_coords_GFp +#undef ec_GFp_simple_set_compressed_coordinates_GFp +#define ec_GFp_simple_set_compressed_coordinates_GFp \ + ec_GFp_smp_set_compr_coords_GFp +#undef ec_GFp_simple_point_set_affine_coordinates +#define ec_GFp_simple_point_set_affine_coordinates \ + ec_GFp_smp_pt_set_af_coords +#undef ec_GFp_simple_point_get_affine_coordinates +#define ec_GFp_simple_point_get_affine_coordinates \ + ec_GFp_smp_pt_get_af_coords +#undef ec_GFp_simple_set_compressed_coordinates +#define ec_GFp_simple_set_compressed_coordinates \ + ec_GFp_smp_set_compr_coords +#undef ec_GFp_simple_group_check_discriminant +#define ec_GFp_simple_group_check_discriminant ec_GFp_simple_grp_chk_discrim + +/* Hack som long STORE names */ +#undef STORE_method_set_initialise_function +#define STORE_method_set_initialise_function STORE_meth_set_initialise_fn +#undef STORE_method_set_cleanup_function +#define STORE_method_set_cleanup_function STORE_meth_set_cleanup_fn +#undef STORE_method_set_generate_function +#define STORE_method_set_generate_function STORE_meth_set_generate_fn +#undef STORE_method_set_modify_function +#define STORE_method_set_modify_function STORE_meth_set_modify_fn +#undef STORE_method_set_revoke_function +#define STORE_method_set_revoke_function STORE_meth_set_revoke_fn +#undef STORE_method_set_delete_function +#define STORE_method_set_delete_function STORE_meth_set_delete_fn +#undef STORE_method_set_list_start_function +#define STORE_method_set_list_start_function STORE_meth_set_list_start_fn +#undef STORE_method_set_list_next_function +#define STORE_method_set_list_next_function STORE_meth_set_list_next_fn +#undef STORE_method_set_list_end_function +#define STORE_method_set_list_end_function STORE_meth_set_list_end_fn +#undef STORE_method_set_update_store_function +#define STORE_method_set_update_store_function STORE_meth_set_update_store_fn +#undef STORE_method_set_lock_store_function +#define STORE_method_set_lock_store_function STORE_meth_set_lock_store_fn +#undef STORE_method_set_unlock_store_function +#define STORE_method_set_unlock_store_function STORE_meth_set_unlock_store_fn +#undef STORE_method_get_initialise_function +#define STORE_method_get_initialise_function STORE_meth_get_initialise_fn +#undef STORE_method_get_cleanup_function +#define STORE_method_get_cleanup_function STORE_meth_get_cleanup_fn +#undef STORE_method_get_generate_function +#define STORE_method_get_generate_function STORE_meth_get_generate_fn +#undef STORE_method_get_modify_function +#define STORE_method_get_modify_function STORE_meth_get_modify_fn +#undef STORE_method_get_revoke_function +#define STORE_method_get_revoke_function STORE_meth_get_revoke_fn +#undef STORE_method_get_delete_function +#define STORE_method_get_delete_function STORE_meth_get_delete_fn +#undef STORE_method_get_list_start_function +#define STORE_method_get_list_start_function STORE_meth_get_list_start_fn +#undef STORE_method_get_list_next_function +#define STORE_method_get_list_next_function STORE_meth_get_list_next_fn +#undef STORE_method_get_list_end_function +#define STORE_method_get_list_end_function STORE_meth_get_list_end_fn +#undef STORE_method_get_update_store_function +#define STORE_method_get_update_store_function STORE_meth_get_update_store_fn +#undef STORE_method_get_lock_store_function +#define STORE_method_get_lock_store_function STORE_meth_get_lock_store_fn +#undef STORE_method_get_unlock_store_function +#define STORE_method_get_unlock_store_function STORE_meth_get_unlock_store_fn + +/* Hack some long TS names */ +#undef TS_RESP_CTX_set_status_info_cond +#define TS_RESP_CTX_set_status_info_cond TS_RESP_CTX_set_stat_info_cond +#undef TS_RESP_CTX_set_clock_precision_digits +#define TS_RESP_CTX_set_clock_precision_digits TS_RESP_CTX_set_clk_prec_digits +#undef TS_CONF_set_clock_precision_digits +#define TS_CONF_set_clock_precision_digits TS_CONF_set_clk_prec_digits + +/* Hack some long CMS names */ +#undef CMS_RecipientInfo_ktri_get0_algs +#define CMS_RecipientInfo_ktri_get0_algs CMS_RecipInfo_ktri_get0_algs +#undef CMS_RecipientInfo_ktri_get0_signer_id +#define CMS_RecipientInfo_ktri_get0_signer_id CMS_RecipInfo_ktri_get0_sigr_id +#undef CMS_OtherRevocationInfoFormat_it +#define CMS_OtherRevocationInfoFormat_it CMS_OtherRevocInfoFormat_it +#undef CMS_KeyAgreeRecipientIdentifier_it +#define CMS_KeyAgreeRecipientIdentifier_it CMS_KeyAgreeRecipIdentifier_it +#undef CMS_OriginatorIdentifierOrKey_it +#define CMS_OriginatorIdentifierOrKey_it CMS_OriginatorIdOrKey_it +#undef cms_SignerIdentifier_get0_signer_id +#define cms_SignerIdentifier_get0_signer_id cms_SignerId_get0_signer_id + +/* Hack some long DTLS1 names */ +#undef dtls1_retransmit_buffered_messages +#define dtls1_retransmit_buffered_messages dtls1_retransmit_buffered_msgs + +/* Hack some long UI names */ +#undef UI_method_get_prompt_constructor +#define UI_method_get_prompt_constructor UI_method_get_prompt_constructr +#undef UI_method_set_prompt_constructor +#define UI_method_set_prompt_constructor UI_method_set_prompt_constructr + +#endif /* defined OPENSSL_SYS_VMS */ + + +/* Case insensitive linking causes problems.... */ +#if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) +#undef ERR_load_CRYPTO_strings +#define ERR_load_CRYPTO_strings ERR_load_CRYPTOlib_strings +#undef OCSP_crlID_new +#define OCSP_crlID_new OCSP_crlID2_new + +#undef d2i_ECPARAMETERS +#define d2i_ECPARAMETERS d2i_UC_ECPARAMETERS +#undef i2d_ECPARAMETERS +#define i2d_ECPARAMETERS i2d_UC_ECPARAMETERS +#undef d2i_ECPKPARAMETERS +#define d2i_ECPKPARAMETERS d2i_UC_ECPKPARAMETERS +#undef i2d_ECPKPARAMETERS +#define i2d_ECPKPARAMETERS i2d_UC_ECPKPARAMETERS + +/* These functions do not seem to exist! However, I'm paranoid... + Original command in x509v3.h: + These functions are being redefined in another directory, + and clash when the linker is case-insensitive, so let's + hide them a little, by giving them an extra 'o' at the + beginning of the name... */ +#undef X509v3_cleanup_extensions +#define X509v3_cleanup_extensions oX509v3_cleanup_extensions +#undef X509v3_add_extension +#define X509v3_add_extension oX509v3_add_extension +#undef X509v3_add_netscape_extensions +#define X509v3_add_netscape_extensions oX509v3_add_netscape_extensions +#undef X509v3_add_standard_extensions +#define X509v3_add_standard_extensions oX509v3_add_standard_extensions + +/* This one clashes with CMS_data_create */ +#undef cms_Data_create +#define cms_Data_create priv_cms_Data_create + +#endif + + +#endif /* ! defined HEADER_VMS_IDHACKS_H */ diff --git a/extra_lib/include/openssl/tls1.h b/extra_lib/include/openssl/tls1.h new file mode 100644 index 0000000..b3cc8f0 --- /dev/null +++ b/extra_lib/include/openssl/tls1.h @@ -0,0 +1,532 @@ +/* ssl/tls1.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef HEADER_TLS1_H +#define HEADER_TLS1_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES 0 + +#define TLS1_VERSION 0x0301 +#define TLS1_VERSION_MAJOR 0x03 +#define TLS1_VERSION_MINOR 0x01 + +#define TLS1_AD_DECRYPTION_FAILED 21 +#define TLS1_AD_RECORD_OVERFLOW 22 +#define TLS1_AD_UNKNOWN_CA 48 /* fatal */ +#define TLS1_AD_ACCESS_DENIED 49 /* fatal */ +#define TLS1_AD_DECODE_ERROR 50 /* fatal */ +#define TLS1_AD_DECRYPT_ERROR 51 +#define TLS1_AD_EXPORT_RESTRICTION 60 /* fatal */ +#define TLS1_AD_PROTOCOL_VERSION 70 /* fatal */ +#define TLS1_AD_INSUFFICIENT_SECURITY 71 /* fatal */ +#define TLS1_AD_INTERNAL_ERROR 80 /* fatal */ +#define TLS1_AD_USER_CANCELLED 90 +#define TLS1_AD_NO_RENEGOTIATION 100 +/* codes 110-114 are from RFC3546 */ +#define TLS1_AD_UNSUPPORTED_EXTENSION 110 +#define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111 +#define TLS1_AD_UNRECOGNIZED_NAME 112 +#define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 +#define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 +#define TLS1_AD_UNKNOWN_PSK_IDENTITY 115 /* fatal */ + +/* ExtensionType values from RFC3546 / RFC4366 */ +#define TLSEXT_TYPE_server_name 0 +#define TLSEXT_TYPE_max_fragment_length 1 +#define TLSEXT_TYPE_client_certificate_url 2 +#define TLSEXT_TYPE_trusted_ca_keys 3 +#define TLSEXT_TYPE_truncated_hmac 4 +#define TLSEXT_TYPE_status_request 5 +/* ExtensionType values from RFC4492 */ +#define TLSEXT_TYPE_elliptic_curves 10 +#define TLSEXT_TYPE_ec_point_formats 11 +#define TLSEXT_TYPE_session_ticket 35 +/* ExtensionType value from draft-rescorla-tls-opaque-prf-input-00.txt */ +#if 0 /* will have to be provided externally for now , + * i.e. build with -DTLSEXT_TYPE_opaque_prf_input=38183 + * using whatever extension number you'd like to try */ +# define TLSEXT_TYPE_opaque_prf_input ?? */ +#endif + +/* Temporary extension type */ +#define TLSEXT_TYPE_renegotiate 0xff01 + +/* NameType value from RFC 3546 */ +#define TLSEXT_NAMETYPE_host_name 0 +/* status request value from RFC 3546 */ +#define TLSEXT_STATUSTYPE_ocsp 1 + +/* ECPointFormat values from draft-ietf-tls-ecc-12 */ +#define TLSEXT_ECPOINTFORMAT_first 0 +#define TLSEXT_ECPOINTFORMAT_uncompressed 0 +#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime 1 +#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 2 +#define TLSEXT_ECPOINTFORMAT_last 2 + +#ifndef OPENSSL_NO_TLSEXT + +#define TLSEXT_MAXLEN_host_name 255 + +const char *SSL_get_servername(const SSL *s, const int type) ; +int SSL_get_servername_type(const SSL *s) ; + +#define SSL_set_tlsext_host_name(s,name) \ +SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name) + +#define SSL_set_tlsext_debug_callback(ssl, cb) \ +SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,(void (*)(void))cb) + +#define SSL_set_tlsext_debug_arg(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0, (void *)arg) + +#define SSL_set_tlsext_status_type(ssl, type) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type, NULL) + +#define SSL_get_tlsext_status_exts(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg) + +#define SSL_set_tlsext_status_exts(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg) + +#define SSL_get_tlsext_status_ids(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg) + +#define SSL_set_tlsext_status_ids(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg) + +#define SSL_get_tlsext_status_ocsp_resp(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP,0, (void *)arg) + +#define SSL_set_tlsext_status_ocsp_resp(ssl, arg, arglen) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,arglen, (void *)arg) + +#define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \ +SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,(void (*)(void))cb) + +#define SSL_TLSEXT_ERR_OK 0 +#define SSL_TLSEXT_ERR_ALERT_WARNING 1 +#define SSL_TLSEXT_ERR_ALERT_FATAL 2 +#define SSL_TLSEXT_ERR_NOACK 3 + +#define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \ +SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0, (void *)arg) + +#define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_GET_TLSEXT_TICKET_KEYS,(keylen),(keys)) +#define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_SET_TLSEXT_TICKET_KEYS,(keylen),(keys)) + +#define SSL_CTX_set_tlsext_status_cb(ssl, cb) \ +SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,(void (*)(void))cb) + +#define SSL_CTX_set_tlsext_status_arg(ssl, arg) \ +SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0, (void *)arg) + +#define SSL_set_tlsext_opaque_prf_input(s, src, len) \ +SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT, len, src) +#define SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb) \ +SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB, (void (*)(void))cb) +#define SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg) \ +SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg) + +#define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \ +SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) + +#endif + +/* PSK ciphersuites from 4279 */ +#define TLS1_CK_PSK_WITH_RC4_128_SHA 0x0300008A +#define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA 0x0300008B +#define TLS1_CK_PSK_WITH_AES_128_CBC_SHA 0x0300008C +#define TLS1_CK_PSK_WITH_AES_256_CBC_SHA 0x0300008D + +/* Additional TLS ciphersuites from expired Internet Draft + * draft-ietf-tls-56-bit-ciphersuites-01.txt + * (available if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see + * s3_lib.c). We actually treat them like SSL 3.0 ciphers, which we probably + * shouldn't. Note that the first two are actually not in the IDs. */ +#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5 0x03000060 /* not in ID */ +#define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 0x03000061 /* not in ID */ +#define TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA 0x03000062 +#define TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA 0x03000063 +#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA 0x03000064 +#define TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA 0x03000065 +#define TLS1_CK_DHE_DSS_WITH_RC4_128_SHA 0x03000066 + +/* AES ciphersuites from RFC3268 */ + +#define TLS1_CK_RSA_WITH_AES_128_SHA 0x0300002F +#define TLS1_CK_DH_DSS_WITH_AES_128_SHA 0x03000030 +#define TLS1_CK_DH_RSA_WITH_AES_128_SHA 0x03000031 +#define TLS1_CK_DHE_DSS_WITH_AES_128_SHA 0x03000032 +#define TLS1_CK_DHE_RSA_WITH_AES_128_SHA 0x03000033 +#define TLS1_CK_ADH_WITH_AES_128_SHA 0x03000034 + +#define TLS1_CK_RSA_WITH_AES_256_SHA 0x03000035 +#define TLS1_CK_DH_DSS_WITH_AES_256_SHA 0x03000036 +#define TLS1_CK_DH_RSA_WITH_AES_256_SHA 0x03000037 +#define TLS1_CK_DHE_DSS_WITH_AES_256_SHA 0x03000038 +#define TLS1_CK_DHE_RSA_WITH_AES_256_SHA 0x03000039 +#define TLS1_CK_ADH_WITH_AES_256_SHA 0x0300003A + +/* Camellia ciphersuites from RFC4132 */ +#define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000041 +#define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000042 +#define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000043 +#define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000044 +#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000045 +#define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA 0x03000046 + +#define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000084 +#define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000085 +#define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000086 +#define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000087 +#define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000088 +#define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA 0x03000089 + +/* SEED ciphersuites from RFC4162 */ +#define TLS1_CK_RSA_WITH_SEED_SHA 0x03000096 +#define TLS1_CK_DH_DSS_WITH_SEED_SHA 0x03000097 +#define TLS1_CK_DH_RSA_WITH_SEED_SHA 0x03000098 +#define TLS1_CK_DHE_DSS_WITH_SEED_SHA 0x03000099 +#define TLS1_CK_DHE_RSA_WITH_SEED_SHA 0x0300009A +#define TLS1_CK_ADH_WITH_SEED_SHA 0x0300009B + +/* ECC ciphersuites from draft-ietf-tls-ecc-12.txt with changes soon to be in draft 13 */ +#define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA 0x0300C001 +#define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA 0x0300C002 +#define TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C003 +#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0x0300C004 +#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0x0300C005 + +#define TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA 0x0300C006 +#define TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA 0x0300C007 +#define TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C008 +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0x0300C009 +#define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0x0300C00A + +#define TLS1_CK_ECDH_RSA_WITH_NULL_SHA 0x0300C00B +#define TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA 0x0300C00C +#define TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA 0x0300C00D +#define TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA 0x0300C00E +#define TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA 0x0300C00F + +#define TLS1_CK_ECDHE_RSA_WITH_NULL_SHA 0x0300C010 +#define TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA 0x0300C011 +#define TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA 0x0300C012 +#define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA 0x0300C013 +#define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA 0x0300C014 + +#define TLS1_CK_ECDH_anon_WITH_NULL_SHA 0x0300C015 +#define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA 0x0300C016 +#define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA 0x0300C017 +#define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA 0x0300C018 +#define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA 0x0300C019 + +/* XXX + * Inconsistency alert: + * The OpenSSL names of ciphers with ephemeral DH here include the string + * "DHE", while elsewhere it has always been "EDH". + * (The alias for the list of all such ciphers also is "EDH".) + * The specifications speak of "EDH"; maybe we should allow both forms + * for everything. */ +#define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5 "EXP1024-RC4-MD5" +#define TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 "EXP1024-RC2-CBC-MD5" +#define TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA "EXP1024-DES-CBC-SHA" +#define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA "EXP1024-DHE-DSS-DES-CBC-SHA" +#define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA "EXP1024-RC4-SHA" +#define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA "EXP1024-DHE-DSS-RC4-SHA" +#define TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA "DHE-DSS-RC4-SHA" + +/* AES ciphersuites from RFC3268 */ +#define TLS1_TXT_RSA_WITH_AES_128_SHA "AES128-SHA" +#define TLS1_TXT_DH_DSS_WITH_AES_128_SHA "DH-DSS-AES128-SHA" +#define TLS1_TXT_DH_RSA_WITH_AES_128_SHA "DH-RSA-AES128-SHA" +#define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA "DHE-DSS-AES128-SHA" +#define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA "DHE-RSA-AES128-SHA" +#define TLS1_TXT_ADH_WITH_AES_128_SHA "ADH-AES128-SHA" + +#define TLS1_TXT_RSA_WITH_AES_256_SHA "AES256-SHA" +#define TLS1_TXT_DH_DSS_WITH_AES_256_SHA "DH-DSS-AES256-SHA" +#define TLS1_TXT_DH_RSA_WITH_AES_256_SHA "DH-RSA-AES256-SHA" +#define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA "DHE-DSS-AES256-SHA" +#define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA "DHE-RSA-AES256-SHA" +#define TLS1_TXT_ADH_WITH_AES_256_SHA "ADH-AES256-SHA" + +/* ECC ciphersuites from draft-ietf-tls-ecc-01.txt (Mar 15, 2001) */ +#define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA "ECDH-ECDSA-NULL-SHA" +#define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA "ECDH-ECDSA-RC4-SHA" +#define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA "ECDH-ECDSA-DES-CBC3-SHA" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA "ECDH-ECDSA-AES128-SHA" +#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA "ECDH-ECDSA-AES256-SHA" + +#define TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA "ECDHE-ECDSA-NULL-SHA" +#define TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA "ECDHE-ECDSA-RC4-SHA" +#define TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA "ECDHE-ECDSA-DES-CBC3-SHA" +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA "ECDHE-ECDSA-AES128-SHA" +#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA "ECDHE-ECDSA-AES256-SHA" + +#define TLS1_TXT_ECDH_RSA_WITH_NULL_SHA "ECDH-RSA-NULL-SHA" +#define TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA "ECDH-RSA-RC4-SHA" +#define TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA "ECDH-RSA-DES-CBC3-SHA" +#define TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA "ECDH-RSA-AES128-SHA" +#define TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA "ECDH-RSA-AES256-SHA" + +#define TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA "ECDHE-RSA-NULL-SHA" +#define TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA "ECDHE-RSA-RC4-SHA" +#define TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA "ECDHE-RSA-DES-CBC3-SHA" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA "ECDHE-RSA-AES128-SHA" +#define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA "ECDHE-RSA-AES256-SHA" + +#define TLS1_TXT_ECDH_anon_WITH_NULL_SHA "AECDH-NULL-SHA" +#define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA "AECDH-RC4-SHA" +#define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA "AECDH-DES-CBC3-SHA" +#define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA "AECDH-AES128-SHA" +#define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA "AECDH-AES256-SHA" + +/* PSK ciphersuites from RFC 4279 */ +#define TLS1_TXT_PSK_WITH_RC4_128_SHA "PSK-RC4-SHA" +#define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA "PSK-3DES-EDE-CBC-SHA" +#define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA "PSK-AES128-CBC-SHA" +#define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA "PSK-AES256-CBC-SHA" + +/* Camellia ciphersuites from RFC4132 */ +#define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA "CAMELLIA128-SHA" +#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA "DH-DSS-CAMELLIA128-SHA" +#define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA "DH-RSA-CAMELLIA128-SHA" +#define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA "DHE-DSS-CAMELLIA128-SHA" +#define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA "DHE-RSA-CAMELLIA128-SHA" +#define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA "ADH-CAMELLIA128-SHA" + +#define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA "CAMELLIA256-SHA" +#define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA "DH-DSS-CAMELLIA256-SHA" +#define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA "DH-RSA-CAMELLIA256-SHA" +#define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA "DHE-DSS-CAMELLIA256-SHA" +#define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA "DHE-RSA-CAMELLIA256-SHA" +#define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA "ADH-CAMELLIA256-SHA" + +/* SEED ciphersuites from RFC4162 */ +#define TLS1_TXT_RSA_WITH_SEED_SHA "SEED-SHA" +#define TLS1_TXT_DH_DSS_WITH_SEED_SHA "DH-DSS-SEED-SHA" +#define TLS1_TXT_DH_RSA_WITH_SEED_SHA "DH-RSA-SEED-SHA" +#define TLS1_TXT_DHE_DSS_WITH_SEED_SHA "DHE-DSS-SEED-SHA" +#define TLS1_TXT_DHE_RSA_WITH_SEED_SHA "DHE-RSA-SEED-SHA" +#define TLS1_TXT_ADH_WITH_SEED_SHA "ADH-SEED-SHA" + + +#define TLS_CT_RSA_SIGN 1 +#define TLS_CT_DSS_SIGN 2 +#define TLS_CT_RSA_FIXED_DH 3 +#define TLS_CT_DSS_FIXED_DH 4 +#define TLS_CT_ECDSA_SIGN 64 +#define TLS_CT_RSA_FIXED_ECDH 65 +#define TLS_CT_ECDSA_FIXED_ECDH 66 +#define TLS_CT_GOST94_SIGN 21 +#define TLS_CT_GOST01_SIGN 22 +/* when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see + * comment there) */ +#define TLS_CT_NUMBER 9 + +#define TLS1_FINISH_MAC_LENGTH 12 + +#define TLS_MD_MAX_CONST_SIZE 20 +#define TLS_MD_CLIENT_FINISH_CONST "client finished" +#define TLS_MD_CLIENT_FINISH_CONST_SIZE 15 +#define TLS_MD_SERVER_FINISH_CONST "server finished" +#define TLS_MD_SERVER_FINISH_CONST_SIZE 15 +#define TLS_MD_SERVER_WRITE_KEY_CONST "server write key" +#define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE 16 +#define TLS_MD_KEY_EXPANSION_CONST "key expansion" +#define TLS_MD_KEY_EXPANSION_CONST_SIZE 13 +#define TLS_MD_CLIENT_WRITE_KEY_CONST "client write key" +#define TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE 16 +#define TLS_MD_SERVER_WRITE_KEY_CONST "server write key" +#define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE 16 +#define TLS_MD_IV_BLOCK_CONST "IV block" +#define TLS_MD_IV_BLOCK_CONST_SIZE 8 +#define TLS_MD_MASTER_SECRET_CONST "master secret" +#define TLS_MD_MASTER_SECRET_CONST_SIZE 13 + +#ifdef CHARSET_EBCDIC +#undef TLS_MD_CLIENT_FINISH_CONST +#define TLS_MD_CLIENT_FINISH_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x66\x69\x6e\x69\x73\x68\x65\x64" /*client finished*/ +#undef TLS_MD_SERVER_FINISH_CONST +#define TLS_MD_SERVER_FINISH_CONST "\x73\x65\x72\x76\x65\x72\x20\x66\x69\x6e\x69\x73\x68\x65\x64" /*server finished*/ +#undef TLS_MD_SERVER_WRITE_KEY_CONST +#define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" /*server write key*/ +#undef TLS_MD_KEY_EXPANSION_CONST +#define TLS_MD_KEY_EXPANSION_CONST "\x6b\x65\x79\x20\x65\x78\x70\x61\x6e\x73\x69\x6f\x6e" /*key expansion*/ +#undef TLS_MD_CLIENT_WRITE_KEY_CONST +#define TLS_MD_CLIENT_WRITE_KEY_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" /*client write key*/ +#undef TLS_MD_SERVER_WRITE_KEY_CONST +#define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" /*server write key*/ +#undef TLS_MD_IV_BLOCK_CONST +#define TLS_MD_IV_BLOCK_CONST "\x49\x56\x20\x62\x6c\x6f\x63\x6b" /*IV block*/ +#undef TLS_MD_MASTER_SECRET_CONST +#define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" /*master secret*/ +#endif + +/* TLS Session Ticket extension struct */ +struct tls_session_ticket_ext_st + { + unsigned short length; + void *data; + }; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/x509.h b/extra_lib/include/openssl/x509.h new file mode 100644 index 0000000..e6f8a40 --- /dev/null +++ b/extra_lib/include/openssl/x509.h @@ -0,0 +1,1286 @@ +/* crypto/x509/x509.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_X509_H +#define HEADER_X509_H + +#include +#include +#ifndef OPENSSL_NO_BUFFER +#include +#endif +#ifndef OPENSSL_NO_EVP +#include +#endif +#ifndef OPENSSL_NO_BIO +#include +#endif +#include +#include +#include + +#ifndef OPENSSL_NO_EC +#include +#endif + +#ifndef OPENSSL_NO_ECDSA +#include +#endif + +#ifndef OPENSSL_NO_ECDH +#include +#endif + +#ifndef OPENSSL_NO_DEPRECATED +#ifndef OPENSSL_NO_RSA +#include +#endif +#ifndef OPENSSL_NO_DSA +#include +#endif +#ifndef OPENSSL_NO_DH +#include +#endif +#endif + +#ifndef OPENSSL_NO_SHA +#include +#endif +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef OPENSSL_SYS_WIN32 +/* Under Win32 these are defined in wincrypt.h */ +#undef X509_NAME +#undef X509_CERT_PAIR +#undef X509_EXTENSIONS +#endif + +#define X509_FILETYPE_PEM 1 +#define X509_FILETYPE_ASN1 2 +#define X509_FILETYPE_DEFAULT 3 + +#define X509v3_KU_DIGITAL_SIGNATURE 0x0080 +#define X509v3_KU_NON_REPUDIATION 0x0040 +#define X509v3_KU_KEY_ENCIPHERMENT 0x0020 +#define X509v3_KU_DATA_ENCIPHERMENT 0x0010 +#define X509v3_KU_KEY_AGREEMENT 0x0008 +#define X509v3_KU_KEY_CERT_SIGN 0x0004 +#define X509v3_KU_CRL_SIGN 0x0002 +#define X509v3_KU_ENCIPHER_ONLY 0x0001 +#define X509v3_KU_DECIPHER_ONLY 0x8000 +#define X509v3_KU_UNDEF 0xffff + +typedef struct X509_objects_st + { + int nid; + int (*a2i)(void); + int (*i2a)(void); + } X509_OBJECTS; + +struct X509_algor_st + { + ASN1_OBJECT *algorithm; + ASN1_TYPE *parameter; + } /* X509_ALGOR */; + +DECLARE_ASN1_SET_OF(X509_ALGOR) + +typedef STACK_OF(X509_ALGOR) X509_ALGORS; + +typedef struct X509_val_st + { + ASN1_TIME *notBefore; + ASN1_TIME *notAfter; + } X509_VAL; + +struct X509_pubkey_st + { + X509_ALGOR *algor; + ASN1_BIT_STRING *public_key; + EVP_PKEY *pkey; + }; + +typedef struct X509_sig_st + { + X509_ALGOR *algor; + ASN1_OCTET_STRING *digest; + } X509_SIG; + +typedef struct X509_name_entry_st + { + ASN1_OBJECT *object; + ASN1_STRING *value; + int set; + int size; /* temp variable */ + } X509_NAME_ENTRY; + +DECLARE_STACK_OF(X509_NAME_ENTRY) +DECLARE_ASN1_SET_OF(X509_NAME_ENTRY) + +/* we always keep X509_NAMEs in 2 forms. */ +struct X509_name_st + { + STACK_OF(X509_NAME_ENTRY) *entries; + int modified; /* true if 'bytes' needs to be built */ +#ifndef OPENSSL_NO_BUFFER + BUF_MEM *bytes; +#else + char *bytes; +#endif +/* unsigned long hash; Keep the hash around for lookups */ + unsigned char *canon_enc; + int canon_enclen; + } /* X509_NAME */; + +DECLARE_STACK_OF(X509_NAME) + +#define X509_EX_V_NETSCAPE_HACK 0x8000 +#define X509_EX_V_INIT 0x0001 +typedef struct X509_extension_st + { + ASN1_OBJECT *object; + ASN1_BOOLEAN critical; + ASN1_OCTET_STRING *value; + } X509_EXTENSION; + +typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; + +DECLARE_STACK_OF(X509_EXTENSION) +DECLARE_ASN1_SET_OF(X509_EXTENSION) + +/* a sequence of these are used */ +typedef struct x509_attributes_st + { + ASN1_OBJECT *object; + int single; /* 0 for a set, 1 for a single item (which is wrong) */ + union { + char *ptr; +/* 0 */ STACK_OF(ASN1_TYPE) *set; +/* 1 */ ASN1_TYPE *single; + } value; + } X509_ATTRIBUTE; + +DECLARE_STACK_OF(X509_ATTRIBUTE) +DECLARE_ASN1_SET_OF(X509_ATTRIBUTE) + + +typedef struct X509_req_info_st + { + ASN1_ENCODING enc; + ASN1_INTEGER *version; + X509_NAME *subject; + X509_PUBKEY *pubkey; + /* d=2 hl=2 l= 0 cons: cont: 00 */ + STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ + } X509_REQ_INFO; + +typedef struct X509_req_st + { + X509_REQ_INFO *req_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int references; + } X509_REQ; + +typedef struct x509_cinf_st + { + ASN1_INTEGER *version; /* [ 0 ] default of v1 */ + ASN1_INTEGER *serialNumber; + X509_ALGOR *signature; + X509_NAME *issuer; + X509_VAL *validity; + X509_NAME *subject; + X509_PUBKEY *key; + ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */ + ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */ + STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */ + ASN1_ENCODING enc; + } X509_CINF; + +/* This stuff is certificate "auxiliary info" + * it contains details which are useful in certificate + * stores and databases. When used this is tagged onto + * the end of the certificate itself + */ + +typedef struct x509_cert_aux_st + { + STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */ + STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */ + ASN1_UTF8STRING *alias; /* "friendly name" */ + ASN1_OCTET_STRING *keyid; /* key id of private key */ + STACK_OF(X509_ALGOR) *other; /* other unspecified info */ + } X509_CERT_AUX; + +struct x509_st + { + X509_CINF *cert_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int valid; + int references; + char *name; + CRYPTO_EX_DATA ex_data; + /* These contain copies of various extension values */ + long ex_pathlen; + long ex_pcpathlen; + unsigned long ex_flags; + unsigned long ex_kusage; + unsigned long ex_xkusage; + unsigned long ex_nscert; + ASN1_OCTET_STRING *skid; + AUTHORITY_KEYID *akid; + X509_POLICY_CACHE *policy_cache; + STACK_OF(DIST_POINT) *crldp; + STACK_OF(GENERAL_NAME) *altname; + NAME_CONSTRAINTS *nc; +#ifndef OPENSSL_NO_RFC3779 + STACK_OF(IPAddressFamily) *rfc3779_addr; + struct ASIdentifiers_st *rfc3779_asid; +#endif +#ifndef OPENSSL_NO_SHA + unsigned char sha1_hash[SHA_DIGEST_LENGTH]; +#endif + X509_CERT_AUX *aux; + } /* X509 */; + +DECLARE_STACK_OF(X509) +DECLARE_ASN1_SET_OF(X509) + +/* This is used for a table of trust checking functions */ + +typedef struct x509_trust_st { + int trust; + int flags; + int (*check_trust)(struct x509_trust_st *, X509 *, int); + char *name; + int arg1; + void *arg2; +} X509_TRUST; + +DECLARE_STACK_OF(X509_TRUST) + +typedef struct x509_cert_pair_st { + X509 *forward; + X509 *reverse; +} X509_CERT_PAIR; + +/* standard trust ids */ + +#define X509_TRUST_DEFAULT -1 /* Only valid in purpose settings */ + +#define X509_TRUST_COMPAT 1 +#define X509_TRUST_SSL_CLIENT 2 +#define X509_TRUST_SSL_SERVER 3 +#define X509_TRUST_EMAIL 4 +#define X509_TRUST_OBJECT_SIGN 5 +#define X509_TRUST_OCSP_SIGN 6 +#define X509_TRUST_OCSP_REQUEST 7 +#define X509_TRUST_TSA 8 + +/* Keep these up to date! */ +#define X509_TRUST_MIN 1 +#define X509_TRUST_MAX 8 + + +/* trust_flags values */ +#define X509_TRUST_DYNAMIC 1 +#define X509_TRUST_DYNAMIC_NAME 2 + +/* check_trust return codes */ + +#define X509_TRUST_TRUSTED 1 +#define X509_TRUST_REJECTED 2 +#define X509_TRUST_UNTRUSTED 3 + +/* Flags for X509_print_ex() */ + +#define X509_FLAG_COMPAT 0 +#define X509_FLAG_NO_HEADER 1L +#define X509_FLAG_NO_VERSION (1L << 1) +#define X509_FLAG_NO_SERIAL (1L << 2) +#define X509_FLAG_NO_SIGNAME (1L << 3) +#define X509_FLAG_NO_ISSUER (1L << 4) +#define X509_FLAG_NO_VALIDITY (1L << 5) +#define X509_FLAG_NO_SUBJECT (1L << 6) +#define X509_FLAG_NO_PUBKEY (1L << 7) +#define X509_FLAG_NO_EXTENSIONS (1L << 8) +#define X509_FLAG_NO_SIGDUMP (1L << 9) +#define X509_FLAG_NO_AUX (1L << 10) +#define X509_FLAG_NO_ATTRIBUTES (1L << 11) + +/* Flags specific to X509_NAME_print_ex() */ + +/* The field separator information */ + +#define XN_FLAG_SEP_MASK (0xf << 16) + +#define XN_FLAG_COMPAT 0 /* Traditional SSLeay: use old X509_NAME_print */ +#define XN_FLAG_SEP_COMMA_PLUS (1 << 16) /* RFC2253 ,+ */ +#define XN_FLAG_SEP_CPLUS_SPC (2 << 16) /* ,+ spaced: more readable */ +#define XN_FLAG_SEP_SPLUS_SPC (3 << 16) /* ;+ spaced */ +#define XN_FLAG_SEP_MULTILINE (4 << 16) /* One line per field */ + +#define XN_FLAG_DN_REV (1 << 20) /* Reverse DN order */ + +/* How the field name is shown */ + +#define XN_FLAG_FN_MASK (0x3 << 21) + +#define XN_FLAG_FN_SN 0 /* Object short name */ +#define XN_FLAG_FN_LN (1 << 21) /* Object long name */ +#define XN_FLAG_FN_OID (2 << 21) /* Always use OIDs */ +#define XN_FLAG_FN_NONE (3 << 21) /* No field names */ + +#define XN_FLAG_SPC_EQ (1 << 23) /* Put spaces round '=' */ + +/* This determines if we dump fields we don't recognise: + * RFC2253 requires this. + */ + +#define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) + +#define XN_FLAG_FN_ALIGN (1 << 25) /* Align field names to 20 characters */ + +/* Complete set of RFC2253 flags */ + +#define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \ + XN_FLAG_SEP_COMMA_PLUS | \ + XN_FLAG_DN_REV | \ + XN_FLAG_FN_SN | \ + XN_FLAG_DUMP_UNKNOWN_FIELDS) + +/* readable oneline form */ + +#define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \ + ASN1_STRFLGS_ESC_QUOTE | \ + XN_FLAG_SEP_CPLUS_SPC | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_SN) + +/* readable multiline form */ + +#define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + XN_FLAG_SEP_MULTILINE | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_LN | \ + XN_FLAG_FN_ALIGN) + +struct x509_revoked_st + { + ASN1_INTEGER *serialNumber; + ASN1_TIME *revocationDate; + STACK_OF(X509_EXTENSION) /* optional */ *extensions; + /* Set up if indirect CRL */ + STACK_OF(GENERAL_NAME) *issuer; + /* Revocation reason */ + int reason; + int sequence; /* load sequence */ + }; + +DECLARE_STACK_OF(X509_REVOKED) +DECLARE_ASN1_SET_OF(X509_REVOKED) + +typedef struct X509_crl_info_st + { + ASN1_INTEGER *version; + X509_ALGOR *sig_alg; + X509_NAME *issuer; + ASN1_TIME *lastUpdate; + ASN1_TIME *nextUpdate; + STACK_OF(X509_REVOKED) *revoked; + STACK_OF(X509_EXTENSION) /* [0] */ *extensions; + ASN1_ENCODING enc; + } X509_CRL_INFO; + +struct X509_crl_st + { + /* actual signature */ + X509_CRL_INFO *crl; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int references; + int flags; + /* Copies of various extensions */ + AUTHORITY_KEYID *akid; + ISSUING_DIST_POINT *idp; + /* Convenient breakdown of IDP */ + int idp_flags; + int idp_reasons; + /* CRL and base CRL numbers for delta processing */ + ASN1_INTEGER *crl_number; + ASN1_INTEGER *base_crl_number; +#ifndef OPENSSL_NO_SHA + unsigned char sha1_hash[SHA_DIGEST_LENGTH]; +#endif + STACK_OF(GENERAL_NAMES) *issuers; + const X509_CRL_METHOD *meth; + void *meth_data; + } /* X509_CRL */; + +DECLARE_STACK_OF(X509_CRL) +DECLARE_ASN1_SET_OF(X509_CRL) + +typedef struct private_key_st + { + int version; + /* The PKCS#8 data types */ + X509_ALGOR *enc_algor; + ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */ + + /* When decrypted, the following will not be NULL */ + EVP_PKEY *dec_pkey; + + /* used to encrypt and decrypt */ + int key_length; + char *key_data; + int key_free; /* true if we should auto free key_data */ + + /* expanded version of 'enc_algor' */ + EVP_CIPHER_INFO cipher; + + int references; + } X509_PKEY; + +#ifndef OPENSSL_NO_EVP +typedef struct X509_info_st + { + X509 *x509; + X509_CRL *crl; + X509_PKEY *x_pkey; + + EVP_CIPHER_INFO enc_cipher; + int enc_len; + char *enc_data; + + int references; + } X509_INFO; + +DECLARE_STACK_OF(X509_INFO) +#endif + +/* The next 2 structures and their 8 routines were sent to me by + * Pat Richard and are used to manipulate + * Netscapes spki structures - useful if you are writing a CA web page + */ +typedef struct Netscape_spkac_st + { + X509_PUBKEY *pubkey; + ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */ + } NETSCAPE_SPKAC; + +typedef struct Netscape_spki_st + { + NETSCAPE_SPKAC *spkac; /* signed public key and challenge */ + X509_ALGOR *sig_algor; + ASN1_BIT_STRING *signature; + } NETSCAPE_SPKI; + +/* Netscape certificate sequence structure */ +typedef struct Netscape_certificate_sequence + { + ASN1_OBJECT *type; + STACK_OF(X509) *certs; + } NETSCAPE_CERT_SEQUENCE; + +/* Unused (and iv length is wrong) +typedef struct CBCParameter_st + { + unsigned char iv[8]; + } CBC_PARAM; +*/ + +/* Password based encryption structure */ + +typedef struct PBEPARAM_st { +ASN1_OCTET_STRING *salt; +ASN1_INTEGER *iter; +} PBEPARAM; + +/* Password based encryption V2 structures */ + +typedef struct PBE2PARAM_st { +X509_ALGOR *keyfunc; +X509_ALGOR *encryption; +} PBE2PARAM; + +typedef struct PBKDF2PARAM_st { +ASN1_TYPE *salt; /* Usually OCTET STRING but could be anything */ +ASN1_INTEGER *iter; +ASN1_INTEGER *keylength; +X509_ALGOR *prf; +} PBKDF2PARAM; + + +/* PKCS#8 private key info structure */ + +struct pkcs8_priv_key_info_st + { + int broken; /* Flag for various broken formats */ +#define PKCS8_OK 0 +#define PKCS8_NO_OCTET 1 +#define PKCS8_EMBEDDED_PARAM 2 +#define PKCS8_NS_DB 3 +#define PKCS8_NEG_PRIVKEY 4 + ASN1_INTEGER *version; + X509_ALGOR *pkeyalg; + ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */ + STACK_OF(X509_ATTRIBUTE) *attributes; + }; + +#ifdef __cplusplus +} +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define X509_EXT_PACK_UNKNOWN 1 +#define X509_EXT_PACK_STRING 2 + +#define X509_get_version(x) ASN1_INTEGER_get((x)->cert_info->version) +/* #define X509_get_serialNumber(x) ((x)->cert_info->serialNumber) */ +#define X509_get_notBefore(x) ((x)->cert_info->validity->notBefore) +#define X509_get_notAfter(x) ((x)->cert_info->validity->notAfter) +#define X509_extract_key(x) X509_get_pubkey(x) /*****/ +#define X509_REQ_get_version(x) ASN1_INTEGER_get((x)->req_info->version) +#define X509_REQ_get_subject_name(x) ((x)->req_info->subject) +#define X509_REQ_extract_key(a) X509_REQ_get_pubkey(a) +#define X509_name_cmp(a,b) X509_NAME_cmp((a),(b)) +#define X509_get_signature_type(x) EVP_PKEY_type(OBJ_obj2nid((x)->sig_alg->algorithm)) + +#define X509_CRL_get_version(x) ASN1_INTEGER_get((x)->crl->version) +#define X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate) +#define X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate) +#define X509_CRL_get_issuer(x) ((x)->crl->issuer) +#define X509_CRL_get_REVOKED(x) ((x)->crl->revoked) + +void X509_CRL_set_default_method(const X509_CRL_METHOD *meth); +X509_CRL_METHOD *X509_CRL_METHOD_new( + int (*crl_init)(X509_CRL *crl), + int (*crl_free)(X509_CRL *crl), + int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret, + ASN1_INTEGER *ser, X509_NAME *issuer), + int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk)); +void X509_CRL_METHOD_free(X509_CRL_METHOD *m); + +void X509_CRL_set_meth_data(X509_CRL *crl, void *dat); +void *X509_CRL_get_meth_data(X509_CRL *crl); + +/* This one is only used so that a binary form can output, as in + * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf) */ +#define X509_get_X509_PUBKEY(x) ((x)->cert_info->key) + + +const char *X509_verify_cert_error_string(long n); + +#ifndef OPENSSL_NO_EVP +int X509_verify(X509 *a, EVP_PKEY *r); + +int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r); +int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r); +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r); + +NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len); +char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x); +EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x); +int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey); + +int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki); + +int X509_signature_print(BIO *bp,X509_ALGOR *alg, ASN1_STRING *sig); + +int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md); +int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md); + +int X509_pubkey_digest(const X509 *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_digest(const X509 *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_CRL_digest(const X509_CRL *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_REQ_digest(const X509_REQ *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_NAME_digest(const X509_NAME *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +#endif + +#ifndef OPENSSL_NO_FP_API +X509 *d2i_X509_fp(FILE *fp, X509 **x509); +int i2d_X509_fp(FILE *fp,X509 *x509); +X509_CRL *d2i_X509_CRL_fp(FILE *fp,X509_CRL **crl); +int i2d_X509_CRL_fp(FILE *fp,X509_CRL *crl); +X509_REQ *d2i_X509_REQ_fp(FILE *fp,X509_REQ **req); +int i2d_X509_REQ_fp(FILE *fp,X509_REQ *req); +#ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_fp(FILE *fp,RSA **rsa); +int i2d_RSAPrivateKey_fp(FILE *fp,RSA *rsa); +RSA *d2i_RSAPublicKey_fp(FILE *fp,RSA **rsa); +int i2d_RSAPublicKey_fp(FILE *fp,RSA *rsa); +RSA *d2i_RSA_PUBKEY_fp(FILE *fp,RSA **rsa); +int i2d_RSA_PUBKEY_fp(FILE *fp,RSA *rsa); +#endif +#ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa); +int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa); +DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa); +int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa); +#endif +#ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey); +int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey); +int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey); +#endif +X509_SIG *d2i_PKCS8_fp(FILE *fp,X509_SIG **p8); +int i2d_PKCS8_fp(FILE *fp,X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key); +int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); +int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); +#endif + +#ifndef OPENSSL_NO_BIO +X509 *d2i_X509_bio(BIO *bp,X509 **x509); +int i2d_X509_bio(BIO *bp,X509 *x509); +X509_CRL *d2i_X509_CRL_bio(BIO *bp,X509_CRL **crl); +int i2d_X509_CRL_bio(BIO *bp,X509_CRL *crl); +X509_REQ *d2i_X509_REQ_bio(BIO *bp,X509_REQ **req); +int i2d_X509_REQ_bio(BIO *bp,X509_REQ *req); +#ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_bio(BIO *bp,RSA **rsa); +int i2d_RSAPrivateKey_bio(BIO *bp,RSA *rsa); +RSA *d2i_RSAPublicKey_bio(BIO *bp,RSA **rsa); +int i2d_RSAPublicKey_bio(BIO *bp,RSA *rsa); +RSA *d2i_RSA_PUBKEY_bio(BIO *bp,RSA **rsa); +int i2d_RSA_PUBKEY_bio(BIO *bp,RSA *rsa); +#endif +#ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa); +int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa); +DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa); +int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa); +#endif +#ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey); +int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey); +int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey); +#endif +X509_SIG *d2i_PKCS8_bio(BIO *bp,X509_SIG **p8); +int i2d_PKCS8_bio(BIO *bp,X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key); +int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); +int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); +#endif + +X509 *X509_dup(X509 *x509); +X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa); +X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex); +X509_CRL *X509_CRL_dup(X509_CRL *crl); +X509_REQ *X509_REQ_dup(X509_REQ *req); +X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn); +int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval); +void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval, + X509_ALGOR *algor); + +X509_NAME *X509_NAME_dup(X509_NAME *xn); +X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); + +int X509_cmp_time(const ASN1_TIME *s, time_t *t); +int X509_cmp_current_time(const ASN1_TIME *s); +ASN1_TIME * X509_time_adj(ASN1_TIME *s, long adj, time_t *t); +ASN1_TIME * X509_time_adj_ex(ASN1_TIME *s, + int offset_day, long offset_sec, time_t *t); +ASN1_TIME * X509_gmtime_adj(ASN1_TIME *s, long adj); + +const char * X509_get_default_cert_area(void ); +const char * X509_get_default_cert_dir(void ); +const char * X509_get_default_cert_file(void ); +const char * X509_get_default_cert_dir_env(void ); +const char * X509_get_default_cert_file_env(void ); +const char * X509_get_default_private_dir(void ); + +X509_REQ * X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +X509 * X509_REQ_to_X509(X509_REQ *r, int days,EVP_PKEY *pkey); + +DECLARE_ASN1_FUNCTIONS(X509_ALGOR) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS) +DECLARE_ASN1_FUNCTIONS(X509_VAL) + +DECLARE_ASN1_FUNCTIONS(X509_PUBKEY) + +int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); +EVP_PKEY * X509_PUBKEY_get(X509_PUBKEY *key); +int X509_get_pubkey_parameters(EVP_PKEY *pkey, + STACK_OF(X509) *chain); +int i2d_PUBKEY(EVP_PKEY *a,unsigned char **pp); +EVP_PKEY * d2i_PUBKEY(EVP_PKEY **a,const unsigned char **pp, + long length); +#ifndef OPENSSL_NO_RSA +int i2d_RSA_PUBKEY(RSA *a,unsigned char **pp); +RSA * d2i_RSA_PUBKEY(RSA **a,const unsigned char **pp, + long length); +#endif +#ifndef OPENSSL_NO_DSA +int i2d_DSA_PUBKEY(DSA *a,unsigned char **pp); +DSA * d2i_DSA_PUBKEY(DSA **a,const unsigned char **pp, + long length); +#endif +#ifndef OPENSSL_NO_EC +int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp); +EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, + long length); +#endif + +DECLARE_ASN1_FUNCTIONS(X509_SIG) +DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO) +DECLARE_ASN1_FUNCTIONS(X509_REQ) + +DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE) +X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value); + +DECLARE_ASN1_FUNCTIONS(X509_EXTENSION) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) + +DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY) + +DECLARE_ASN1_FUNCTIONS(X509_NAME) + +int X509_NAME_set(X509_NAME **xn, X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(X509_CINF) + +DECLARE_ASN1_FUNCTIONS(X509) +DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX) + +DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR) + +int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int X509_set_ex_data(X509 *r, int idx, void *arg); +void *X509_get_ex_data(X509 *r, int idx); +int i2d_X509_AUX(X509 *a,unsigned char **pp); +X509 * d2i_X509_AUX(X509 **a,const unsigned char **pp,long length); + +int X509_alias_set1(X509 *x, unsigned char *name, int len); +int X509_keyid_set1(X509 *x, unsigned char *id, int len); +unsigned char * X509_alias_get0(X509 *x, int *len); +unsigned char * X509_keyid_get0(X509 *x, int *len); +int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int); +int X509_TRUST_set(int *t, int trust); +int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj); +int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj); +void X509_trust_clear(X509 *x); +void X509_reject_clear(X509 *x); + +DECLARE_ASN1_FUNCTIONS(X509_REVOKED) +DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO) +DECLARE_ASN1_FUNCTIONS(X509_CRL) + +int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); +int X509_CRL_get0_by_serial(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial); +int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x); + +X509_PKEY * X509_PKEY_new(void ); +void X509_PKEY_free(X509_PKEY *a); +int i2d_X509_PKEY(X509_PKEY *a,unsigned char **pp); +X509_PKEY * d2i_X509_PKEY(X509_PKEY **a,const unsigned char **pp,long length); + +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE) + +#ifndef OPENSSL_NO_EVP +X509_INFO * X509_INFO_new(void); +void X509_INFO_free(X509_INFO *a); +char * X509_NAME_oneline(X509_NAME *a,char *buf,int size); + +int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature,char *data,EVP_PKEY *pkey); + +int ASN1_digest(i2d_of_void *i2d,const EVP_MD *type,char *data, + unsigned char *md,unsigned int *len); + +int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + char *data,EVP_PKEY *pkey, const EVP_MD *type); + +int ASN1_item_digest(const ASN1_ITEM *it,const EVP_MD *type,void *data, + unsigned char *md,unsigned int *len); + +int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature,void *data,EVP_PKEY *pkey); + +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, + void *data, EVP_PKEY *pkey, const EVP_MD *type); +#endif + +int X509_set_version(X509 *x,long version); +int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial); +ASN1_INTEGER * X509_get_serialNumber(X509 *x); +int X509_set_issuer_name(X509 *x, X509_NAME *name); +X509_NAME * X509_get_issuer_name(X509 *a); +int X509_set_subject_name(X509 *x, X509_NAME *name); +X509_NAME * X509_get_subject_name(X509 *a); +int X509_set_notBefore(X509 *x, const ASN1_TIME *tm); +int X509_set_notAfter(X509 *x, const ASN1_TIME *tm); +int X509_set_pubkey(X509 *x, EVP_PKEY *pkey); +EVP_PKEY * X509_get_pubkey(X509 *x); +ASN1_BIT_STRING * X509_get0_pubkey_bitstr(const X509 *x); +int X509_certificate_type(X509 *x,EVP_PKEY *pubkey /* optional */); + +int X509_REQ_set_version(X509_REQ *x,long version); +int X509_REQ_set_subject_name(X509_REQ *req,X509_NAME *name); +int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey); +EVP_PKEY * X509_REQ_get_pubkey(X509_REQ *req); +int X509_REQ_extension_nid(int nid); +int * X509_REQ_get_extension_nids(void); +void X509_REQ_set_extension_nids(int *nids); +STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req); +int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, + int nid); +int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts); +int X509_REQ_get_attr_count(const X509_REQ *req); +int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, + int lastpos); +int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc); +X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc); +int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr); +int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_NID(X509_REQ *req, + int nid, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_CRL_set_version(X509_CRL *x, long version); +int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); +int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_sort(X509_CRL *crl); + +int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); +int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm); + +int X509_REQ_check_private_key(X509_REQ *x509,EVP_PKEY *pkey); + +int X509_check_private_key(X509 *x509,EVP_PKEY *pkey); + +int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_and_serial_hash(X509 *a); + +int X509_issuer_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_name_hash(X509 *a); + +int X509_subject_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_subject_name_hash(X509 *x); + +#ifndef OPENSSL_NO_MD5 +unsigned long X509_issuer_name_hash_old(X509 *a); +unsigned long X509_subject_name_hash_old(X509 *x); +#endif + +int X509_cmp(const X509 *a, const X509 *b); +int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); +unsigned long X509_NAME_hash(X509_NAME *x); +unsigned long X509_NAME_hash_old(X509_NAME *x); + +int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); +#ifndef OPENSSL_NO_FP_API +int X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag); +int X509_print_fp(FILE *bp,X509 *x); +int X509_CRL_print_fp(FILE *bp,X509_CRL *x); +int X509_REQ_print_fp(FILE *bp,X509_REQ *req); +int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags); +#endif + +#ifndef OPENSSL_NO_BIO +int X509_NAME_print(BIO *bp, X509_NAME *name, int obase); +int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags); +int X509_print_ex(BIO *bp,X509 *x, unsigned long nmflag, unsigned long cflag); +int X509_print(BIO *bp,X509 *x); +int X509_ocspid_print(BIO *bp,X509 *x); +int X509_CERT_AUX_print(BIO *bp,X509_CERT_AUX *x, int indent); +int X509_CRL_print(BIO *bp,X509_CRL *x); +int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, unsigned long cflag); +int X509_REQ_print(BIO *bp,X509_REQ *req); +#endif + +int X509_NAME_entry_count(X509_NAME *name); +int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, + char *buf,int len); +int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, + char *buf,int len); + +/* NOTE: you should be passsing -1, not 0 as lastpos. The functions that use + * lastpos, search after that position on. */ +int X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos); +int X509_NAME_get_index_by_OBJ(X509_NAME *name,ASN1_OBJECT *obj, + int lastpos); +X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc); +X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); +int X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne, + int loc, int set); +int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, + unsigned char *bytes, int len, int loc, int set); +int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, + unsigned char *bytes, int len, int loc, int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, + const char *field, int type, const unsigned char *bytes, int len); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, + int type,unsigned char *bytes, int len); +int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, + const unsigned char *bytes, int len, int loc, int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, + ASN1_OBJECT *obj, int type,const unsigned char *bytes, + int len); +int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, + ASN1_OBJECT *obj); +int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, int len); +ASN1_OBJECT * X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne); +ASN1_STRING * X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne); + +int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x); +int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, + int nid, int lastpos); +int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x, + ASN1_OBJECT *obj,int lastpos); +int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x, + int crit, int lastpos); +X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc); +X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc); +STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, + X509_EXTENSION *ex, int loc); + +int X509_get_ext_count(X509 *x); +int X509_get_ext_by_NID(X509 *x, int nid, int lastpos); +int X509_get_ext_by_OBJ(X509 *x,ASN1_OBJECT *obj,int lastpos); +int X509_get_ext_by_critical(X509 *x, int crit, int lastpos); +X509_EXTENSION *X509_get_ext(X509 *x, int loc); +X509_EXTENSION *X509_delete_ext(X509 *x, int loc); +int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); +void * X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx); +int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_CRL_get_ext_count(X509_CRL *x); +int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos); +int X509_CRL_get_ext_by_OBJ(X509_CRL *x,ASN1_OBJECT *obj,int lastpos); +int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos); +X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc); +X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc); +int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc); +void * X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx); +int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_REVOKED_get_ext_count(X509_REVOKED *x); +int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos); +int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x,ASN1_OBJECT *obj,int lastpos); +int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos); +X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc); +X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc); +int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc); +void * X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx); +int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, + unsigned long flags); + +X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, + int nid, int crit, ASN1_OCTET_STRING *data); +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, + ASN1_OBJECT *obj,int crit,ASN1_OCTET_STRING *data); +int X509_EXTENSION_set_object(X509_EXTENSION *ex,ASN1_OBJECT *obj); +int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit); +int X509_EXTENSION_set_data(X509_EXTENSION *ex, + ASN1_OCTET_STRING *data); +ASN1_OBJECT * X509_EXTENSION_get_object(X509_EXTENSION *ex); +ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne); +int X509_EXTENSION_get_critical(X509_EXTENSION *ex); + +int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x); +int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, + int lastpos); +int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc); +X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, + X509_ATTRIBUTE *attr); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x, + int nid, int type, + const unsigned char *bytes, int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x, + const char *attrname, int type, + const unsigned char *bytes, int len); +void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, + ASN1_OBJECT *obj, int lastpos, int type); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, + int atrtype, const void *data, int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, + const ASN1_OBJECT *obj, int atrtype, const void *data, int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, + const char *atrname, int type, const unsigned char *bytes, int len); +int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj); +int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len); +void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, + int atrtype, void *data); +int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr); +ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr); +ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx); + +int EVP_PKEY_get_attr_count(const EVP_PKEY *key); +int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, + int lastpos); +int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc); +X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc); +int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr); +int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key, + int nid, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_verify_cert(X509_STORE_CTX *ctx); + +/* lookup a cert from a X509 STACK */ +X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk,X509_NAME *name, + ASN1_INTEGER *serial); +X509 *X509_find_by_subject(STACK_OF(X509) *sk,X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(PBEPARAM) +DECLARE_ASN1_FUNCTIONS(PBE2PARAM) +DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM) + +int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, + const unsigned char *salt, int saltlen); + +X509_ALGOR *PKCS5_pbe_set(int alg, int iter, + const unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen, + unsigned char *aiv, int prf_nid); + +/* PKCS#8 utilities */ + +DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) + +EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8); +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey); +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken); +PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken); + +int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, + int version, int ptype, void *pval, + unsigned char *penc, int penclen); +int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, + PKCS8_PRIV_KEY_INFO *p8); + +int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, + int ptype, void *pval, + unsigned char *penc, int penclen); +int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, + X509_PUBKEY *pub); + +int X509_check_trust(X509 *x, int id, int flags); +int X509_TRUST_get_count(void); +X509_TRUST * X509_TRUST_get0(int idx); +int X509_TRUST_get_by_id(int id); +int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int), + char *name, int arg1, void *arg2); +void X509_TRUST_cleanup(void); +int X509_TRUST_get_flags(X509_TRUST *xp); +char *X509_TRUST_get0_name(X509_TRUST *xp); +int X509_TRUST_get_trust(X509_TRUST *xp); + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_X509_strings(void); + +/* Error codes for the X509 functions. */ + +/* Function codes. */ +#define X509_F_ADD_CERT_DIR 100 +#define X509_F_BY_FILE_CTRL 101 +#define X509_F_CHECK_POLICY 145 +#define X509_F_DIR_CTRL 102 +#define X509_F_GET_CERT_BY_SUBJECT 103 +#define X509_F_NETSCAPE_SPKI_B64_DECODE 129 +#define X509_F_NETSCAPE_SPKI_B64_ENCODE 130 +#define X509_F_X509AT_ADD1_ATTR 135 +#define X509_F_X509V3_ADD_EXT 104 +#define X509_F_X509_ATTRIBUTE_CREATE_BY_NID 136 +#define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ 137 +#define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT 140 +#define X509_F_X509_ATTRIBUTE_GET0_DATA 139 +#define X509_F_X509_ATTRIBUTE_SET1_DATA 138 +#define X509_F_X509_CHECK_PRIVATE_KEY 128 +#define X509_F_X509_CRL_PRINT_FP 147 +#define X509_F_X509_EXTENSION_CREATE_BY_NID 108 +#define X509_F_X509_EXTENSION_CREATE_BY_OBJ 109 +#define X509_F_X509_GET_PUBKEY_PARAMETERS 110 +#define X509_F_X509_LOAD_CERT_CRL_FILE 132 +#define X509_F_X509_LOAD_CERT_FILE 111 +#define X509_F_X509_LOAD_CRL_FILE 112 +#define X509_F_X509_NAME_ADD_ENTRY 113 +#define X509_F_X509_NAME_ENTRY_CREATE_BY_NID 114 +#define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT 131 +#define X509_F_X509_NAME_ENTRY_SET_OBJECT 115 +#define X509_F_X509_NAME_ONELINE 116 +#define X509_F_X509_NAME_PRINT 117 +#define X509_F_X509_PRINT_EX_FP 118 +#define X509_F_X509_PUBKEY_GET 119 +#define X509_F_X509_PUBKEY_SET 120 +#define X509_F_X509_REQ_CHECK_PRIVATE_KEY 144 +#define X509_F_X509_REQ_PRINT_EX 121 +#define X509_F_X509_REQ_PRINT_FP 122 +#define X509_F_X509_REQ_TO_X509 123 +#define X509_F_X509_STORE_ADD_CERT 124 +#define X509_F_X509_STORE_ADD_CRL 125 +#define X509_F_X509_STORE_CTX_GET1_ISSUER 146 +#define X509_F_X509_STORE_CTX_INIT 143 +#define X509_F_X509_STORE_CTX_NEW 142 +#define X509_F_X509_STORE_CTX_PURPOSE_INHERIT 134 +#define X509_F_X509_TO_X509_REQ 126 +#define X509_F_X509_TRUST_ADD 133 +#define X509_F_X509_TRUST_SET 141 +#define X509_F_X509_VERIFY_CERT 127 + +/* Reason codes. */ +#define X509_R_BAD_X509_FILETYPE 100 +#define X509_R_BASE64_DECODE_ERROR 118 +#define X509_R_CANT_CHECK_DH_KEY 114 +#define X509_R_CERT_ALREADY_IN_HASH_TABLE 101 +#define X509_R_ERR_ASN1_LIB 102 +#define X509_R_INVALID_DIRECTORY 113 +#define X509_R_INVALID_FIELD_NAME 119 +#define X509_R_INVALID_TRUST 123 +#define X509_R_KEY_TYPE_MISMATCH 115 +#define X509_R_KEY_VALUES_MISMATCH 116 +#define X509_R_LOADING_CERT_DIR 103 +#define X509_R_LOADING_DEFAULTS 104 +#define X509_R_METHOD_NOT_SUPPORTED 124 +#define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105 +#define X509_R_PUBLIC_KEY_DECODE_ERROR 125 +#define X509_R_PUBLIC_KEY_ENCODE_ERROR 126 +#define X509_R_SHOULD_RETRY 106 +#define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107 +#define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108 +#define X509_R_UNKNOWN_KEY_TYPE 117 +#define X509_R_UNKNOWN_NID 109 +#define X509_R_UNKNOWN_PURPOSE_ID 121 +#define X509_R_UNKNOWN_TRUST_ID 120 +#define X509_R_UNSUPPORTED_ALGORITHM 111 +#define X509_R_WRONG_LOOKUP_TYPE 112 +#define X509_R_WRONG_TYPE 122 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/extra_lib/include/openssl/x509_vfy.h b/extra_lib/include/openssl/x509_vfy.h new file mode 100644 index 0000000..fe09b30 --- /dev/null +++ b/extra_lib/include/openssl/x509_vfy.h @@ -0,0 +1,567 @@ +/* crypto/x509/x509_vfy.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_X509_H +#include +/* openssl/x509.h ends up #include-ing this file at about the only + * appropriate moment. */ +#endif + +#ifndef HEADER_X509_VFY_H +#define HEADER_X509_VFY_H + +#include +#ifndef OPENSSL_NO_LHASH +#include +#endif +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if 0 +/* Outer object */ +typedef struct x509_hash_dir_st + { + int num_dirs; + char **dirs; + int *dirs_type; + int num_dirs_alloced; + } X509_HASH_DIR_CTX; +#endif + +typedef struct x509_file_st + { + int num_paths; /* number of paths to files or directories */ + int num_alloced; + char **paths; /* the list of paths or directories */ + int *path_type; + } X509_CERT_FILE_CTX; + +/*******************************/ +/* +SSL_CTX -> X509_STORE + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + +SSL -> X509_STORE_CTX + ->X509_STORE + +The X509_STORE holds the tables etc for verification stuff. +A X509_STORE_CTX is used while validating a single certificate. +The X509_STORE has X509_LOOKUPs for looking up certs. +The X509_STORE then calls a function to actually verify the +certificate chain. +*/ + +#define X509_LU_RETRY -1 +#define X509_LU_FAIL 0 +#define X509_LU_X509 1 +#define X509_LU_CRL 2 +#define X509_LU_PKEY 3 + +typedef struct x509_object_st + { + /* one of the above types */ + int type; + union { + char *ptr; + X509 *x509; + X509_CRL *crl; + EVP_PKEY *pkey; + } data; + } X509_OBJECT; + +typedef struct x509_lookup_st X509_LOOKUP; + +DECLARE_STACK_OF(X509_LOOKUP) +DECLARE_STACK_OF(X509_OBJECT) + +/* This is a static that defines the function interface */ +typedef struct x509_lookup_method_st + { + const char *name; + int (*new_item)(X509_LOOKUP *ctx); + void (*free)(X509_LOOKUP *ctx); + int (*init)(X509_LOOKUP *ctx); + int (*shutdown)(X509_LOOKUP *ctx); + int (*ctrl)(X509_LOOKUP *ctx,int cmd,const char *argc,long argl, + char **ret); + int (*get_by_subject)(X509_LOOKUP *ctx,int type,X509_NAME *name, + X509_OBJECT *ret); + int (*get_by_issuer_serial)(X509_LOOKUP *ctx,int type,X509_NAME *name, + ASN1_INTEGER *serial,X509_OBJECT *ret); + int (*get_by_fingerprint)(X509_LOOKUP *ctx,int type, + unsigned char *bytes,int len, + X509_OBJECT *ret); + int (*get_by_alias)(X509_LOOKUP *ctx,int type,char *str,int len, + X509_OBJECT *ret); + } X509_LOOKUP_METHOD; + +/* This structure hold all parameters associated with a verify operation + * by including an X509_VERIFY_PARAM structure in related structures the + * parameters used can be customized + */ + +typedef struct X509_VERIFY_PARAM_st + { + char *name; + time_t check_time; /* Time to use */ + unsigned long inh_flags; /* Inheritance flags */ + unsigned long flags; /* Various verify flags */ + int purpose; /* purpose to check untrusted certificates */ + int trust; /* trust setting to check */ + int depth; /* Verify depth */ + STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */ + } X509_VERIFY_PARAM; + +DECLARE_STACK_OF(X509_VERIFY_PARAM) + +/* This is used to hold everything. It is used for all certificate + * validation. Once we have a certificate chain, the 'verify' + * function is then called to actually check the cert chain. */ +struct x509_store_st + { + /* The following is a cache of trusted certs */ + int cache; /* if true, stash any hits */ + STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */ + + /* These are external lookup methods */ + STACK_OF(X509_LOOKUP) *get_cert_methods; + + X509_VERIFY_PARAM *param; + + /* Callbacks for various operations */ + int (*verify)(X509_STORE_CTX *ctx); /* called to verify a certificate */ + int (*verify_cb)(int ok,X509_STORE_CTX *ctx); /* error callback */ + int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); /* get issuers cert from ctx */ + int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */ + int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */ + int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */ + int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ + int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ + STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm); + STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm); + int (*cleanup)(X509_STORE_CTX *ctx); + + CRYPTO_EX_DATA ex_data; + int references; + } /* X509_STORE */; + +int X509_STORE_set_depth(X509_STORE *store, int depth); + +#define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func)) +#define X509_STORE_set_verify_func(ctx,func) ((ctx)->verify=(func)) + +/* This is the functions plus an instance of the local variables. */ +struct x509_lookup_st + { + int init; /* have we been started */ + int skip; /* don't use us. */ + X509_LOOKUP_METHOD *method; /* the functions */ + char *method_data; /* method data */ + + X509_STORE *store_ctx; /* who owns us */ + } /* X509_LOOKUP */; + +/* This is a used when verifying cert chains. Since the + * gathering of the cert chain can take some time (and have to be + * 'retried', this needs to be kept and passed around. */ +struct x509_store_ctx_st /* X509_STORE_CTX */ + { + X509_STORE *ctx; + int current_method; /* used when looking up certs */ + + /* The following are set by the caller */ + X509 *cert; /* The cert to check */ + STACK_OF(X509) *untrusted; /* chain of X509s - untrusted - passed in */ + STACK_OF(X509_CRL) *crls; /* set of CRLs passed in */ + + X509_VERIFY_PARAM *param; + void *other_ctx; /* Other info for use with get_issuer() */ + + /* Callbacks for various operations */ + int (*verify)(X509_STORE_CTX *ctx); /* called to verify a certificate */ + int (*verify_cb)(int ok,X509_STORE_CTX *ctx); /* error callback */ + int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); /* get issuers cert from ctx */ + int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */ + int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */ + int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */ + int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ + int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ + int (*check_policy)(X509_STORE_CTX *ctx); + STACK_OF(X509) * (*lookup_certs)(X509_STORE_CTX *ctx, X509_NAME *nm); + STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm); + int (*cleanup)(X509_STORE_CTX *ctx); + + /* The following is built up */ + int valid; /* if 0, rebuild chain */ + int last_untrusted; /* index of last untrusted cert */ + STACK_OF(X509) *chain; /* chain of X509s - built up and trusted */ + X509_POLICY_TREE *tree; /* Valid policy tree */ + + int explicit_policy; /* Require explicit policy value */ + + /* When something goes wrong, this is why */ + int error_depth; + int error; + X509 *current_cert; + X509 *current_issuer; /* cert currently being tested as valid issuer */ + X509_CRL *current_crl; /* current CRL */ + + int current_crl_score; /* score of current CRL */ + unsigned int current_reasons; /* Reason mask */ + + X509_STORE_CTX *parent; /* For CRL path validation: parent context */ + + CRYPTO_EX_DATA ex_data; + } /* X509_STORE_CTX */; + +void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); + +#define X509_STORE_CTX_set_app_data(ctx,data) \ + X509_STORE_CTX_set_ex_data(ctx,0,data) +#define X509_STORE_CTX_get_app_data(ctx) \ + X509_STORE_CTX_get_ex_data(ctx,0) + +#define X509_L_FILE_LOAD 1 +#define X509_L_ADD_DIR 2 + +#define X509_LOOKUP_load_file(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL) + +#define X509_LOOKUP_add_dir(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL) + +#define X509_V_OK 0 +/* illegal error (for uninitialized values, to avoid X509_V_OK): 1 */ + +#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 +#define X509_V_ERR_UNABLE_TO_GET_CRL 3 +#define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 +#define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 +#define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 +#define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 +#define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 +#define X509_V_ERR_CERT_NOT_YET_VALID 9 +#define X509_V_ERR_CERT_HAS_EXPIRED 10 +#define X509_V_ERR_CRL_NOT_YET_VALID 11 +#define X509_V_ERR_CRL_HAS_EXPIRED 12 +#define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 +#define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 +#define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 +#define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 +#define X509_V_ERR_OUT_OF_MEM 17 +#define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 +#define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 +#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 +#define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 +#define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 +#define X509_V_ERR_CERT_REVOKED 23 +#define X509_V_ERR_INVALID_CA 24 +#define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 +#define X509_V_ERR_INVALID_PURPOSE 26 +#define X509_V_ERR_CERT_UNTRUSTED 27 +#define X509_V_ERR_CERT_REJECTED 28 +/* These are 'informational' when looking for issuer cert */ +#define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 +#define X509_V_ERR_AKID_SKID_MISMATCH 30 +#define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 +#define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 + +#define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 +#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 +#define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 +#define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 +#define X509_V_ERR_INVALID_NON_CA 37 +#define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 +#define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 +#define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 + +#define X509_V_ERR_INVALID_EXTENSION 41 +#define X509_V_ERR_INVALID_POLICY_EXTENSION 42 +#define X509_V_ERR_NO_EXPLICIT_POLICY 43 +#define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 +#define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 + +#define X509_V_ERR_UNNESTED_RESOURCE 46 + +#define X509_V_ERR_PERMITTED_VIOLATION 47 +#define X509_V_ERR_EXCLUDED_VIOLATION 48 +#define X509_V_ERR_SUBTREE_MINMAX 49 +#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 +#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 +#define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 +#define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 + +/* The application is not happy */ +#define X509_V_ERR_APPLICATION_VERIFICATION 50 + +/* Certificate verify flags */ + +/* Send issuer+subject checks to verify_cb */ +#define X509_V_FLAG_CB_ISSUER_CHECK 0x1 +/* Use check time instead of current time */ +#define X509_V_FLAG_USE_CHECK_TIME 0x2 +/* Lookup CRLs */ +#define X509_V_FLAG_CRL_CHECK 0x4 +/* Lookup CRLs for whole chain */ +#define X509_V_FLAG_CRL_CHECK_ALL 0x8 +/* Ignore unhandled critical extensions */ +#define X509_V_FLAG_IGNORE_CRITICAL 0x10 +/* Disable workarounds for broken certificates */ +#define X509_V_FLAG_X509_STRICT 0x20 +/* Enable proxy certificate validation */ +#define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 +/* Enable policy checking */ +#define X509_V_FLAG_POLICY_CHECK 0x80 +/* Policy variable require-explicit-policy */ +#define X509_V_FLAG_EXPLICIT_POLICY 0x100 +/* Policy variable inhibit-any-policy */ +#define X509_V_FLAG_INHIBIT_ANY 0x200 +/* Policy variable inhibit-policy-mapping */ +#define X509_V_FLAG_INHIBIT_MAP 0x400 +/* Notify callback that policy is OK */ +#define X509_V_FLAG_NOTIFY_POLICY 0x800 +/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */ +#define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000 +/* Delta CRL support */ +#define X509_V_FLAG_USE_DELTAS 0x2000 +/* Check selfsigned CA signature */ +#define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 + + +#define X509_VP_FLAG_DEFAULT 0x1 +#define X509_VP_FLAG_OVERWRITE 0x2 +#define X509_VP_FLAG_RESET_FLAGS 0x4 +#define X509_VP_FLAG_LOCKED 0x8 +#define X509_VP_FLAG_ONCE 0x10 + +/* Internal use: mask of policy related options */ +#define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \ + | X509_V_FLAG_EXPLICIT_POLICY \ + | X509_V_FLAG_INHIBIT_ANY \ + | X509_V_FLAG_INHIBIT_MAP) + +int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,int type,X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x); +void X509_OBJECT_up_ref_count(X509_OBJECT *a); +void X509_OBJECT_free_contents(X509_OBJECT *a); +X509_STORE *X509_STORE_new(void ); +void X509_STORE_free(X509_STORE *v); + +STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm); +STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm); +int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); +int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); +int X509_STORE_set_trust(X509_STORE *ctx, int trust); +int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm); + +void X509_STORE_set_verify_cb(X509_STORE *ctx, + int (*verify_cb)(int, X509_STORE_CTX *)); + +X509_STORE_CTX *X509_STORE_CTX_new(void); + +int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + +void X509_STORE_CTX_free(X509_STORE_CTX *ctx); +int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, + X509 *x509, STACK_OF(X509) *chain); +void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); + +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m); + +X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); +X509_LOOKUP_METHOD *X509_LOOKUP_file(void); + +int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); +int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); + +int X509_STORE_get_by_subject(X509_STORE_CTX *vs,int type,X509_NAME *name, + X509_OBJECT *ret); + +int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); + +#ifndef OPENSSL_NO_STDIO +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type); +#endif + + +X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method); +void X509_LOOKUP_free(X509_LOOKUP *ctx); +int X509_LOOKUP_init(X509_LOOKUP *ctx); +int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret); +int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, + ASN1_INTEGER *serial, X509_OBJECT *ret); +int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, + unsigned char *bytes, int len, X509_OBJECT *ret); +int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, + int len, X509_OBJECT *ret); +int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); + +#ifndef OPENSSL_NO_STDIO +int X509_STORE_load_locations (X509_STORE *ctx, + const char *file, const char *dir); +int X509_STORE_set_default_paths(X509_STORE *ctx); +#endif + +int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx,int idx,void *data); +void * X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx); +int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s); +int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); +X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); +X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx); +X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx); +X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x); +void X509_STORE_CTX_set_chain(X509_STORE_CTX *c,STACK_OF(X509) *sk); +void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c,STACK_OF(X509_CRL) *sk); +int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); +int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, + int purpose, int trust); +void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); +void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, + time_t t); +void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + int (*verify_cb)(int, X509_STORE_CTX *)); + +X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx); +int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx); + +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); +int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); + +/* X509_VERIFY_PARAM functions */ + +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); +void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name); +int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags); +int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose); +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust); +void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); +int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, + ASN1_OBJECT *policy); +int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies); +int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); + +int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name); +void X509_VERIFY_PARAM_table_cleanup(void); + +int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, + STACK_OF(X509) *certs, + STACK_OF(ASN1_OBJECT) *policy_oids, + unsigned int flags); + +void X509_policy_tree_free(X509_POLICY_TREE *tree); + +int X509_policy_tree_level_count(const X509_POLICY_TREE *tree); +X509_POLICY_LEVEL * + X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i); + +STACK_OF(X509_POLICY_NODE) * + X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree); + +STACK_OF(X509_POLICY_NODE) * + X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree); + +int X509_policy_level_node_count(X509_POLICY_LEVEL *level); + +X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i); + +const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node); + +STACK_OF(POLICYQUALINFO) * + X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node); +const X509_POLICY_NODE * + X509_policy_node_get0_parent(const X509_POLICY_NODE *node); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/extra_lib/lib/android/armeabi-v7a/libeditline.so b/extra_lib/lib/android/armeabi-v7a/libeditline.so deleted file mode 100755 index d78b58b..0000000 Binary files a/extra_lib/lib/android/armeabi-v7a/libeditline.so and /dev/null differ diff --git a/extra_lib/lib/android/armeabi-v7a/libfaad.so b/extra_lib/lib/android/armeabi-v7a/libfaad.so deleted file mode 100755 index 82c2988..0000000 Binary files a/extra_lib/lib/android/armeabi-v7a/libfaad.so and /dev/null differ diff --git a/extra_lib/lib/android/armeabi-v7a/libffmpeg.so b/extra_lib/lib/android/armeabi-v7a/libffmpeg.so deleted file mode 100755 index 4793189..0000000 Binary files a/extra_lib/lib/android/armeabi-v7a/libffmpeg.so and /dev/null differ diff --git a/extra_lib/lib/android/armeabi-v7a/libft2.so b/extra_lib/lib/android/armeabi-v7a/libft2.so deleted file mode 100755 index 6c50c80..0000000 Binary files a/extra_lib/lib/android/armeabi-v7a/libft2.so and /dev/null differ diff --git a/extra_lib/lib/android/armeabi-v7a/libjpeg.so b/extra_lib/lib/android/armeabi-v7a/libjpeg.so deleted file mode 100755 index 2e31bba..0000000 Binary files a/extra_lib/lib/android/armeabi-v7a/libjpeg.so and /dev/null differ diff --git a/extra_lib/lib/android/armeabi-v7a/libjs_osmo.so b/extra_lib/lib/android/armeabi-v7a/libjs_osmo.so deleted file mode 100755 index f41de44..0000000 Binary files a/extra_lib/lib/android/armeabi-v7a/libjs_osmo.so and /dev/null differ diff --git a/extra_lib/lib/android/armeabi-v7a/libmad.so b/extra_lib/lib/android/armeabi-v7a/libmad.so deleted file mode 100755 index 6d530ea..0000000 Binary files a/extra_lib/lib/android/armeabi-v7a/libmad.so and /dev/null differ diff --git a/extra_lib/lib/android/armeabi-v7a/libopenjpeg.so b/extra_lib/lib/android/armeabi-v7a/libopenjpeg.so deleted file mode 100755 index 8a1d2fe..0000000 Binary files a/extra_lib/lib/android/armeabi-v7a/libopenjpeg.so and /dev/null differ diff --git a/extra_lib/lib/android/armeabi-v7a/libpng.so b/extra_lib/lib/android/armeabi-v7a/libpng.so deleted file mode 100755 index fcfdc89..0000000 Binary files a/extra_lib/lib/android/armeabi-v7a/libpng.so and /dev/null differ diff --git a/extra_lib/lib/android/armeabi-v7a/libz.so b/extra_lib/lib/android/armeabi-v7a/libz.so deleted file mode 100755 index 2611089..0000000 Binary files a/extra_lib/lib/android/armeabi-v7a/libz.so and /dev/null differ diff --git a/extra_lib/lib/android/armeabi/libeditline.so b/extra_lib/lib/android/armeabi/libeditline.so deleted file mode 100755 index a4dda63..0000000 Binary files a/extra_lib/lib/android/armeabi/libeditline.so and /dev/null differ diff --git a/extra_lib/lib/android/armeabi/libfaad.so b/extra_lib/lib/android/armeabi/libfaad.so deleted file mode 100755 index 7cfc949..0000000 Binary files a/extra_lib/lib/android/armeabi/libfaad.so and /dev/null differ diff --git a/extra_lib/lib/android/armeabi/libffmpeg.so b/extra_lib/lib/android/armeabi/libffmpeg.so deleted file mode 100755 index b215685..0000000 Binary files a/extra_lib/lib/android/armeabi/libffmpeg.so and /dev/null differ diff --git a/extra_lib/lib/android/armeabi/libft2.so b/extra_lib/lib/android/armeabi/libft2.so deleted file mode 100755 index e066dc2..0000000 Binary files a/extra_lib/lib/android/armeabi/libft2.so and /dev/null differ diff --git a/extra_lib/lib/android/armeabi/libjpeg.so b/extra_lib/lib/android/armeabi/libjpeg.so deleted file mode 100755 index 3975464..0000000 Binary files a/extra_lib/lib/android/armeabi/libjpeg.so and /dev/null differ diff --git a/extra_lib/lib/android/armeabi/libjs_osmo.so b/extra_lib/lib/android/armeabi/libjs_osmo.so deleted file mode 100755 index c13e680..0000000 Binary files a/extra_lib/lib/android/armeabi/libjs_osmo.so and /dev/null differ diff --git a/extra_lib/lib/android/armeabi/libmad.so b/extra_lib/lib/android/armeabi/libmad.so deleted file mode 100755 index f0301fc..0000000 Binary files a/extra_lib/lib/android/armeabi/libmad.so and /dev/null differ diff --git a/extra_lib/lib/android/armeabi/libopenjpeg.so b/extra_lib/lib/android/armeabi/libopenjpeg.so deleted file mode 100755 index 48905d0..0000000 Binary files a/extra_lib/lib/android/armeabi/libopenjpeg.so and /dev/null differ diff --git a/extra_lib/lib/android/armeabi/libpng.so b/extra_lib/lib/android/armeabi/libpng.so deleted file mode 100755 index 78ff0bb..0000000 Binary files a/extra_lib/lib/android/armeabi/libpng.so and /dev/null differ diff --git a/extra_lib/lib/android/armeabi/libz.so b/extra_lib/lib/android/armeabi/libz.so deleted file mode 100755 index 075217d..0000000 Binary files a/extra_lib/lib/android/armeabi/libz.so and /dev/null differ diff --git a/gui/extensions/widget_manager/init.js b/gui/extensions/widget_manager/init.js index 1f931c9..e8e8b79 100644 --- a/gui/extensions/widget_manager/init.js +++ b/gui/extensions/widget_manager/init.js @@ -49,7 +49,7 @@ function scan_directory(dir) if (j==count) { new_wid = WidgetManager.open(uri, null); if (new_wid!=null) { - widget_insert_icon(new_wid, 1); + widget_insert_icon(new_wid); } } } @@ -78,13 +78,14 @@ function open_widget_manager(extension) var new_wid = WidgetManager.open(value, null); if (new_wid==null) return; WidgetManager.last_widget_dir = directory; - widget_insert_icon(new_wid, 0); + widget_insert_icon(new_wid); dock.layout(dock.width, dock.height); open_dock(true); } filebrowse.on_directory = function(directory) { WidgetManager.last_widget_dir = directory; scan_directory(directory); + open_dock(true); } filebrowse.set_size(320 , 240); gpacui_show_window(filebrowse); @@ -109,7 +110,8 @@ function open_widget_manager(extension) } function widget_insert_icon(new_wid) { - var icon = gw_new_icon_button(dock, widget_get_icon(new_wid), new_wid.name, 'button'); + //var icon = gw_new_icon_button(dock, widget_get_icon(new_wid), new_wid.name, 'button'); + var icon = gpacui_insert_dock_icon(new_wid.name, widget_get_icon(new_wid) ); new_wid.in_panel = true; new_wid.visible = false; new_wid.icon_dock = icon; diff --git a/gui/gui.js b/gui/gui.js index 57adfd0..6767db7 100644 --- a/gui/gui.js +++ b/gui/gui.js @@ -28,6 +28,7 @@ UPnP_Enabled = false; browser_mode = false; upnp_renderers = null; current_url = ''; +current_time = 0.0; player_control = null; all_extensions = []; @@ -57,6 +58,9 @@ function on_movie_active(value) function on_movie_time(value) { + /*filter out every 1/2 seconds*/ + if (current_time+0.5 > value) return; + current_time = value; player_control.set_time(value); if (UPnP_Enabled) UPnP.MovieTime = value; } @@ -83,6 +87,15 @@ function filter_event(evt) return true; } return false; + + case GF_EVENT_OPENFILE: + var files = evt.files; + /*todo - handle playlist*/ + if (files.length) { + set_movie_url(files[0]); + } + return true; + case GF_EVENT_MOUSEUP: in_drag = false; if (evt.picked) return false; @@ -95,21 +108,25 @@ function filter_event(evt) { open_dock(false); if (player_control.visible) { - player_control.hide(); + //player_control.hide(); top_wnd = null; } else { player_control.show(); top_wnd = player_control; } } + return false; } - return true; + return false; case GF_EVENT_KEYUP: // alert(evt.keycode); + //commented out as HOME is used for viewpoint reset +/* if (evt.keycode=='Home') { open_dock(!dock.visible); return true; } +*/ if (evt.keycode=='Up') { if (dock.visible) return false; if (player_control.visible) { @@ -149,7 +166,9 @@ function open_dock(show) { if (show) { dock.show(); + dock.layout(); player_control.hide(); + set_movie_url(''); top_wnd = dock; // uidisplay.hide(); } else { @@ -164,14 +183,16 @@ function open_dock(show) function gpacui_insert_dock_icon(label, icon) { - if (0) { + if (1) { var wnd = gw_new_window(dock, true, 'offscreen'); var icon = gw_new_icon_button(wnd, icon, label, 'osdbutton'); wnd.set_size(icon.width, icon.height); wnd.show(); + dock.set_size(display_width, display_height); return icon; } else { var icon = gw_new_icon_button(dock, icon, label, 'osdbutton'); + dock.set_size(display_width, display_height); return icon; } } @@ -333,8 +354,9 @@ function initialize() { if (url.indexOf('://')<0) set_movie_url('gpac://'+url); else set_movie_url(url); } else { - open_dock(true); - } +// open_dock(true); + player_control.show(); + } } @@ -406,6 +428,11 @@ function set_movie_url(url) controlled_renderer.Open(uri); } current_url = url; + current_time = 0; + + if (url == '') player_control.show(); + else player_control.hide(); + } //performs layout on all contents @@ -730,9 +757,7 @@ function new_player_control(container) this.view.show(); } } else { - if (this.media_line.visible) - this.media_line.set_size(width - min_w - 5, control_icon_size/3); - + if (this.snd_low) this.snd_low.hide(); if (this.snd_ctrl) this.snd_ctrl.hide(); if (this.rewind) this.rewind.hide(); @@ -740,6 +765,26 @@ function new_player_control(container) if (this.forward) this.forward.hide(); if (this.fullscreen) this.fullscreen.hide(); if (this.remote) this.remote.hide(); + + if (this.view && movie_connected && (gpac.navigation_type!= GF_NAVIGATE_TYPE_NONE) ) { + if (min_w + time_w + this.view.width < width) { + min_w += this.view.width; + this.view.show(); + } + } + + if (this.remote) { + if (UPnP.MediaRenderersCount && (current_url!='') && (min_w + time_w + this.remote.width < width)) { + min_w += this.remote.width; + this.remote.show(); + } else { + this.remote.hide(); + } + } + + if (this.media_line.visible) + this.media_line.set_size(width - min_w - 5, control_icon_size/3); + } width += control_icon_size/2; this.infobar.set_size(width, height); @@ -1096,12 +1141,14 @@ function browse_remote_servers() item.is_server = false; item.on_click = this._on_server_click; } else { - for (var j=0; j +#include +#include + +#define AIT_SECTION_LENGTH_MAX 1021 +#define APPLICATION_TYPE_HTTP_APPLICATION 16 + +typedef enum { + APPLICATION_DESCRIPTOR = 0x00, + APPLICATION_NAME_DESCRIPTOR = 0x01, + TRANSPORT_PROTOCOL_DESCRIPTOR = 0x02, + SIMPLE_APPLICATION_LOCATION_DESCRIPTOR = 0x15, + APPLICATION_USAGE_DESCRIPTOR = 0x16, +} DESCRIPTOR_TAG; + + +typedef struct +{ + + ABSTRACT_ES + GF_M2TS_SectionFilter *sec; + + u32 service_id; + u8 table_id; + Bool section_syntax_indicator; + u16 section_length; + Bool test_application_flag; + u16 application_type; + u8 version_number; + Bool current_next_indicator; + u8 section_number; + u8 last_section_number; + u16 common_descriptors_length; + GF_List * common_descriptors; + u16 application_loop_length; + GF_List * application; + u32 CRC_32; + +} GF_M2TS_AIT; + + +typedef struct +{ + u32 organisation_id; + u16 application_id; + u8 application_control_code; + u16 application_descriptors_loop_length; + GF_List * application_descriptors; + u8 application_descriptors_id[50]; + u8 index_app_desc_id; + +} +GF_M2TS_AIT_APPLICATION; + + +typedef enum { + FUTURE_USE = 0x00, + CAROUSEL = 0x01, + RESERVED = 0x02, + TRANSPORT_HTTP = 0x03, + DVB_USE = 0x04, + TO_REGISTER = 0x100, +} PROTOCOL_ID; + +typedef struct +{ + u8 descriptor_tag; + u8 descriptor_length; + u8 application_profiles_length; + u16 application_profile; + u8 version_major; + u8 version_minor; + u8 version_micro; + Bool service_bound_flag; + u8 visibility; + u8 application_priority; + u8 transport_protocol_label; + +} GF_M2TS_APPLICATION_DESCRIPTOR; + +typedef struct +{ + u8 descriptor_tag; + u8 descriptor_length; + u8 usage_type; + +} GF_M2TS_APPLICATION_USAGE; + +typedef struct +{ + u8 descriptor_tag; + u8 descriptor_length; + char* initial_path_bytes; + +}GF_M2TS_SIMPLE_APPLICATION_LOCATION; + +typedef struct +{ + Bool remote_connection; + u16 original_network_id; + u16 transport_stream_id; + u16 service_id; + u8 component_tag; + +} GF_M2TS_OBJECT_CAROUSEL_SELECTOR_BYTE; + +typedef struct{ + + u8 URL_extension_length; + char* URL_extension_byte; + +}GF_M2TS_TRANSPORT_HTTP_URL_EXTENTION; + +typedef struct +{ + u8 URL_base_length; + char* URL_base_byte; + u8 URL_extension_count; + GF_M2TS_TRANSPORT_HTTP_URL_EXTENTION* URL_extentions; + +} GF_M2TS_TRANSPORT_HTTP_SELECTOR_BYTE; + +typedef struct +{ + u8 descriptor_tag; + u8 descriptor_length; + u16 protocol_id; + u8 transport_protocol_label; + void* selector_byte; + +} GF_M2TS_TRANSPORT_PROTOCOL_DESCRIPTOR; + +typedef struct +{ + u8 descriptor_tag; + u8 descriptor_length; + u32 ISO_639_language_code; + u8 application_name_length; + char* application_name_char; + +} GF_M2TS_APPLICATION_NAME_DESCRIPTOR; + +GF_Err gf_m2ts_process_ait(GF_M2TS_AIT *es, char *data, u32 data_size, u32 table_id); +void on_ait_section(GF_M2TS_Demuxer *ts, u32 evt_type, void *par); +GF_M2TS_ES *gf_ait_section_new(u32 service_id); +void gf_ait_destroy(GF_M2TS_AIT* ait); + + +#endif //_GF_CAROUSSEL_H_ + diff --git a/include/gpac/compositor.h b/include/gpac/compositor.h index 5799a45..ea55d1f 100644 --- a/include/gpac/compositor.h +++ b/include/gpac/compositor.h @@ -108,7 +108,9 @@ scene timing*/ /*force render tick*/ void gf_sc_render(GF_Compositor *sr); /*gets screen buffer - this locks the scene graph too until released is called*/ -GF_Err gf_sc_get_screen_buffer(GF_Compositor *sr, GF_VideoSurface *framebuffer, Bool depth_buffer); +GF_Err gf_sc_get_screen_buffer(GF_Compositor *sr, GF_VideoSurface *framebuffer, u32 depth_buffer_mode); +/*gets offscreen buffer - this locks the scene graph too until released is called*/ +GF_Err gf_sc_get_offscreen_buffer(GF_Compositor *sr, GF_VideoSurface *framebuffer, u32 view_idx, u32 depth_buffer_mode); /*releases screen buffer and unlocks graph*/ GF_Err gf_sc_release_screen_buffer(GF_Compositor *sr, GF_VideoSurface *framebuffer); diff --git a/include/gpac/config_file.h b/include/gpac/config_file.h index 8398047..d08a4f6 100644 --- a/include/gpac/config_file.h +++ b/include/gpac/config_file.h @@ -50,6 +50,18 @@ extern "C" { typedef struct __tag_config GF_Config; +/*! + * \brief configuration file initialization + * + * Constructs a configuration file from fileName. if fileName is NULL, the default GPAC configuration file is loaded. + * If no configuration file is found, a default configuration file is created with the proper module directory, font directory + * and other default options. + *\param fileName name of the configuration file, or NULL for default file + *\param new_cfg Boolean set to true if a new configuration file has been created + *\return the configuration file object, NULL if the file could not be created + */ +GF_Config *gf_cfg_init(const char *file, Bool *new_cfg); + /*! * \brief configuration file constructor * diff --git a/include/gpac/configuration.h b/include/gpac/configuration.h index a3b4bec..c4f6eb1 100644 --- a/include/gpac/configuration.h +++ b/include/gpac/configuration.h @@ -28,12 +28,8 @@ #define GPAC_CONFIGURATION "(static configuration file)" -/*this file defines all common macros for libgpac compilation*/ -#ifdef WIN32 -#define GPAC_CONFIG_WIN32 -#endif - -/*except for symbian32 which uses .mmp directives ... */ +/*this file defines all common macros for libgpac compilation + except for symbian32 which uses .mmp directives ... */ #if defined(WIN32) || defined(_WIN32_WCE) || defined(GPAC_CONFIG_DARWIN) /*visual studio and xcode*/ /*enables GPAC fixed point*/ @@ -51,7 +47,9 @@ //#define GPAC_BIG_ENDIAN /*SSL enabled*/ -//#define GPAC_HAS_SSL +#ifdef WIN32 +#define GPAC_HAS_SSL +#endif /*spidermonkey enabled*/ #define GPAC_HAS_SPIDERMONKEY diff --git a/include/gpac/constants.h b/include/gpac/constants.h index 75723b4..8220aa4 100644 --- a/include/gpac/constants.h +++ b/include/gpac/constants.h @@ -188,6 +188,9 @@ typedef enum /*!Stereo RGBA. Component ordering in bytes is R-G-B-A. */ GF_PIXEL_RGBAS = GF_4CC('R', 'G', 'A', 'S'), + /*internal format for OpenGL using pachek RGB 24 bit plus planaer depth plane at the end of the image*/ + GF_PIXEL_RGB_24_DEPTH = GF_4CC('R', 'G', 'B', 'd'), + /*!YUV packed format*/ GF_PIXEL_YUY2 = GF_4CC('Y','U','Y','2'), /*!YUV packed format*/ @@ -399,9 +402,29 @@ enum /*!OTI for 13K Voice / QCELP audio streams*/ GPAC_OTI_AUDIO_13K_VOICE = 0xE1, - /*!OTI for LIBPLAYER private streams. The data pointer in the DSI is the libplayer handle object*/ - GPAC_OTI_PRIVATE_MEDIA_LIBPLAYER = 0xF1 + /*!OTI for RAW media streams. Input data is directly dispatched to the composition memory. The DSI contains is formated (MSBF) as follows:\n + * DSI Syntax for audio streams + \code + * u32 sample_rate: sampling rate + * u16 nb_channels: num channels + * u16 nb_bits_per_sample: num of bits per audio sample + * u32 frame_size: max size of audio frame in byte + * u32 channel_config: GPAC mask of GF_AUDIO_CH_ constants, or 0 if unknown + \endcode + \n + * DSI Syntax for video streams + \code + * u32 codec_four_cc: the codec 4CC reg code / codec id for ffmpeg + * u16 width: video width or 0 if unknown + * u16 height: video height or 0 if unknown + * u32 frame_size: size of the video frame + * u32 stride: horizontal stride of the video frame + \endcode + */ + GPAC_OTI_RAW_MEDIA_STREAM = 0x101, + /*!OTI for LIBPLAYER private streams. The data pointer in the DSI is the libplayer handle object*/ + GPAC_OTI_PRIVATE_MEDIA_LIBPLAYER = 0xF1 }; diff --git a/include/gpac/download.h b/include/gpac/download.h index 0979175..a96194f 100644 --- a/include/gpac/download.h +++ b/include/gpac/download.h @@ -162,10 +162,12 @@ extern "C" { { /*!session is not threaded, the user must explicitely fetch the data */ GF_NETIO_SESSION_NOT_THREADED = 1, - /*!session has no cache: data will be sent to the user if threaded mode (live streams like radios & co)*/ + /*! session data is live, e.g. data will be sent to the user if threaded mode (live streams like radios & co) + Whether the data is cached or not to disk cannot be controlled by the user at the current time. + */ GF_NETIO_SESSION_NOT_CACHED = 1<<1, - /*! ignores any data already in the cache */ - GF_NETIO_SESSION_FORCE_NO_CACHE = 1<<2 + /*indicates that the connection to the server should be kept once the download is successfully completed*/ + GF_NETIO_SESSION_PERSISTENT = 1<<2, }; @@ -304,6 +306,17 @@ extern "C" { *\return the mime type of the URL, or NULL if error. You should get the error with \ref gf_dm_sess_last_error */ const char *gf_dm_sess_mime_type(GF_DownloadSession * sess); + + /*! + *\brief sets session range + * + *Sets the session byte range. This shll be called before processing the session. + *\param sess the download session + *\param start_range HTTP download start range in byte + *\param end_range HTTP download end range in byte + *\note this can only be used when the session is not threaded + */ + GF_Err gf_dm_sess_set_range(GF_DownloadSession *sess, u64 start_range, u64 end_range); /*! *\brief get cache file name * @@ -357,6 +370,21 @@ extern "C" { GF_Err gf_dm_sess_process(GF_DownloadSession * sess); /*! + *\brief fetch session object headers + * + *Fetch the session object headers and stops after that. This is only usable if the session is not threaded + *\param sess the download session + *\return the last error in the session or 0 if none*/ + GF_Err gf_dm_sess_process_headers(GF_DownloadSession * sess); + + /*! + *\brief fetch session status + * + *Fetch the session current status + *\param sess the download session + *\return the session status*/ + u32 gf_dm_sess_get_status(GF_DownloadSession * sess); + /*! *\brief Get session resource url * *Returns the original resource URL associated with the session @@ -364,6 +392,15 @@ extern "C" { *\return the associated URL */ const char *gf_dm_sess_get_resource_name(GF_DownloadSession *dnload); + /*! + *\brief Get session original resource url + * + *Returns the original resource URL before any redirection associated with the session + *\param sess the download session + *\return the associated URL + */ + const char *gf_dm_sess_get_original_resource_name(GF_DownloadSession *dnload); + /*! * \brief Download a file over the network using a download manager @@ -410,7 +447,57 @@ extern "C" { */ Bool gf_dm_sess_can_be_cached_on_disk(const GF_DownloadSession *sess); - /*! @} */ + + /*! + * Reassigns session flags and callbacks. This is only possible if the session is not threaded. + * \param sess The session + * \param flags The new flags for the session + * \param user_io The new callback function + * \param cbk The new user data to ba used in the callback function + * \return GF_OK or error + */ + GF_Err gf_dm_sess_reassign(GF_DownloadSession *sess, u32 flags, gf_dm_user_io user_io, void *cbk); + + /*! + * Re-setup an existing, completed session to download a new URL. If same server/port/protocol is used, the same socket will be reused if the session + has the @GF_NETIO_SESSION_PERSISTENT flag set. This is only possible if the session is not threaded. + * \param sess The session + * \param url The new url for the session + * \return GF_OK or error + */ + GF_Err gf_dm_sess_setup_from_url(GF_DownloadSession *sess, const char *url); + + /* + *\brief sets download manager max rate per session + * + *Sets the maximum rate (per session only at the current time). + *\param dm the download manager object + *\param rate_in_byte_per_sec the new rate in bytes per sec. If 0, HTTP rate will not be limited + */ + void gf_dm_set_data_rate(GF_DownloadManager *dm, u32 rate_in_byte_per_sec); + + /* + *\brief gets download manager max rate per session + * + *Sets the maximum rate (per session only at the current time). + *\param dm the download manager object + *\return the rate in bytes per sec. If 0, HTTP rate is not limited + */ + u32 gf_dm_get_data_rate(GF_DownloadManager *dm); + + + /* + *\brief fetches remote file in memory + * + *Fetches remote file in memory . + *\param url the data to fetch + *\param out_data output data (allocated by function) + *\param out_size output data size + *\param out_mime if not NULL, pointer will contain the mime type (allocated by function) + *\return error code if any + */ + GF_Err gf_dm_get_file_memory(const char *url, char **out_data, u32 *out_size, char **out_mime); + /*! @} */ #ifdef __cplusplus } diff --git a/include/gpac/esi.h b/include/gpac/esi.h index d942c46..e2f8e77 100644 --- a/include/gpac/esi.h +++ b/include/gpac/esi.h @@ -109,6 +109,8 @@ enum GF_ESI_SIGNAL_DTS = 1<<1, /*no more data to expect from this stream*/ GF_ESI_STREAM_IS_OVER = 1<<2, + /*stream is not signaled through MPEG-4 Systems (OD stream) */ + GF_ESI_STREAM_WITHOUT_MPEG4_SYSTEMS = 1<<3, }; typedef struct __elementary_stream_ifce @@ -137,6 +139,9 @@ typedef struct __elementary_stream_ifce char *decoder_config; u32 decoder_config_size; + + /* MPEG-4 SL Config if any*/ + GF_SLConfig *sl_config; struct __esi_video_info info_video; struct __esi_audio_info info_audio; diff --git a/include/gpac/events.h b/include/gpac/events.h index a186f3d..f5f06d8 100644 --- a/include/gpac/events.h +++ b/include/gpac/events.h @@ -199,16 +199,17 @@ enum { GF_EVENT_NAVIGATE_INFO, /*indicates the link or its description under the mouse pointer*/ GF_EVENT_MESSAGE, /*message from the MPEG-4 terminal*/ GF_EVENT_PROGRESS, /*progress message from the MPEG-4 terminal*/ + GF_EVENT_FORWARDED, /*event forwarded by service (MPEG-2, RTP, ...)*/ GF_EVENT_VIEWPOINTS, /*indicates viewpoint list has changed - no struct associated*/ GF_EVENT_STREAMLIST, /*indicates stream list has changed - no struct associated - only used when no scene info is present*/ GF_EVENT_METADATA, /*indicates a change in associated metadata*/ GF_EVENT_MIGRATE, /*indicates a session migration request*/ GF_EVENT_DISCONNECT, /*indicates the current url should be disconnected*/ GF_EVENT_RESOLUTION, /*indicates the screen resolution has changed*/ - - /* Events for Keyboad */ - GF_EVENT_TEXT_EDITING_START, - GF_EVENT_TEXT_EDITING_END + GF_EVENT_OPENFILE, + /* Events for Keyboad */ + GF_EVENT_TEXT_EDITING_START, + GF_EVENT_TEXT_EDITING_END }; /*GPAC/DOM3 key codes*/ @@ -689,6 +690,32 @@ typedef struct { u8 attrChange; } GF_EventMutation; +enum +{ + /*events forwarded from MPEG-2 stack*/ + GF_EVT_FORWARDED_MPEG2 = 0, + /*events forwarded from RTP/RTSP/IP stack (not used yet)*/ + GF_EVT_FORWARDED_RTP_RTSP +}; + +typedef struct { + /* GF_EVENT_OPENFILE*/ + u8 type; + u32 nb_files; + char **files; +} GF_EventOpenFile; + +typedef struct { + /* GF_EVENT_FORWARDED*/ + u8 type; + /*one of te above event*/ + u8 forward_type; + /*original type of event as forwarded by the service*/ + u32 service_event_type; + /*parameter of event as forwarded by the service - creation/deletion is handled by the service*/ + void *param; +} GF_EventForwarded; + typedef union { u8 type; @@ -709,6 +736,8 @@ typedef union GF_EventMove move; GF_EventVideoSetup setup; GF_EventMutation mutation; + GF_EventForwarded forwarded_event; + GF_EventOpenFile open_file; } GF_Event; diff --git a/include/gpac/ietf.h b/include/gpac/ietf.h index 8e449a9..7818052 100644 --- a/include/gpac/ietf.h +++ b/include/gpac/ietf.h @@ -939,6 +939,10 @@ typedef struct /* stream profile and level indication - for AVC/H264, 0xPPCCLL, with PP:profile, CC:compatibility, LL:level*/ u32 PL_ID; + /*rvc config of the stream if carried in SDP*/ + u16 rvc_predef; + char *rvc_config; + u32 rvc_config_size; /*2 - optional options*/ diff --git a/include/gpac/internal/bifs_tables.h b/include/gpac/internal/bifs_tables.h index c36268f..b3c384d 100644 --- a/include/gpac/internal/bifs_tables.h +++ b/include/gpac/internal/bifs_tables.h @@ -24,7 +24,7 @@ /* - DO NOT MOFIFY - File generated on GMT Mon Jan 18 12:27:12 2010 + DO NOT MOFIFY - File generated on GMT Wed Jul 20 05:50:21 2011 BY MPEG4Gen for GPAC Version 0.4.6-DEV */ diff --git a/include/gpac/internal/camera.h b/include/gpac/internal/camera.h index 0434545..2f031f2 100644 --- a/include/gpac/internal/camera.h +++ b/include/gpac/internal/camera.h @@ -36,6 +36,8 @@ enum CAM_IS_DIRTY = 1, /*if set when ortho, indicates the viewport matrix shall be used when computing modelview (2D only)*/ CAM_HAS_VIEWPORT = 1<<2, + /*if set when ortho to disable LookAt mode*/ + CAM_NO_LOOKAT = 1<<3, }; enum diff --git a/include/gpac/internal/compositor_dev.h b/include/gpac/internal/compositor_dev.h index 8d85cf6..f6510f1 100644 --- a/include/gpac/internal/compositor_dev.h +++ b/include/gpac/internal/compositor_dev.h @@ -134,6 +134,14 @@ enum GF_SC_DRAW_FLUSH, }; +enum +{ + GF_SC_DEPTH_GL_NONE=0, + GF_SC_DEPTH_GL_POINTS, + GF_SC_DEPTH_GL_STRIPS, + GF_SC_DEPTH_GL_VBO, +}; + struct __tag_compositor { /*the main user*/ @@ -462,8 +470,7 @@ struct __tag_compositor void *tgl_ctx; #endif - Float depth_gl_scale, depth_gl_strips_filter; - /*0: none - 1: point-based, 2: elevation grid*/ + Fixed depth_gl_scale, depth_gl_strips_filter; u32 depth_gl_type; /*increase/decrease the standard interoccular offset by the specified distance in cm*/ Fixed interoccular_offset; @@ -1114,10 +1121,11 @@ GF_Camera *compositor_layer3d_get_camera(GF_Node *node); void compositor_layer3d_bind_camera(GF_Node *node, Bool do_bind, u32 nav_value); void compositor_3d_draw_bitmap(struct _drawable *stack, DrawAspect2D *asp, GF_TraverseState *tr_state, Fixed width, Fixed height, Fixed bmp_scale_x, Fixed bmp_scale_y); -GF_Err compositor_3d_get_screen_buffer(GF_Compositor *sr, GF_VideoSurface *fb, Bool depth_buffer); +GF_Err compositor_3d_get_screen_buffer(GF_Compositor *sr, GF_VideoSurface *fb, u32 depth_buffer_mode); +GF_Err compositor_3d_get_offscreen_buffer(GF_Compositor *sr, GF_VideoSurface *fb, u32 view_idx, u32 depth_buffer_mode); GF_Err compositor_3d_release_screen_buffer(GF_Compositor *sr, GF_VideoSurface *framebuffer); -void gf_sc_load_opengl_extensions(GF_Compositor *sr); +void gf_sc_load_opengl_extensions(GF_Compositor *sr, Bool has_gl_context); Bool gf_sc_fit_world_to_screen(GF_Compositor *compositor); @@ -1327,6 +1335,9 @@ typedef struct GF_Err gf_sc_add_audio_listener(GF_Compositor *compositor, GF_AudioListener *al); GF_Err gf_sc_remove_audio_listener(GF_Compositor *compositor, GF_AudioListener *al); + +GF_Err gf_sc_set_scene_size(GF_Compositor *compositor, u32 Width, u32 Height, Bool force_size); + #ifdef __cplusplus } #endif diff --git a/include/gpac/internal/ietf_dev.h b/include/gpac/internal/ietf_dev.h index 23876ba..03d0040 100644 --- a/include/gpac/internal/ietf_dev.h +++ b/include/gpac/internal/ietf_dev.h @@ -206,7 +206,7 @@ void gf_rtp_get_next_report_time(GF_RTPChannel *ch); if (sig < 0) { \ sprintf(temp, "%d", d); \ } else { \ - sprintf(temp, "%ud", d); \ + sprintf(temp, "%d", d); \ } \ RTSP_WRITE_ALLOC_STR_WITHOUT_CHECK(buf, buf_size, pos, temp); diff --git a/include/gpac/internal/isomedia_dev.h b/include/gpac/internal/isomedia_dev.h index 91bd860..9b68c46 100644 --- a/include/gpac/internal/isomedia_dev.h +++ b/include/gpac/internal/isomedia_dev.h @@ -183,8 +183,7 @@ enum /* 3GPP Adaptive Streaming extensions */ GF_ISOM_BOX_TYPE_STYP = GF_4CC( 's', 't', 'y', 'p' ), - GF_ISOM_BOX_TYPE_TFAD = GF_4CC( 't', 'f', 'a', 'd' ), - GF_ISOM_BOX_TYPE_TFMA = GF_4CC( 't', 'f', 'm', 'a' ), + GF_ISOM_BOX_TYPE_TFDT = GF_4CC( 't', 'f', 'd', 't' ), GF_ISOM_BOX_TYPE_SIDX = GF_4CC( 's', 'i', 'd', 'x' ), /*3GPP text / MPEG-4 StreamingText*/ @@ -308,6 +307,8 @@ enum GF_ISOM_BOX_TYPE_SUBS = GF_4CC( 's', 'u', 'b', 's' ), + GF_ISOM_BOX_TYPE_RVCC = GF_4CC( 'r', 'v', 'c', 'c' ), + /*ALL INTERNAL BOXES - NEVER WRITTEN TO FILE!!*/ /*generic handlers*/ @@ -745,6 +746,12 @@ typedef struct u32 vSpacing; } GF_PixelAspectRatioBox; +typedef struct +{ + GF_ISOM_BOX + u16 predefined_rvc_config; + u32 rvc_meta_idx; +} GF_RVCConfigurationBox; #define GF_ISOM_VISUAL_SAMPLE_ENTRY \ GF_ISOM_SAMPLE_ENTRY_FIELDS \ @@ -760,7 +767,8 @@ typedef struct char compressor_name[33]; \ u16 bit_depth; \ s16 color_table_index; \ - GF_PixelAspectRatioBox *pasp; + GF_PixelAspectRatioBox *pasp; \ + GF_RVCConfigurationBox *rvcc; \ typedef struct { @@ -1055,7 +1063,7 @@ typedef struct u32 gf_isom_sample_get_subsample_entry(GF_ISOFile *movie, u32 track, u32 sampleNumber, GF_SampleEntry **sub_sample); #ifndef GPAC_DISABLE_ISOM_WRITE -GF_Err gf_isom_add_subsample_info(GF_SubSampleInformationBox *sub_samples, u32 sampleNumber, u32 subSampleSize, u32 priority, Bool discardable); +GF_Err gf_isom_add_subsample_info(GF_SubSampleInformationBox *sub_samples, u32 sampleNumber, u32 subSampleSize, u8 priority, u32 reserved, Bool discardable); #endif typedef struct @@ -1337,6 +1345,8 @@ typedef struct char *content_encoding; // needed to actually read the resource file, but not written in the MP21 file. char *full_path; + // if not 0, full_path is actually the data to write. + u32 data_len; } GF_ItemInfoEntryBox; typedef struct @@ -1499,6 +1509,13 @@ typedef struct u8 IFrameSwitching; } GF_TrackFragmentHeaderBox; + +typedef struct +{ + GF_ISOM_FULL_BOX + u64 baseMediaDecodeTime; +} GF_TFBaseMediaDecodeTimeBox; + typedef struct { GF_ISOM_BOX @@ -1510,7 +1527,7 @@ typedef struct GF_SubSampleInformationBox *subs; /*when data caching is on*/ u32 DataCache; - GF_Box *tfad; + GF_TFBaseMediaDecodeTimeBox *tfdt; } GF_TrackFragmentBox; /*FLAGS for TRUN : specify what is written in the SampleTable of TRUN*/ @@ -1840,7 +1857,7 @@ typedef struct __oma_kms_box typedef struct { Bool reference_type; - u32 reference_offset; + u32 reference_size; u32 subsegment_duration; Bool contains_RAP; u32 RAP_delta_time; @@ -1883,6 +1900,8 @@ enum /*read-only access to the movie file: we create a file mapping object mode is set to GF_ISOM_DATA_MAP_READ afterwards*/ GF_ISOM_DATA_MAP_READ_ONLY = 4, + /*write-only access at the end of the movie - only used for movie fragments concatenation*/ + GF_ISOM_DATA_MAP_CAT = 5, }; /*this is the DataHandler structure each data handler has its own bitstream*/ @@ -1955,6 +1974,8 @@ GF_Err gf_isom_datamap_add_data(GF_DataMap *ptr, char *data, u32 dataSize); #define GF_ISOM_GET_FRAG_PAD(flag) ( (flag) >> 17) & 0x7 #define GF_ISOM_GET_FRAG_SYNC(flag) ( ! ( ( (flag) >> 16) & 0x1)) #define GF_ISOM_GET_FRAG_DEG(flag) (flag) & 0x7FFF + +GF_TrackExtendsBox *GetTrex(GF_MovieBox *moov, u32 TrackID); #endif enum @@ -2005,6 +2026,7 @@ struct __tag_isom { #ifndef GPAC_DISABLE_ISOM_FRAGMENTS u32 FragmentsFlags, NextMoofNumber; + Bool first_moof_merged; /*active fragment*/ GF_MovieFragmentBox *moof; /*in WRITE mode, this is the current MDAT where data is written*/ @@ -2013,7 +2035,7 @@ struct __tag_isom { u64 segment_start; GF_List *moof_list; - Bool use_segments, moof_first; + Bool use_segments, moof_first, append_segment; Bool is_index_segment; #endif @@ -2073,6 +2095,8 @@ GF_Err findEntryForTime(GF_SampleTableBox *stbl, u64 DTS, u8 useCTS, u32 *sample GF_Err stbl_GetSampleSize(GF_SampleSizeBox *stsz, u32 SampleNumber, u32 *Size); GF_Err stbl_GetSampleCTS(GF_CompositionOffsetBox *ctts, u32 SampleNumber, u32 *CTSoffset); GF_Err stbl_GetSampleDTS(GF_TimeToSampleBox *stts, u32 SampleNumber, u64 *DTS); +GF_Err stbl_GetSampleDTS_and_Duration(GF_TimeToSampleBox *stts, u32 SampleNumber, u64 *DTS, u32 *duration); + /*find a RAP or set the prev / next RAPs if vars are passed*/ GF_Err stbl_GetSampleRAP(GF_SyncSampleBox *stss, u32 SampleNumber, u8 *IsRAP, u32 *prevRAP, u32 *nextRAP); GF_Err stbl_GetSampleInfos(GF_SampleTableBox *stbl, u32 sampleNumber, u64 *offset, u32 *chunkNumber, u32 *descIndex, u8 *isEdited); @@ -3319,6 +3343,20 @@ GF_Err subs_Size(GF_Box *s); GF_Err subs_Read(GF_Box *s, GF_BitStream *bs); GF_Err subs_dump(GF_Box *a, FILE * trace); +GF_Box *tfdt_New(); +void tfdt_del(GF_Box *); +GF_Err tfdt_Write(GF_Box *s, GF_BitStream *bs); +GF_Err tfdt_Size(GF_Box *s); +GF_Err tfdt_Read(GF_Box *s, GF_BitStream *bs); +GF_Err tfdt_dump(GF_Box *a, FILE * trace); + +GF_Box *rvcc_New(); +void rvcc_del(GF_Box *); +GF_Err rvcc_Write(GF_Box *s, GF_BitStream *bs); +GF_Err rvcc_Size(GF_Box *s); +GF_Err rvcc_Read(GF_Box *s, GF_BitStream *bs); +GF_Err rvcc_dump(GF_Box *a, FILE * trace); + #endif /*GPAC_DISABLE_ISOM*/ #ifdef __cplusplus diff --git a/include/gpac/internal/m3u8.h b/include/gpac/internal/m3u8.h index 9672235..aaf37ab 100644 --- a/include/gpac/internal/m3u8.h +++ b/include/gpac/internal/m3u8.h @@ -1,188 +1,188 @@ -/** - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) Jean Le Feuvre 2000-2005 - * All rights reserved - * - * This file is part of GPAC - * - * 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. - * Written by Pierre Souchay for VizionR SAS - * - */ -#ifndef M3U8_PLAYLIST_H -#define M3U8_PLAYLIST_H -#include -#include - -/** - * Global Structure - * - * For a stream with multiple bandwidths and multiple programs - * - * VariantPlayList - * | - * |_ program id 1 - * | | - * | |_ bandwidth X : playlistElement1 - * | |- bandwidth Y : playlistElement2 - * | - * |- program id 2 - * | - * |_ bandwidth Z : playlistElement - * - * For a "normal" playlist - * - * VariantPlayList - * | - * |_ program id 1 - * | - * |_ bandwidth 0 : playlistElement1 - * - * Where PlaylistElement can be : - * - a stream (real resource) - * - a playlist (list of PlaylistElements itself) - */ - -#define M3U8_UNKOWN_MIME_TYPE "unknown" - -/** - * Basic Stream structure - */ -typedef struct s_stream { - u8 i; -} Stream; - -/** - * The playlist contains a list of elements to play - */ -typedef struct s_playList { - int currentMediaSequence; - int target_duration; - int mediaSequenceMin; - int mediaSequenceMax; - char is_ended; - GF_List * elements; -} Playlist; - -typedef enum e_playlistElementType { TYPE_PLAYLIST, TYPE_STREAM, TYPE_UNKNOWN} PlaylistElementType; - -/** - * The Structure containing the playlist element - */ -typedef struct s_playlistElement { - int durationInfo; - int bandwidth; - char * title; - char * codecs; - char * url; - PlaylistElementType elementType; - union { Playlist playlist; - Stream stream; - } element; - -} PlaylistElement; - -typedef struct s_program { - int programId; - GF_List * bitrates; - int currentBitrateIndex; -} Program; - - -/** - * The root playlist, can contains several PlaylistElements structures - */ -typedef struct s_variantPlaylist { - GF_List * programs; - int currentProgram; - Bool playlistNeedsRefresh; -} VariantPlaylist; - -/** - * Creates a new playlist - * @return NULL if playlist could not be allocated - * -Playlist * playlist_new(); -*/ -/** - * Deletes a given playlist and all of its sub elements - * -GF_Err playlist_del(Playlist *); -*/ - -/** - * Deletes an Playlist element - */ -GF_Err playlist_element_del(PlaylistElement *); - -/** - * Creates a new program properly initialized - */ -Program * program_new(int programId); - -/** - * Deletes the specified program - */ -GF_Err program_del(Program * program); - -/** - * Creates an Playlist element. - * This element can be either a playlist of a stream according to first parameter. - * @return NULL if element could not be created. Element deletion will be deleted recusivly by #playlist_del(Playlist*) - */ -PlaylistElement * playlist_element_new(PlaylistElementType elementType, const char * url, const char * title, const char *codecs, int durationInfo); - -/** - * Creates a new VariantPlaylist - * @return NULL if VariantPlaylist element could not be allocated - */ -VariantPlaylist * variant_playlist_new (); - -/** - * Deletes the given VariantPlaylist and all of its sub elements - */ -GF_Err variant_playlist_del(VariantPlaylist *); - -GF_Err playlist_element_dump(const PlaylistElement * e, int indent); - -GF_Err variant_playlist_dump(const VariantPlaylist *); - -Program * variant_playlist_find_matching_program(const VariantPlaylist *, const u32 programId); - -Program * variant_playlist_get_current_program(const VariantPlaylist *); - - - -/** - * Parse the given playlist file - * @param file The file from cache to parse - * @param The playlist to fill. If argument is null, and file is valid, playlist will be allocated - * @return GF_OK if playlist valid - */ -GF_Err parse_root_playlist(const char * file, VariantPlaylist ** playlist, const char * baseURL); -/** - * Parse the given playlist file as a subplaylist of an existing playlist - * @param file The file from cache to parse - * @param The playlist to fill. - * @param baseURL base URL of the playlist - * @param program in which the playlist is parsed - * @param sub_playlist existing subplaylist element in the @playlist in which the playlist is parsed - * @return GF_OK if playlist valid - */ -GF_Err parse_sub_playlist(const char * file, VariantPlaylist ** playlist, const char * baseURL, Program * in_program, PlaylistElement *sub_playlist); - -#endif /* M3U8_PLAYLIST_H */ - +/** + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Jean Le Feuvre 2000-2005 + * All rights reserved + * + * This file is part of GPAC + * + * 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. + * Written by Pierre Souchay for VizionR SAS + * + */ +#ifndef M3U8_PLAYLIST_H +#define M3U8_PLAYLIST_H +#include +#include + +/** + * Global Structure + * + * For a stream with multiple bandwidths and multiple programs + * + * VariantPlayList + * | + * |_ program id 1 + * | | + * | |_ bandwidth X : playlistElement1 + * | |- bandwidth Y : playlistElement2 + * | + * |- program id 2 + * | + * |_ bandwidth Z : playlistElement + * + * For a "normal" playlist + * + * VariantPlayList + * | + * |_ program id 1 + * | + * |_ bandwidth 0 : playlistElement1 + * + * Where PlaylistElement can be : + * - a stream (real resource) + * - a playlist (list of PlaylistElements itself) + */ + +#define M3U8_UNKOWN_MIME_TYPE "unknown" + +/** + * Basic Stream structure + */ +typedef struct s_stream { + u8 i; +} Stream; + +/** + * The playlist contains a list of elements to play + */ +typedef struct s_playList { + int currentMediaSequence; + int target_duration; + int mediaSequenceMin; + int mediaSequenceMax; + char is_ended; + GF_List * elements; +} Playlist; + +typedef enum e_playlistElementType { TYPE_PLAYLIST, TYPE_STREAM, TYPE_UNKNOWN} PlaylistElementType; + +/** + * The Structure containing the playlist element + */ +typedef struct s_playlistElement { + int durationInfo; + int bandwidth; + char * title; + char * codecs; + char * url; + PlaylistElementType elementType; + union { Playlist playlist; + Stream stream; + } element; + +} PlaylistElement; + +typedef struct s_program { + int programId; + GF_List * bitrates; + int currentBitrateIndex; +} Program; + + +/** + * The root playlist, can contains several PlaylistElements structures + */ +typedef struct s_variantPlaylist { + GF_List * programs; + int currentProgram; + Bool playlistNeedsRefresh; +} VariantPlaylist; + +/** + * Creates a new playlist + * @return NULL if playlist could not be allocated + * +Playlist * playlist_new(); +*/ +/** + * Deletes a given playlist and all of its sub elements + * +GF_Err playlist_del(Playlist *); +*/ + +/** + * Deletes an Playlist element + */ +GF_Err playlist_element_del(PlaylistElement *); + +/** + * Creates a new program properly initialized + */ +Program * program_new(int programId); + +/** + * Deletes the specified program + */ +GF_Err program_del(Program * program); + +/** + * Creates an Playlist element. + * This element can be either a playlist of a stream according to first parameter. + * @return NULL if element could not be created. Element deletion will be deleted recusivly by #playlist_del(Playlist*) + */ +PlaylistElement * playlist_element_new(PlaylistElementType elementType, const char * url, const char * title, const char *codecs, int durationInfo); + +/** + * Creates a new VariantPlaylist + * @return NULL if VariantPlaylist element could not be allocated + */ +VariantPlaylist * variant_playlist_new (); + +/** + * Deletes the given VariantPlaylist and all of its sub elements + */ +GF_Err variant_playlist_del(VariantPlaylist *); + +GF_Err playlist_element_dump(const PlaylistElement * e, int indent); + +GF_Err variant_playlist_dump(const VariantPlaylist *); + +Program * variant_playlist_find_matching_program(const VariantPlaylist *, const u32 programId); + +Program * variant_playlist_get_current_program(const VariantPlaylist *); + + + +/** + * Parse the given playlist file + * @param file The file from cache to parse + * @param The playlist to fill. If argument is null, and file is valid, playlist will be allocated + * @return GF_OK if playlist valid + */ +GF_Err parse_root_playlist(const char * file, VariantPlaylist ** playlist, const char * baseURL); +/** + * Parse the given playlist file as a subplaylist of an existing playlist + * @param file The file from cache to parse + * @param The playlist to fill. + * @param baseURL base URL of the playlist + * @param program in which the playlist is parsed + * @param sub_playlist existing subplaylist element in the @playlist in which the playlist is parsed + * @return GF_OK if playlist valid + */ +GF_Err parse_sub_playlist(const char * file, VariantPlaylist ** playlist, const char * baseURL, Program * in_program, PlaylistElement *sub_playlist); + +#endif /* M3U8_PLAYLIST_H */ + diff --git a/include/gpac/internal/mesh.h b/include/gpac/internal/mesh.h index 9ccdb7b..3bed651 100644 --- a/include/gpac/internal/mesh.h +++ b/include/gpac/internal/mesh.h @@ -165,6 +165,7 @@ typedef struct __gf_mesh // u32 aabb_nb_index; u32 vbo; + Bool vbo_dirty, vbo_dynamic; } GF_Mesh; GF_Mesh *new_mesh(); diff --git a/include/gpac/internal/mpd.h b/include/gpac/internal/mpd.h index effa68e..d481434 100644 --- a/include/gpac/internal/mpd.h +++ b/include/gpac/internal/mpd.h @@ -1,130 +1,131 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Cyril Concolato - * Copyright (c) Telecom ParisTech 2010- - * All rights reserved - * - * This file is part of GPAC / 3GPP/MPEG Media Presentation Description input module - * - * 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. - * - */ -#ifndef _MPD_IN_H_ -#define _MPD_IN_H_ - -#include -#include -#include -#include - -typedef struct -{ - char *url; - Bool use_byterange; - u32 byterange_start; - u32 byterange_end; -} GF_MPD_SegmentInfo; - -typedef struct { - char *id; - u32 bandwidth; - u32 width; - u32 height; - char *lang; - char *mime; - u32 groupID; - Bool startWithRap; - /* TODO: maximumRAPPeriod */ - /* TODO: depid*/ - /* TODO: default rep*/ - - u32 qualityRanking; - char *content_protection_type; - char *content_protection_uri; - double alternatePlayoutRate; - u32 default_segment_duration; - /*TODO: multiple views */ - char *default_base_url; - - /* initialization segment */ - char *init_url; - Bool init_use_range; - u32 init_byterange_start; - u32 init_byterange_end; - - /* other segments */ - char *url_template; - u32 startIndex; - u32 endIndex; - - GF_List *segments; -} GF_MPD_Representation; - -typedef struct { - u32 start; /* expressed in seconds, relative to the start of the MPD */ - u32 duration; /* TODO */ - char *id; /* TODO */ - u8 flags; - Bool segment_alignment_flag; /* to be merged into real flags */ - Bool bitstream_switching_flag; - - u32 default_segment_duration; /* milliseconds */ - char *default_base_url; - /* TODO: default timeline */ - char *url_template; - - /* TODO: xlink:href & xlink:actuate */ - - GF_List *representations; - /* TODO: representation groups */ - /* TODO: subset */ -} GF_MPD_Period; - -typedef enum { - GF_MPD_TYPE_ON_DEMAND, - GF_MPD_TYPE_LIVE, -} GF_MPD_Type; - -typedef struct { - GF_MPD_Type type; - char *base_url; - /* TODO: add alternate URL */ - u32 duration; /* expressed in milliseconds */ - u32 min_update_time; /* expressed in milliseconds */ - u32 min_buffer_time; /* expressed in milliseconds */ - /*start time*/ - /*end time*/ - u32 time_shift_buffer_depth; /* expressed in milliseconds */ - char *title; - char *source; - char *copyright; - char *more_info_url; - - /* the number of periods is dynamic since we may update the MPD from time to time, cannot avoid GF_List */ - GF_List *periods; -} GF_MPD; - -GF_Err gf_mpd_init_from_dom(GF_XMLNode *root, GF_MPD *mpd); - -GF_MPD *gf_mpd_new(); -void gf_mpd_del(GF_MPD *mpd); - -GF_Err gf_m3u8_to_mpd(GF_ClientService *service, const char *m3u8_file, const char *base_url, - const char *mpd_file, - u32 reload_count, char *mimeTypeForM3U8Segments); - -#endif // _MPD_IN_H_ - +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Cyril Concolato + * Copyright (c) Telecom ParisTech 2010- + * All rights reserved + * + * This file is part of GPAC / 3GPP/MPEG Media Presentation Description input module + * + * 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. + * + */ +#ifndef _MPD_IN_H_ +#define _MPD_IN_H_ + +#include +#include +#include +#include + +typedef struct +{ + char *url; + Bool use_byterange; + u32 byterange_start; + u32 byterange_end; +} GF_MPD_SegmentInfo; + +typedef struct { + char *id; + u32 bandwidth; + u32 width; + u32 height; + char *lang; + char *mime; + u32 groupID; + Bool disabled; + Bool startWithRap; + /* TODO: maximumRAPPeriod */ + /* TODO: depid*/ + /* TODO: default rep*/ + + u32 qualityRanking; + char *content_protection_type; + char *content_protection_uri; + double alternatePlayoutRate; + u32 default_segment_duration; + /*TODO: multiple views */ + char *default_base_url; + + /* initialization segment */ + char *init_url; + Bool init_use_range; + u32 init_byterange_start; + u32 init_byterange_end; + + /* other segments */ + char *url_template; + u32 startIndex; + u32 endIndex; + + GF_List *segments; +} GF_MPD_Representation; + +typedef struct { + u32 start; /* expressed in seconds, relative to the start of the MPD */ + u32 duration; /* TODO */ + char *id; /* TODO */ + u8 flags; + Bool segment_alignment_flag; /* to be merged into real flags */ + Bool bitstream_switching_flag; + + u32 default_segment_duration; /* milliseconds */ + char *default_base_url; + /* TODO: default timeline */ + char *url_template; + + /* TODO: xlink:href & xlink:actuate */ + + GF_List *representations; + /* TODO: representation groups */ + /* TODO: subset */ +} GF_MPD_Period; + +typedef enum { + GF_MPD_TYPE_ON_DEMAND, + GF_MPD_TYPE_LIVE, +} GF_MPD_Type; + +typedef struct { + GF_MPD_Type type; + char *base_url; + /* TODO: add alternate URL */ + u32 duration; /* expressed in milliseconds */ + u32 min_update_time; /* expressed in milliseconds */ + u32 min_buffer_time; /* expressed in milliseconds */ + /*start time*/ + /*end time*/ + u32 time_shift_buffer_depth; /* expressed in milliseconds */ + char *title; + char *source; + char *copyright; + char *more_info_url; + + /* the number of periods is dynamic since we may update the MPD from time to time, cannot avoid GF_List */ + GF_List *periods; +} GF_MPD; + +GF_Err gf_mpd_init_from_dom(GF_XMLNode *root, GF_MPD *mpd, const char *base_url); + +GF_MPD *gf_mpd_new(); +void gf_mpd_del(GF_MPD *mpd); + +GF_Err gf_m3u8_to_mpd(GF_ClientService *service, const char *m3u8_file, const char *base_url, + const char *mpd_file, + u32 reload_count, char *mimeTypeForM3U8Segments); + +#endif // _MPD_IN_H_ + diff --git a/include/gpac/internal/scenegraph_dev.h b/include/gpac/internal/scenegraph_dev.h index 0af5d53..8df8523 100644 --- a/include/gpac/internal/scenegraph_dev.h +++ b/include/gpac/internal/scenegraph_dev.h @@ -835,6 +835,7 @@ void gf_smil_anim_init_runtime_info(GF_Node *node); void gf_smil_anim_delete_runtime_info(SMIL_Anim_RTI *rai); void gf_smil_anim_delete_animations(GF_Node *e); void gf_smil_anim_remove_from_target(GF_Node *anim, GF_Node *target); +GF_Node *gf_smil_anim_get_target(GF_Node *e); void gf_sg_handle_dom_event(GF_Node *hdl, GF_DOM_Event *event, GF_Node *observer); void gf_smil_setup_events(GF_Node *node); @@ -975,7 +976,7 @@ struct _node_js_binding typedef struct __tag_svg_script_ctx { Bool (*script_execute)(struct __tag_scene_graph *sg, char *utf8_script, GF_DOM_Event *event); - Bool (*handler_execute)(GF_Node *n, GF_DOM_Event *event, GF_Node *observer); + Bool (*handler_execute)(GF_Node *n, GF_DOM_Event *event, GF_Node *observer, char *utf8_script); u32 nb_scripts; /*global script context for the scene*/ struct JSContext *js_ctx; diff --git a/include/gpac/internal/terminal_dev.h b/include/gpac/internal/terminal_dev.h index 383632f..4cb5f40 100644 --- a/include/gpac/internal/terminal_dev.h +++ b/include/gpac/internal/terminal_dev.h @@ -70,6 +70,10 @@ struct _net_service GF_List *dnloads; /*cache asscoiated with service, if any*/ GF_StreamingCache *cache; + + /*quick hack for avoiding double session creation*/ + GF_DownloadSession *pending_service_session; + }; @@ -169,6 +173,8 @@ struct _scene /*FIXME - Dynamic scenes are only supported through VRML/BIFS nodes, we should add support for SVG scene graph generation if needed*/ Bool is_dynamic_scene; + /*for MPEG-2 TS, indicates the current serviceID played from mux*/ + u32 selected_service_id; /*clock for dynamic scene - current assumption is that all selected streams are synchronized in the dyn scene*/ GF_Clock *dyn_ck; /*URLs of current video, audio and subs (we can't store objects since they may be destroyed when seeking)*/ @@ -350,6 +356,8 @@ struct _tag_terminal /*net services*/ GF_List *net_services; + /*net services to be connected*/ + GF_List *net_services_to_connect; /*net services to be destroyed*/ GF_List *net_services_to_remove; /*channels waiting for service CONNECT ack to be setup*/ @@ -396,7 +404,6 @@ struct _tag_terminal GF_Shortcut shortcuts[MAX_SHORTCUTS]; Fixed speed_ratio; - }; @@ -484,6 +491,7 @@ struct _object_clock u32 discontinuity_time; s32 drift; u32 data_timeout; + Bool probe_ocr; }; /*destroys clock*/ @@ -575,7 +583,7 @@ struct _es_channel /*last received AU time - if exceeding a certain time and buffering is on, buffering is turned off. This is needed for streams with very short duration (less than buffer time) and stream with only one AU (BIFS/OD)*/ u32 last_au_time; - /*Current reassemnbling buffer - currently packets are NOT reordered, only AUs are*/ + /*Current reassembling buffer - currently packets are NOT reordered, only AUs are*/ char *buffer; u32 len, allocSize; /*only for last packet of an AU*/ @@ -641,6 +649,9 @@ struct _es_channel GF_IPMPTool *ipmp_tool; Bool is_protected; + /*indicates that AU received will be copied to the composition memory*/ + Bool is_raw_channel; + u32 resync_drift; /*TSs as received from network - these are used for cache storage*/ @@ -679,6 +690,8 @@ these channels are ALWAYS pulling ones, and this function will init the channel void gf_es_init_dummy(GF_Channel *ch); /*setup DRM info*/ void gf_es_config_drm(GF_Channel *ch, GF_NetComDRMConfig *isma_cryp); +/*dispatch raw media AU to the composition buffer and BLOCKS until the AU is consumed by the decoder*/ +void gf_es_dispatch_raw_media_au(GF_Channel *ch, char *payload, u32 payload_size, u32 cts); /* decoder stuff @@ -710,6 +723,9 @@ enum GF_ESM_CODEC_IS_USE = 1<<1, /*set for OD codec when static (ressources are declared in OD stream esd a la ISMA*/ GF_ESM_CODEC_IS_STATIC_OD = 1<<2, + /*set when codec is identified as RAW, meaning all AU comming from the network are directly + dispatched to the composition memory*/ + GF_ESM_CODEC_IS_RAW_MEDIA = 1<<3, }; struct _generic_codec @@ -797,6 +813,8 @@ enum /*flag set if object has been started before any start request from the scene*/ GF_ODM_PREFETCH = (1<<8), + /*flag set if object has been deleted*/ + GF_ODM_DESTROYED = (1<<9), /*dynamic flags*/ /*flag set if associated subscene must be regenerated*/ @@ -809,7 +827,6 @@ enum GF_ODM_STATE_PLAY, GF_ODM_STATE_IN_SETUP, GF_ODM_STATE_BLOCKED, - GF_ODM_STATE_DESTROYED, }; enum @@ -872,6 +889,9 @@ struct _od_manager u32 action_type; +// u32 raw_media_frame_pending; + GF_Semaphore *raw_frame_sema; + #ifndef GPAC_DISABLE_VRML /*the one and only media control currently attached to this object*/ struct _media_control *media_ctrl; @@ -1001,6 +1021,10 @@ void gf_term_service_media_event(GF_ObjectManager *odm, u32 event_type); /*checks the URL and returns the ODID (MPEG-4 od://) or GF_MEDIA_EXTERNAL_ID for all regular URLs*/ u32 gf_mo_get_od_id(MFURL *url); +void gf_scene_generate_views(GF_Scene *scene, char *url); + +GF_Err gf_codec_process_private_media(GF_Codec *codec, u32 TimeAvailable); + #ifdef __cplusplus } #endif diff --git a/include/gpac/isomedia.h b/include/gpac/isomedia.h index ce36dda..03bf281 100644 --- a/include/gpac/isomedia.h +++ b/include/gpac/isomedia.h @@ -100,7 +100,9 @@ enum /*Opens an existing file in EDIT mode*/ GF_ISOM_OPEN_EDIT, /*Creates a new file in EDIT mode*/ - GF_ISOM_WRITE_EDIT + GF_ISOM_WRITE_EDIT, + /*Opens an existing file for fragment concatenation*/ + GF_ISOM_OPEN_CAT_FRAGMENTS, }; /*Movie Options for file writing*/ @@ -478,6 +480,12 @@ u64 gf_isom_get_sample_dts(GF_ISOFile *the_file, u32 trackNumber, u32 sampleNumb /*returns sample duration in media timeScale*/ u32 gf_isom_get_sample_duration(GF_ISOFile *the_file, u32 trackNumber, u32 sampleNumber); +/*returns sample size in bytes*/ +u32 gf_isom_get_sample_size(GF_ISOFile *the_file, u32 trackNumber, u32 sampleNumber); + +/*returns sync flag of sample*/ +u8 gf_isom_get_sample_sync(GF_ISOFile *the_file, u32 trackNumber, u32 sampleNumber); + /*gets a sample given a desired decoding time IN MEDIA TIME SCALE and set the StreamDescIndex of this sample this index allows to retrieve the stream description if needed (2 media in 1 track) @@ -591,6 +599,9 @@ return -1 if error, 0 if the reference is a NULL one, or the trackNumber */ GF_Err gf_isom_get_reference(GF_ISOFile *the_file, u32 trackNumber, u32 referenceType, u32 referenceIndex, u32 *refTrack); +/*Return 1 if the given track has a reference to the given TreckID of a given ReferenceType, 0 otherwise*/ +Bool gf_isom_has_track_reference(GF_ISOFile *movie, u32 trackNumber, u32 referenceType, u32 refTrackID); + u8 gf_isom_get_pl_indication(GF_ISOFile *the_file, u8 PL_Code); /*locates the first ObjectDescriptor using the given track by inspecting any OD tracks*/ @@ -640,6 +651,9 @@ GF_Err gf_isom_get_track_matrix(GF_ISOFile *the_file, u32 trackNumber, u32 matri /*returns width and height of the given visual sample desc - error if not a visual track*/ GF_Err gf_isom_get_pixel_aspect_ratio(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex, u32 *hSpacing, u32 *vSpacing); +/*gets RVC config of given sample description*/ +GF_Err gf_isom_get_rvc_config(GF_ISOFile *movie, u32 track, u32 sampleDescriptionIndex, u16 *rvc_predefined, char **data, u32 *size, const char **mime); + /* User Data Manipulation (cf write API too) */ @@ -769,6 +783,9 @@ fragmented options such as MPEG-4 video packets. This will update the data size. CANNOT be used with OD media type*/ GF_Err gf_isom_append_sample_data(GF_ISOFile *the_file, u32 trackNumber, char *data, u32 data_size); +/*sets RAP flag of last sample added to TRUE*/ +GF_Err gf_isom_set_sample_rap(GF_ISOFile *movie, u32 trackNumber); + /*Add sample references to a track. The dataOffset is the offset of the data in the referenced file you MUST have created a StreamDescription with URL or URN specifying your referenced file Use streamDescriptionIndex to specify the desired stream (if several)*/ @@ -967,6 +984,9 @@ GF_Err gf_isom_set_media_language(GF_ISOFile *the_file, u32 trackNumber, char *t /*removes given stream description*/ GF_Err gf_isom_remove_sample_description(GF_ISOFile *the_file, u32 trackNumber, u32 streamDescIndex); +/*sets the RVC config for the given track sample description*/ +GF_Err gf_isom_set_rvc_config(GF_ISOFile *movie, u32 track, u32 sampleDescriptionIndex, u16 rvc_predefined, char *mime, char *data, u32 size); + /* some authoring extensions */ @@ -1123,14 +1143,11 @@ GF_Err gf_isom_start_fragment(GF_ISOFile *movie, Bool moof_first); /*starts a new segment in the file. If SegName is given, the output will be written in the SegName file*/ GF_Err gf_isom_start_segment(GF_ISOFile *movie, char *SegName); -typedef struct -{ - u32 track_ID; - u64 decoding_time; -} GF_SIDXTrackTimes; +/*sets the baseMediaDecodeTime of the first sample of the given track*/ +GF_Err gf_isom_set_traf_base_media_decode_time(GF_ISOFile *movie, u32 TrackID, u64 decode_time); -/*closes current segment*/ -GF_Err gf_isom_close_segment(GF_ISOFile *movie, u32 fragments_per_sidx, u32 referenceTrackID, GF_SIDXTrackTimes *tracks_times, u32 nb_times, Bool daisy_chain_sidx); +/*closes current segment - if fragments_per_sidx is <0, no sidx is used - if fragments_per_sidx is ==0, a single sidx is used*/ +GF_Err gf_isom_close_segment(GF_ISOFile *movie, s32 fragments_per_sidx, u32 referenceTrackID, u64 ref_track_decode_time, Bool daisy_chain_sidx, Bool last_segment); enum { @@ -1753,9 +1770,15 @@ u32 gf_isom_get_meta_item_by_id(GF_ISOFile *file, Bool root_meta, u32 track_num, /*extracts item from given meta @item_num: 1-based index of item to query + @dump_file_name: if NULL, use item name for dumping */ GF_Err gf_isom_extract_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num, u32 item_num, const char *dump_file_name); +/*extracts item from given meta in memory + @item_num: 1-based index of item to query +*/ +GF_Err gf_isom_extract_meta_item_mem(GF_ISOFile *file, Bool root_meta, u32 track_num, u32 item_id, char **out_data, u32 *out_size, const char **mime_type); + /*retirves primary item ID, 0 if none found (primary can also be stored through meta XML)*/ u32 gf_isom_get_meta_primary_item_id(GF_ISOFile *file, Bool root_meta, u32 track_num); @@ -1784,6 +1807,8 @@ GF_Err gf_isom_set_meta_xml_memory(GF_ISOFile *file, Bool root_meta, u32 track_n @URL, @URN: if set, resource will be remote (same as stream descriptions) */ GF_Err gf_isom_add_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num, Bool self_reference, char *resource_path, const char *item_name, const char *mime_type, const char *content_encoding, const char *URL, const char *URN); +/*same as above excepts take the item directly in memory*/ +GF_Err gf_isom_add_meta_item_memory(GF_ISOFile *file, Bool root_meta, u32 track_num, const char *item_name, const char *mime_type, const char *content_encoding, char *data, u32 data_len); /*removes item from meta*/ GF_Err gf_isom_remove_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num, u32 item_num); @@ -1931,18 +1956,22 @@ GF_Err gf_isom_ac3_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_AC3Confi /*returns the number of subsamples in the given sample */ u32 gf_isom_sample_has_subsamples(GF_ISOFile *movie, u32 track, u32 sampleNumber); -GF_Err gf_isom_sample_get_subsample(GF_ISOFile *movie, u32 track, u32 sampleNumber, u32 subSampleNumber, u32 *size, u8 *priority, Bool *discardable); +GF_Err gf_isom_sample_get_subsample(GF_ISOFile *movie, u32 track, u32 sampleNumber, u32 subSampleNumber, u32 *size, u8 *priority, u32 *reserved, Bool *discardable); #ifndef GPAC_DISABLE_ISOM_WRITE /*adds subsample information to a given sample. Subsample information shall be added in increasing order of sampleNumbers, insertion of information is not supported. Note that you may add subsample information for samples not yet added to the file specifying 0 as subSampleSize will remove the last subsample information if any*/ -GF_Err gf_isom_add_subsample(GF_ISOFile *movie, u32 track, u32 sampleNumber, u32 subSampleSize, u32 priority, Bool discardable); +GF_Err gf_isom_add_subsample(GF_ISOFile *movie, u32 track, u32 sampleNumber, u32 subSampleSize, u8 priority, u32 reserved, Bool discardable); #endif /*add subsample information for the latest sample added to the current track fragment*/ -GF_Err gf_isom_fragment_add_subsample(GF_ISOFile *movie, u32 TrackID, u32 subSampleSize, u32 priority, Bool discardable); +GF_Err gf_isom_fragment_add_subsample(GF_ISOFile *movie, u32 TrackID, u32 subSampleSize, u8 priority, u32 reserved, Bool discardable); /*copy over the subsample information of the given sample from the source track/file to the last sample added to the current track fragment of the destination file*/ GF_Err gf_isom_fragment_copy_subsample(GF_ISOFile *dest, u32 TrackID, GF_ISOFile *orig, u32 track, u32 sampleNumber); +/*gets the number of the next moof to be produced*/ +u32 gf_isom_get_next_moof_number(GF_ISOFile *movie); +/*Sets the number of the next moof to be produced*/ +void gf_isom_set_next_moof_number(GF_ISOFile *movie, u32 value); #endif /*GPAC_DISABLE_ISOM*/ diff --git a/include/gpac/media_tools.h b/include/gpac/media_tools.h index a05efdf..1f6bb73 100644 --- a/include/gpac/media_tools.h +++ b/include/gpac/media_tools.h @@ -91,6 +91,10 @@ enum /* oversampled SBR */ GF_IMPORT_OVSBR = 1<<14, + /* set subsample information with SVC*/ + GF_IMPORT_SET_SUBSAMPLES = 1<<15, + + /*when set, only updates tracks info and return*/ GF_IMPORT_PROBE_ONLY = 1<<20, /*only set when probing, signals several frames per sample possible*/ @@ -105,6 +109,9 @@ enum GF_IMPORT_DO_ABORT = 1<<31 }; +#define GF_IMPORT_DEFAULT_FPS 25.0 +#define GF_IMPORT_AUTO_FPS 10000.0 + #define GF_IMPORT_MAX_TRACKS 100 struct __track_video_info { @@ -212,7 +219,7 @@ GF_Err gf_media_import_chapters(GF_ISOFile *file, char *chap_file, Double import /*save file as fragmented movie @dash_mode: 0 = DASH not used, 1 = DASH used without GOP spliting, 2 = DASH used with GOP spliting, */ -GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_duration_sec, u32 dash_mode, Double dash_duration_sec, char *seg_rad_name, char *seg_ext, u32 fragments_per_sidx, Bool daisy_chain_sidx, Bool use_url_template); +GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_duration_sec, u32 dash_mode, Double dash_duration_sec, char *seg_rad_name, char *seg_ext, s32 fragments_per_sidx, Bool daisy_chain_sidx, Bool use_url_template, const char *dash_ctx); /*make the file ISMA compliant: creates ISMA BIFS / OD tracks if needed, and update audio/video IDs the file should not contain more than one audio and one video track @@ -234,6 +241,9 @@ GF_Err gf_media_change_par(GF_ISOFile *file, u32 track, s32 ar_num, s32 ar_den); /*changes the profile (if not 0) and level (if not 0) indication of the media - only AVC/H264 supported for now*/ GF_Err gf_media_change_pl(GF_ISOFile *file, u32 track, u32 profile, u32 level); +/*rewrite AVC samples if nalu size_length has to be changed*/ +GF_Err gf_media_avc_rewrite_samples(GF_ISOFile *file, u32 track, u32 prev_size_in_bits, u32 new_size_in_bits); + #endif /*GPAC_DISABLE_MEDIA_IMPORT*/ diff --git a/include/gpac/mediaobject.h b/include/gpac/mediaobject.h index 5873f05..897edf5 100644 --- a/include/gpac/mediaobject.h +++ b/include/gpac/mediaobject.h @@ -125,7 +125,8 @@ Bool gf_mo_has_audio(GF_MediaObject *mo); /*checks if the service associated withthis object has an audio stream*/ Bool gf_mo_is_private_media(GF_MediaObject *mo); -void gf_mo_set_position(GF_MediaObject *mo, GF_Window *src, GF_Window *dst); +/*set destination window for harware codecs directly outputing to video out - returns 1 if video size has changed*/ +Bool gf_mo_set_position(GF_MediaObject *mo, GF_Window *src, GF_Window *dst); enum { diff --git a/include/gpac/modules/codec.h b/include/gpac/modules/codec.h index ee9c196..14bb2cf 100644 --- a/include/gpac/modules/codec.h +++ b/include/gpac/modules/codec.h @@ -111,6 +111,8 @@ enum /*this is only used for audio in case transport mapping relies on sampleRate (RTP) gets the CU duration in samplerate unit (type: int) */ GF_CODEC_CU_DURATION, + /*queries whether data is RAW (directly dispatched to CompositionMemory) or not*/ + GF_CODEC_RAW_MEDIA, /*This is only called on scene decoders to signal that potential overlay scene should be showed (cap.valueINT=1) or hidden (cap.valueINT=0). Currently only used with SetCap*/ @@ -128,6 +130,18 @@ enum }; +enum +{ + /*stream format is NOT supported by this codec*/ + GF_CODEC_NOT_SUPPORTED = 0, + /*stream type (eg audio, video) is supported by this codec*/ + GF_CODEC_STREAM_TYPE_SUPPORTED = 1, + /*stream format may be (partially) supported by this codec*/ + GF_CODEC_MAYBE_SUPPORTED = 127, + /*stream format is supported by this codec*/ + GF_CODEC_SUPPORTED = 255, +}; + /* Generic interface used by both media decoders and scene decoders @AttachStream: Add a Stream to the codec. If DependsOnESID is NULL, the stream is a base layer @@ -143,7 +157,7 @@ enum Set the desired capability given its code if possible if the codec does not support the request capability, return GF_NOT_SUPPORTED @CanHandleStream - Can module handle this codec? Return 0 if No and !0 otherwise + Can module handle this codec? Return one of GF_CODEC_NOT_SUPPORTED, GF_CODEC_MAYBE_SUPPORTED or GF_CODEC_SUPPORTED esd is provided for more advanced inspection ( eg MPEG4 audio/visual where a bunch of codecs are defined with same objectType). If esd is NULL, only decoder type is checked (audio or video), not codec type @GetDecoderName @@ -158,7 +172,7 @@ enum GF_Err (*DetachStream)(IFCE_NAME, u16 ES_ID);\ GF_Err (*GetCapabilities)(IFCE_NAME, GF_CodecCapability *capability);\ GF_Err (*SetCapabilities)(IFCE_NAME, GF_CodecCapability capability);\ - Bool (*CanHandleStream)(IFCE_NAME, u32 StreamType, GF_ESD *esd, u8 ProfileLevelIndication);\ + u32 (*CanHandleStream)(IFCE_NAME, u32 StreamType, GF_ESD *esd, u8 ProfileLevelIndication);\ const char *(*GetName)(IFCE_NAME);\ void *privateStack; \ diff --git a/include/gpac/modules/service.h b/include/gpac/modules/service.h index 13d79ca..fb74d09 100644 --- a/include/gpac/modules/service.h +++ b/include/gpac/modules/service.h @@ -31,6 +31,7 @@ extern "C" { /*for SL, ESD and OD*/ #include +#include #include /*handle to service*/ @@ -39,7 +40,7 @@ typedef struct _net_service GF_ClientService; /*handle to channel*/ typedef void *LPNETCHANNEL; -enum +typedef enum { /*channel control, app->module. Note that most modules don't need to handle pause/resume/set_speed*/ GF_NET_CHAN_PLAY, @@ -94,9 +95,12 @@ enum /*instructs the service to get the migration info - term->net only*/ GF_NET_SERVICE_MIGRATION_INFO, + /*When using DASH or playlists, query the next file to concatenate to thecurrent one net->proxy only*/ + GF_NET_SERVICE_QUALITY_SWITCH, + /*When using DASH or playlists, query the next file to concatenate to thecurrent one net->proxy only*/ GF_NET_SERVICE_QUERY_NEXT, -}; +} GF_NET_CHAN_CMD; /*channel command for all commands that don't need params: GF_NET_CHAN_SET_PULL: module shall return GF_OK or GF_NOT_SUPPORTED @@ -260,6 +264,7 @@ typedef struct u32 command_type; LPNETCHANNEL on_channel; u32 hSpacing, vSpacing; + u32 width, height, pixel_format; } GF_NetComPixelAR; /*GF_NET_SERVICE_INFO*/ @@ -304,6 +309,16 @@ typedef struct const char *next_url; } GF_NetURLQuery; +/*GF_NET_SERVICE_QUALITY_SWITCH*/ +typedef struct +{ + u32 command_type; + /*currently NULL only*/ + LPNETCHANNEL on_channel; + /*out: next url to play after current one*/ + Bool up; +} GF_NetQualitySwitch; + typedef union __netcommand { u32 command_type; @@ -323,6 +338,7 @@ typedef union __netcommand GF_NetComHasAudio audio; GF_NetComMigration migrate; GF_NetURLQuery url_query; + GF_NetQualitySwitch switch_quality; } GF_NetworkCommand; /* @@ -337,7 +353,7 @@ typedef struct _netinterface /* interface declaration*/ GF_DECL_MODULE_INTERFACE - /*retuns 1 if module can process this URL, 0 otherwise. This is only called when the file extension/mimeType cannot be + /*returns 1 if module can process this URL, 0 otherwise. This is only called when the file extension/mimeType cannot be retrieved in the cfg file, otherwise the mime type/file ext is used to load service. Typically a module would register its mime types in this function (cf gf_term_register_mime_type below) */ @@ -451,6 +467,8 @@ no_scene_check: specifies if the scene description shall be rebuilt or not. */ void gf_term_add_media(GF_ClientService *service, GF_Descriptor *media_desc, Bool no_scene_update); +Bool gf_term_on_service_event(GF_ClientService *service, GF_Event *service_event); + /*check if @fileExt extension is supported for given mimeType, and if associated with module. If mimeType not registered, register it for given module*/ Bool gf_term_check_extension(GF_InputService *ifce, const char *mimeType, const char *extList, const char *description, const char *fileExt); diff --git a/include/gpac/mpeg4_odf.h b/include/gpac/mpeg4_odf.h index fdafff4..787a542 100644 --- a/include/gpac/mpeg4_odf.h +++ b/include/gpac/mpeg4_odf.h @@ -156,6 +156,11 @@ typedef struct /*includes BOTH IPMP_DescriptorPointer (IPMP & IPMPX) and GF_IPMP_Descriptor (IPMPX only)*/ GF_List *IPMP_Descriptors; GF_List *extensionDescriptors; + /*MPEG-2 (or other service mux formats) service ID*/ + u16 ServiceID; + /*pointer to the service interface (GF_InputService) of the service having declared the object + only used for DASH*/ + void *service_ifce; } GF_ObjectDescriptor; /*GF_InitialObjectDescriptor - WARNING: even though the bitstream IOD is not @@ -171,6 +176,11 @@ typedef struct /*includes BOTH IPMP_DescriptorPointer (IPMP & IPMPX) and GF_IPMP_Descriptor (IPMPX only)*/ GF_List *IPMP_Descriptors; GF_List *extensionDescriptors; + /*MPEG-2 (or other service mux formats) service ID*/ + u16 ServiceID; + /*pointer to the service interface (GF_InputService) of the service having declared the object + only used for DASH*/ + void *service_ifce; /*IOD extensions*/ u8 inlineProfileFlag; @@ -235,7 +245,8 @@ typedef struct { typedef struct { BASE_DESCRIPTOR - u8 objectTypeIndication; + /*coded on 8 bit, but we use 32 bits for internal signaling in GPAC to enable usage of 4CC*/ + u32 objectTypeIndication; u8 streamType; u8 upstream; u32 bufferSizeDB; @@ -243,10 +254,13 @@ typedef struct u32 avgBitrate; GF_DefaultDescriptor *decoderSpecificInfo; - /*placeholder for RVC decoder config*/ + /*placeholder for RVC decoder config if any*/ + u16 predefined_rvc_config; GF_DefaultDescriptor *rvc_config; GF_List *profileLevelIndicationIndexDescriptor; + /*pass through data for some modules*/ + void *udta; } GF_DecoderConfig; diff --git a/include/gpac/mpegts.h b/include/gpac/mpegts.h index 17e4248..f119b12 100644 --- a/include/gpac/mpegts.h +++ b/include/gpac/mpegts.h @@ -40,6 +40,9 @@ typedef struct tag_m2ts_demux GF_M2TS_Demuxer; typedef struct tag_m2ts_es GF_M2TS_ES; typedef struct tag_m2ts_section_es GF_M2TS_SECTION_ES; +#ifdef GPAC_HAS_LINUX_DVB +typedef struct __gf_dvb_tuner GF_Tuner; +#endif /*Maximum number of streams in a TS*/ #define GF_M2TS_MAX_STREAMS 8192 @@ -47,8 +50,8 @@ typedef struct tag_m2ts_section_es GF_M2TS_SECTION_ES; /*Maximum number of service in a TS*/ #define GF_M2TS_MAX_SERVICES 65535 -/*When ODProfileLevelIndication has this value, only scene and od streams are sl-packetized*/ -#define GPAC_MAGIC_OD_PROFILE_FOR_MPEG4_SIGNALING 10 +/*Maximum size of the buffer in UDP */ +#define UDP_BUFFER_SIZE 0x40000 /*MPEG-2 TS Media types*/ enum @@ -170,11 +173,11 @@ enum GF_M2TS_EVT_EIT_OTHER_PF, /* An EIT message for the schedule of an other TS has been received */ GF_M2TS_EVT_EIT_OTHER_SCHEDULE, +#endif /* A message to inform about the current date and time in the TS */ GF_M2TS_EVT_TDT, /* A message to inform about the current time offset in the TS */ GF_M2TS_EVT_TOT, -#endif /* A generic event message for EIT, TDT, TOT etc */ GF_M2TS_EVT_DVB_GENERAL, /* MPE / MPE-FEC frame extraction and IP datagrams decryptation */ @@ -185,6 +188,9 @@ enum GF_M2TS_EVT_CAT_REPEAT, /*PMT has been changed - assoctiated parameter: updated PMT*/ GF_M2TS_EVT_CAT_UPDATE, + /*AIT has been found (carousel) */ + GF_M2TS_EVT_AIT_FOUND, + }; enum @@ -280,6 +286,10 @@ typedef struct used to compute PCR interpolation value*/ u64 before_last_pcr_value; u32 before_last_pcr_value_pck_number; + + /*for hybrid use-cases we need to know if TDT has already been processed*/ + Bool tdt_found; + } GF_M2TS_Program; /*ES flags*/ @@ -379,6 +389,10 @@ typedef struct tag_m2ts_pes Bool rap; u64 PTS, DTS; u32 pes_end_packet_number; + /*bytes not consumed from previous PES - shall be less than 9*/ + unsigned char *prev_data; + /*number of bytes not consumed from previous PES - shall be less than 9*/ + u32 prev_data_len; u32 pes_start_packet_number; /* PCR info related to the PES start */ @@ -393,8 +407,8 @@ typedef struct tag_m2ts_pes /*PES reframer - if NULL, pes processing is skiped*/ u32 frame_state; - /*returns the number of bytes consummed from the input data buffer*/ - void (*reframe)(struct tag_m2ts_demux *ts, struct tag_m2ts_pes *pes, u64 DTS, u64 CTS, unsigned char *data, u32 data_len); + /*returns the number of bytes NOT consummed from the input data buffer - these bytes are kept when reassembling the next PES packet*/ + u32 (*reframe)(struct tag_m2ts_demux *ts, struct tag_m2ts_pes *pes, u64 DTS, u64 CTS, unsigned char *data, u32 data_len); /*LATM stuff - should be moved out of mpegts*/ unsigned char *buf; u32 buf_len; @@ -427,6 +441,16 @@ typedef struct u32 logical_channel_number; } GF_M2TS_NIT; +typedef struct +{ + u16 year; + u8 month; + u8 day; + u8 hour; + u8 minute; + u8 second; +} GF_M2TS_TDT_TOT; + #define GF_M2TS_BASE_DESCRIPTOR u32 tag; typedef struct { @@ -526,10 +550,48 @@ typedef struct /*MPEG-2 TS demuxer*/ struct tag_m2ts_demux { + /* From M2TSIn */ + GF_List *requested_progs; + GF_List *requested_pids; + + /*demuxer thread*/ + GF_Thread *th; + u32 run_state; + + /*net playing*/ + GF_Socket *sock; + +#ifdef GPAC_HAS_LINUX_DVB + /*dvb playing*/ + GF_Tuner *tuner; +#endif + /*local file playing*/ + FILE *file; + char filename[GF_MAX_PATH]; + u32 start_range, end_range; + u64 file_size; + Double duration; + u32 nb_playing; + Bool file_regulate; + u64 pcr_last; + u32 stb_at_last_pcr; + u32 nb_pck; + Bool loop_demux; + + /* "Network" = "MobileIP", "DefaultMCastInterface" */ + Bool MobileIPEnabled; + const char *network_type; + /* Set it to 1 if the TS is meant to be played during the demux */ + Bool demux_and_play; + /* End of M2TSIn */ + GF_M2TS_ES *ess[GF_M2TS_MAX_STREAMS]; GF_List *programs; + u32 nb_prog_pmt_received; + Bool all_prog_pmt_received; /*keep it seperate for now - TODO check if we're sure of the order*/ GF_List *SDTs; + GF_M2TS_TDT_TOT *TDT_time; /*UTC time from both TDT and TOT (we currently ignore local offset)*/ /*user callback - MUST NOT BE NULL*/ void (*on_event)(struct tag_m2ts_demux *ts, u32 evt_type, void *par); @@ -540,7 +602,7 @@ struct tag_m2ts_demux char *buffer; u32 buffer_size, alloc_size; /*default transport PID filters*/ - GF_M2TS_SectionFilter *pat, *cat, *nit, *sdt, *eit, *tdt_tot_st; + GF_M2TS_SectionFilter *pat, *cat, *nit, *sdt, *eit, *tdt_tot; Bool has_4on2; /* analyser */ @@ -549,12 +611,21 @@ struct tag_m2ts_demux Bool direct_mpe; Bool dvb_h_demux; + /*user callback - MUST NOT BE NULL*/ void (*on_mpe_event)(struct tag_m2ts_demux *ts, u32 evt_type, void *par); /* Structure to hold all the INT tables if the TS contains IP streams */ struct __gf_dvb_mpe_ip_platform *ip_platform; - + u32 pck_number; + + /*remote file handling - created and destroyed by user*/ + struct __gf_download_session *dnload; + + const char *dvb_channels_conf_path; + + const char *(*query_next)(void *udta); + void *udta_query; }; GF_M2TS_Demuxer *gf_m2ts_demux_new(); @@ -563,6 +634,7 @@ void gf_m2ts_reset_parsers(GF_M2TS_Demuxer *ts); GF_ESD *gf_m2ts_get_esd(GF_M2TS_ES *es); GF_Err gf_m2ts_set_pes_framing(GF_M2TS_PES *pes, u32 mode); GF_Err gf_m2ts_process_data(GF_M2TS_Demuxer *ts, char *data, u32 data_size); +u32 gf_dvb_get_freq_from_url(const char *channels_config_path, const char *url); @@ -599,6 +671,7 @@ enum /* ... */ GF_M2TS_AVC_TIMING_HRD_DESCRIPTOR = 0x2A, /* ... */ + GF_M2TS_MPEG4_ODUPDATE_DESCRIPTOR = 0x35, /* 0x2D - 0x3F - ISO/IEC 13818-6 values */ /* 0x40 - 0xFF - User Private values */ @@ -650,11 +723,11 @@ enum { GF_M2TS_PID_TSDT = 0x0002, /* reserved 0x0003 to 0x000F */ GF_M2TS_PID_NIT_ST = 0x0010, - GF_M2TS_PID_SDT_BAT_ST = 0x0011, - GF_M2TS_PID_EIT_ST_CIT = 0x0012, + GF_M2TS_PID_SDT_BAT_ST = 0x0011, + GF_M2TS_PID_EIT_ST_CIT = 0x0012, GF_M2TS_PID_RST_ST = 0x0013, - GF_M2TS_PID_TDT_TOT_ST = 0x0014, - GF_M2TS_PID_NET_SYNC = 0x0015, + GF_M2TS_PID_TDT_TOT_ST = 0x0014, + GF_M2TS_PID_NET_SYNC = 0x0015, GF_M2TS_PID_RNT = 0x0016, /* reserved 0x0017 to 0x001B */ GF_M2TS_PID_IN_SIG = 0x001C, @@ -672,10 +745,10 @@ enum { GF_M2TS_TABLE_ID_MPEG4_BIFS = 0x04, /* max size for section 4096 */ GF_M2TS_TABLE_ID_MPEG4_OD = 0x05, /* max size for section 4096 */ GF_M2TS_TABLE_ID_METADATA = 0x06, - GF_M2TS_TABLE_ID_IPMP_CONTROL = 0x07, + GF_M2TS_TABLE_ID_IPMP_CONTROL = 0x07, /* 0x08 - 0x37 reserved */ /* 0x38 - 0x3D DSM-CC defined */ - GF_M2TS_TABLE_ID_DSM_CC_PRIVATE = 0x3E, /* used for MPE (only, not MPE-FEC) */ + GF_M2TS_TABLE_ID_DSM_CC_PRIVATE = 0x3E, /* used for MPE (only, not MPE-FEC) */ /* 0x3F DSM-CC defined */ GF_M2TS_TABLE_ID_NIT_ACTUAL = 0x40, /* max size for section 1024 */ GF_M2TS_TABLE_ID_NIT_OTHER = 0x41, @@ -688,20 +761,20 @@ enum { GF_M2TS_TABLE_ID_INT = 0x4c, /* max size for section 4096 */ /* 0x4d reserved */ - GF_M2TS_TABLE_ID_EIT_ACTUAL_PF = 0x4E, /* max size for section 4096 */ - GF_M2TS_TABLE_ID_EIT_OTHER_PF = 0x4F, + GF_M2TS_TABLE_ID_EIT_ACTUAL_PF = 0x4E, /* max size for section 4096 */ + GF_M2TS_TABLE_ID_EIT_OTHER_PF = 0x4F, /* 0x50 - 0x6f EIT SCHEDULE */ GF_M2TS_TABLE_ID_EIT_SCHEDULE_MIN = 0x50, GF_M2TS_TABLE_ID_EIT_SCHEDULE_ACTUAL_MAX= 0x5F, GF_M2TS_TABLE_ID_EIT_SCHEDULE_MAX = 0x6F, - GF_M2TS_TABLE_ID_TDT = 0x70, + GF_M2TS_TABLE_ID_TDT = 0x70, /* max size for section 1024 */ GF_M2TS_TABLE_ID_RST = 0x71, /* max size for section 1024 */ GF_M2TS_TABLE_ID_ST = 0x72, /* max size for section 4096 */ - GF_M2TS_TABLE_ID_TOT = 0x73, - GF_M2TS_TABLE_ID_AI = 0x74, + GF_M2TS_TABLE_ID_TOT = 0x73, /* max size for section 1024 */ + GF_M2TS_TABLE_ID_AIT = 0x74, GF_M2TS_TABLE_ID_CONT = 0x75, - GF_M2TS_TABLE_ID_RC = 0x76, + GF_M2TS_TABLE_ID_RC = 0x76, GF_M2TS_TABLE_ID_CID = 0x77, GF_M2TS_TABLE_ID_MPE_FEC = 0x78, GF_M2TS_TABLE_ID_RES_NOT = 0x79, @@ -824,6 +897,8 @@ typedef struct __m2ts_mux_stream { /*multiplexer time - NOT THE PCR*/ GF_M2TS_Time time; + /*for PCR strreams, set to 1 when PCR has to be sent, 0 otherwise*/ + u32 pcr_priority; /*table tools*/ GF_M2TS_Mux_Table *tables; @@ -835,22 +910,32 @@ typedef struct __m2ts_mux_stream { u32 current_section_offset; u32 refresh_rate_ms; Bool table_needs_update; + Bool table_needs_send; - Bool (*process)(struct __m2ts_mux *muxer, struct __m2ts_mux_stream *stream); + /*process PES or table update/framing + returns the priority of the stream, 0 meaning not scheduled, 1->N highest priority sent first*/ + u32 (*process)(struct __m2ts_mux *muxer, struct __m2ts_mux_stream *stream); /*PES tools*/ void *pes_packetizer; u32 mpeg2_stream_type; u32 mpeg2_stream_id; + u32 scheduling_priority; GF_ESIPacket curr_pck; /*current packet being processed - does not belong to the packet fifo*/ u32 pck_offset; + u32 next_payload_size, copy_from_next_packets; + u32 pes_data_len, pes_data_remain; Bool force_new; Bool discard_data; + + u32 next_pck_flags; + u64 next_pck_cts, next_pck_dts; + + u32 reframe_overhead; struct __elementary_stream_ifce *ifce; Double ts_scale; - u64 initial_ts; /*packet fifo*/ GF_M2TS_Packet *pck_first, *pck_last; @@ -859,13 +944,11 @@ typedef struct __m2ts_mux_stream { GF_Mutex *mx; /*avg bitrate compute*/ u64 last_br_time; - u32 bytes_since_last_time; + u32 bytes_since_last_time, pes_since_last_time; /*MPEG-4 over MPEG-2*/ u8 table_id; GF_SLHeader sl_header; - /* MPEG-4 SL Config */ - GF_SLConfig sl_config; u32 last_aac_time; } GF_M2TS_Mux_Stream; @@ -873,10 +956,17 @@ typedef struct __m2ts_mux_stream { enum { GF_M2TS_MPEG4_SIGNALING_NONE = 0, GF_M2TS_MPEG4_SIGNALING_FULL, - /*experimental profile where all PES media streams (audio, video, images) are sent directly on PES without SL-packetization*/ + /*MPEG-4 over MPEG-2 profile where PES media streams may be refered to by the scene without SL-packetization*/ GF_M2TS_MPEG4_SIGNALING_SCENE }; +typedef struct __m2ts_base_descriptor +{ + u8 tag; + u8 data_len; + char *data; +} GF_M2TSDescriptor; + struct __m2ts_mux_program { struct __m2ts_mux_program *next; @@ -894,9 +984,15 @@ struct __m2ts_mux_program { GF_M2TS_Time ts_time_at_pcr_init; u64 pcr_init_time, num_pck_at_pcr_init; u64 last_pcr; + u64 last_dts; u32 last_sys_clock; + u64 initial_ts; + Bool initial_ts_set; + u32 pcr_offset; GF_Descriptor *iod; + /*list of GF_M2TSDescriptor to add to the program descriptor loop. By default set to NULL, if non null will be reset and destroyed upon cleanup*/ + GF_List *loop_descriptors; Bool mpeg4_signaling; Bool mpeg4_signaling_for_scene_only; }; @@ -920,6 +1016,9 @@ struct __m2ts_mux { /*output bit-rate in bit/sec*/ u32 bit_rate; + /*init value for PCRs on all streams if 0, random value is used*/ + u64 init_pcr_value; + char dst_pck[188], null_pck[188]; /*multiplexer time, incremented each time a packet is sent @@ -932,12 +1031,16 @@ struct __m2ts_mux { /* System time when the muxer is started */ u32 init_sys_time; + Bool one_au_per_pes; + Bool eos_found; u32 pck_sent_over_br_window, last_br_time, avg_br; u64 tot_pck_sent, tot_pad_sent; }; + + enum { GF_M2TS_STATE_IDLE, @@ -946,25 +1049,73 @@ enum GF_M2TS_STATE_EOS, }; +#define GF_M2TS_PSI_DEFAULT_REFRESH_RATE 200 /*! * mux_rate en kbps */ GF_M2TS_Mux *gf_m2ts_mux_new(u32 mux_rate, u32 pat_refresh_rate, Bool real_time); void gf_m2ts_mux_del(GF_M2TS_Mux *mux); -GF_M2TS_Mux_Program *gf_m2ts_mux_program_add(GF_M2TS_Mux *muxer, u32 program_number, u32 pmt_pid, u32 pmt_refresh_rate, Bool mpeg4_signaling); -GF_M2TS_Mux_Stream *gf_m2ts_program_stream_add(GF_M2TS_Mux_Program *program, GF_ESInterface *ifce, u32 pid, Bool is_pcr); -void gf_m2ts_mux_update_config(GF_M2TS_Mux *mux, Bool reset_time); +GF_M2TS_Mux_Program *gf_m2ts_mux_program_add(GF_M2TS_Mux *muxer, u32 program_number, u32 pmt_pid, u32 pmt_refresh_rate, u32 pcr_offset, Bool mpeg4_signaling); +GF_M2TS_Mux_Stream *gf_m2ts_program_stream_add(GF_M2TS_Mux_Program *program, GF_ESInterface *ifce, u32 pid, Bool is_pcr, Bool force_pes_mode); +void gf_m2ts_mux_update_config(GF_M2TS_Mux *mux, Bool reset_time); +void gf_m2ts_mux_update_bitrate(GF_M2TS_Mux *mux); + const char *gf_m2ts_mux_process(GF_M2TS_Mux *muxer, u32 *status); u32 gf_m2ts_get_sys_clock(GF_M2TS_Mux *muxer); u32 gf_m2ts_get_ts_clock(GF_M2TS_Mux *muxer); +/*set muxer in/out single-au pes mode. In this mode, each PES contains one and only one AU*/ +GF_Err gf_m2ts_mux_use_single_au_pes_mode(GF_M2TS_Mux *muxer, Bool strict_au_pes_mode); +GF_Err gf_m2ts_mux_set_initial_pcr(GF_M2TS_Mux *muxer, u64 init_pcr_value); + /*user inteface functions*/ GF_Err gf_m2ts_program_stream_update_ts_scale(GF_ESInterface *_self, u32 time_scale); -void gf_m2ts_program_stream_update_sl_config(GF_ESInterface *_self, GF_SLConfig *slc); #endif /*GPAC_DISABLE_MPEG2TS_MUX*/ +/******************* Demux DVB ****************************/ +#include + + +#define UDP_BUFFER_SIZE 0x40000 +#define M2TS_BUFFER_MAX 400 + + +#ifdef GPAC_HAS_LINUX_DVB +#include +#include +#include +#include +#include + +struct __gf_dvb_tuner { + u32 freq; + u16 vpid; + u16 apid; + fe_spectral_inversion_t specInv; + fe_modulation_t modulation; + fe_bandwidth_t bandwidth; + fe_transmit_mode_t TransmissionMode; + fe_guard_interval_t guardInterval; + fe_code_rate_t HP_CodeRate; + fe_code_rate_t LP_CodeRate; + fe_hierarchy_t hierarchy; + + int ts_fd; +}; + + +#define DVB_BUFFER_SIZE 3760 // DVB buffer size 188x20 + +#endif + + +GF_Err TSDemux_Demux_Setup(GF_M2TS_Demuxer *ts, const char *url, Bool loop); +GF_Err TSDemux_DemuxPlay(GF_M2TS_Demuxer *ts); +GF_Err TSDemux_CloseDemux(GF_M2TS_Demuxer *ts); + + #endif /*GPAC_DISABLE_MPEG2TS*/ #endif //_GF_MPEG_TS_H_ diff --git a/include/gpac/nodes_mpeg4.h b/include/gpac/nodes_mpeg4.h index 99e101a..04640a8 100644 --- a/include/gpac/nodes_mpeg4.h +++ b/include/gpac/nodes_mpeg4.h @@ -24,7 +24,7 @@ /* - DO NOT MOFIFY - File generated on GMT Mon Jan 18 12:27:12 2010 + DO NOT MOFIFY - File generated on GMT Wed Jul 20 05:50:21 2011 BY MPEG4Gen for GPAC Version 0.4.6-DEV */ @@ -3185,6 +3185,9 @@ typedef struct _tagCacheTexture SFInt32 expirationDate; /*field*/ SFBool repeatS; /*field*/ SFBool repeatT; /*field*/ + /*GPAC private*/ + u8 *data; + u32 data_len; } M_CacheTexture; diff --git a/include/gpac/options.h b/include/gpac/options.h index bf0ecb9..9fbcba1 100644 --- a/include/gpac/options.h +++ b/include/gpac/options.h @@ -293,6 +293,9 @@ enum GF_OPT_COLLISION, /*set/get gravity*/ GF_OPT_GRAVITY, + + /*get the number of offscreen views in stereo mode, or 1 if no offscreen stereo views are available*/ + GF_OPT_NUM_STEREO_VIEWS, }; #ifdef __cplusplus diff --git a/include/gpac/rtp_streamer.h b/include/gpac/rtp_streamer.h index bda1a1b..7a96f2d 100644 --- a/include/gpac/rtp_streamer.h +++ b/include/gpac/rtp_streamer.h @@ -92,7 +92,7 @@ GF_Err gf_rtp_streamer_append_sdp_extended(GF_RTPStreamer *rtp, u16 ESID, char * GF_Err gf_rtp_streamer_send_au(GF_RTPStreamer *rtp, char *data, u32 size, u64 cts, u64 dts, Bool is_rap); -GF_Err gf_rtp_streamer_send_au_with_sn(GF_RTPStreamer *rtp, char *data, u32 size, u64 cts, u64 dts, Bool is_rap, Bool inc_au_sn); +GF_Err gf_rtp_streamer_send_au_with_sn(GF_RTPStreamer *rtp, char *data, u32 size, u64 cts, u64 dts, Bool is_rap, u32 inc_au_sn); GF_Err gf_rtp_streamer_send_data(GF_RTPStreamer *rtp, char *data, u32 size, u32 fullsize, u64 cts, u64 dts, Bool is_rap, Bool au_start, Bool au_end, u32 au_sn, u32 sampleDuration, u32 sampleDescIndex); diff --git a/include/gpac/scene_manager.h b/include/gpac/scene_manager.h index d95d88f..368af1e 100644 --- a/include/gpac/scene_manager.h +++ b/include/gpac/scene_manager.h @@ -85,7 +85,6 @@ typedef struct _stream_context u32 timeScale; GF_List *AUs; - u64 dump_time_offset; /*last stream AU time, when playing the context directly*/ u64 last_au_time; /*set if stream is part of root OD (playback only)*/ @@ -95,6 +94,9 @@ typedef struct _stream_context char *dec_cfg; u32 dec_cfg_len; + /*time offset when exporting (dumping), max AU time created when importing*/ + u64 imp_exp_time; + u16 aggregate_on_esid; u32 carousel_period; Bool disable_aggregation; diff --git a/include/gpac/setup.h b/include/gpac/setup.h index 89b0ef9..3fbe32d 100644 --- a/include/gpac/setup.h +++ b/include/gpac/setup.h @@ -372,7 +372,12 @@ void gf_memory_print(void); /*prints the state of current allocations*/ #define LLU "%llu" #define LLX "%llx" #define LLXPAD( pad ) "%" pad "llx" + +#ifdef __LP64__ /* Mac OS 64 bits */ +#define PTR_TO_U_CAST (u64) +#else #define PTR_TO_U_CAST (u32) +#endif #elif defined(_LP64) /*Unix 64 bits*/ diff --git a/include/gpac/terminal.h b/include/gpac/terminal.h index f93c88d..cfd5c0b 100644 --- a/include/gpac/terminal.h +++ b/include/gpac/terminal.h @@ -96,6 +96,9 @@ u32 gf_term_get_option(GF_Terminal *term, u32 opt_type); if use_parent_url is set, relative URLs are solved against the current presentation URL*/ Bool gf_term_is_supported_url(GF_Terminal *term, const char *fileName, Bool use_parent_url, Bool no_mime_check); +/*returns the current service ID for MPEG-2 TS mux - returns 0 if no service ID is associated (or not loaded yet)*/ +u32 gf_term_get_current_service_id(GF_Terminal *term); + /*sets simulation frame rate*/ GF_Err gf_term_set_simulation_frame_rate(GF_Terminal * term, Double frame_rate); /*gets simulation frame rate*/ @@ -180,6 +183,11 @@ GF_Err gf_term_get_screen_buffer(GF_Terminal *term, GF_VideoSurface *framebuffer /*releases screen buffer and unlocks graph*/ GF_Err gf_term_release_screen_buffer(GF_Terminal *term, GF_VideoSurface *framebuffer); +/*gets view buffer - this locks the scene graph too until released is called +view_idx ranges from 0 to GF_OPT_NUM_STEREO_VIEWS value +the buffer is released by calling gf_term_release_screen_buffer*/ +GF_Err gf_term_get_offscreen_buffer(GF_Terminal *term, GF_VideoSurface *framebuffer, u32 view_idx, u32 depth_buffer_type); + /*ObjectManager used by both terminal and object browser (term_info.h)*/ typedef struct _od_manager GF_ObjectManager; diff --git a/include/gpac/tools.h b/include/gpac/tools.h index 9236fbc..abc0f09 100644 --- a/include/gpac/tools.h +++ b/include/gpac/tools.h @@ -71,6 +71,14 @@ extern "C" { */ #define GPAC_VERSION_INT 0x00000406 +/*! + * \brief Stringizer + * \hideinitializer + * + * Macro transforming its input name into a string +*/ +#define gf_stringizer(x) #x + /*! * \brief Memory allocation * \hideinitializer @@ -288,6 +296,15 @@ enum */ void gf_log_set_level(u32 level); +/*! + * \brief Log exits at first error assignment + * + * When GF_LOG_ERROR happens, program leaves with instruction exit(1); + * \param strict strict behaviour when encoutering a serious error. + * + */ +void gf_log_set_strict_error(Bool strict); + /*! * GPAC Log tools @@ -340,8 +357,9 @@ enum /*! generic Log for modules*/ GF_LOG_MODULE = 1<<20, /*! log for threads and mutexes */ - GF_LOG_MUTEX = 1<<21 - + GF_LOG_MUTEX = 1<<21, + /*! All logs*/ + GF_LOG_ALL = (1<<22)-1 }; /*! diff --git a/include/gpac/user.h b/include/gpac/user.h index 4f4dd76..4357231 100644 --- a/include/gpac/user.h +++ b/include/gpac/user.h @@ -37,7 +37,7 @@ extern "C" { /*GPAC client terminal*/ typedef struct _tag_terminal GF_Terminal; - +typedef struct _tag_user GF_User; enum @@ -77,7 +77,7 @@ enum }; /*user object for all callbacks*/ -typedef struct +struct _tag_user { /*user defined callback for all functions - cannot be NULL*/ void *opaque; @@ -98,7 +98,7 @@ typedef struct /*init flags bypassing GPAC config file */ u32 init_flags; -} GF_User; +}; #ifdef __cplusplus diff --git a/include/win32/stdint.h b/include/win32/stdint.h index fa4054e..5202006 100644 --- a/include/win32/stdint.h +++ b/include/win32/stdint.h @@ -1,17 +1,17 @@ - -#ifndef _STDINT_H -#define _STDINT_H - - -typedef signed char int8_t; -typedef signed short int16_t; -typedef signed int int32_t; -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; - - - -#endif /* _STDINT_H */ + +#ifndef _STDINT_H +#define _STDINT_H + + +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed int int32_t; +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + + +#endif /* _STDINT_H */ diff --git a/include/wince/errno.h b/include/wince/errno.h index 6878115..f021af7 100644 --- a/include/wince/errno.h +++ b/include/wince/errno.h @@ -1,104 +1,104 @@ -#ifdef _WIN32_WCE - -/*** -*errno.h - system wide error numbers (set by system calls) -* -* Copyright (c) Microsoft Corporation. All rights reserved. -* -*Purpose: -* This file defines the system-wide error numbers (set by -* system calls). Conforms to the XENIX standard. Extended -* for compatibility with Uniforum standard. -* [System V] -* -* [Public] -* -****/ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#ifndef _INC_ERRNO -#define _INC_ERRNO - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* declare reference to errno */ - -#ifndef _CRT_ERRNO_DEFINED -#define _CRT_ERRNO_DEFINED -_CRTIMP extern int * __cdecl _errno(void); -#define errno (*_errno()) - -errno_t __cdecl _set_errno(__in int _Value); -errno_t __cdecl _get_errno(__out int * _Value); -#endif - -/* Error Codes */ - -#define EPERM 1 -#define ENOENT 2 -#define ESRCH 3 -#define EINTR 4 -#define EIO 5 -#define ENXIO 6 -#define E2BIG 7 -#define ENOEXEC 8 -#define EBADF 9 -#define ECHILD 10 -#define EAGAIN 11 -#define ENOMEM 12 -#define EACCES 13 -#define EFAULT 14 -#define EBUSY 16 -#define EEXIST 17 -#define EXDEV 18 -#define ENODEV 19 -#define ENOTDIR 20 -#define EISDIR 21 -#define ENFILE 23 -#define EMFILE 24 -#define ENOTTY 25 -#define EFBIG 27 -#define ENOSPC 28 -#define ESPIPE 29 -#define EROFS 30 -#define EMLINK 31 -#define EPIPE 32 -#define EDOM 33 -#define EDEADLK 36 -#define ENAMETOOLONG 38 -#define ENOLCK 39 -#define ENOSYS 40 -#define ENOTEMPTY 41 - -/* Error codes used in the Secure CRT functions */ - -#ifndef RC_INVOKED -#if !defined(_SECURECRT_ERRCODE_VALUES_DEFINED) -#define _SECURECRT_ERRCODE_VALUES_DEFINED -#define EINVAL 22 -#define ERANGE 34 -#define EILSEQ 42 -#define STRUNCATE 80 -#endif -#endif - - -/* - * Support EDEADLOCK for compatibiity with older MS-C versions. - */ -#define EDEADLOCK EDEADLK - -#ifdef __cplusplus -} -#endif - -#endif /* _INC_ERRNO */ - +#ifdef _WIN32_WCE + +/*** +*errno.h - system wide error numbers (set by system calls) +* +* Copyright (c) Microsoft Corporation. All rights reserved. +* +*Purpose: +* This file defines the system-wide error numbers (set by +* system calls). Conforms to the XENIX standard. Extended +* for compatibility with Uniforum standard. +* [System V] +* +* [Public] +* +****/ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#ifndef _INC_ERRNO +#define _INC_ERRNO + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* declare reference to errno */ + +#ifndef _CRT_ERRNO_DEFINED +#define _CRT_ERRNO_DEFINED +_CRTIMP extern int * __cdecl _errno(void); +#define errno (*_errno()) + +errno_t __cdecl _set_errno(__in int _Value); +errno_t __cdecl _get_errno(__out int * _Value); +#endif + +/* Error Codes */ + +#define EPERM 1 +#define ENOENT 2 +#define ESRCH 3 +#define EINTR 4 +#define EIO 5 +#define ENXIO 6 +#define E2BIG 7 +#define ENOEXEC 8 +#define EBADF 9 +#define ECHILD 10 +#define EAGAIN 11 +#define ENOMEM 12 +#define EACCES 13 +#define EFAULT 14 +#define EBUSY 16 +#define EEXIST 17 +#define EXDEV 18 +#define ENODEV 19 +#define ENOTDIR 20 +#define EISDIR 21 +#define ENFILE 23 +#define EMFILE 24 +#define ENOTTY 25 +#define EFBIG 27 +#define ENOSPC 28 +#define ESPIPE 29 +#define EROFS 30 +#define EMLINK 31 +#define EPIPE 32 +#define EDOM 33 +#define EDEADLK 36 +#define ENAMETOOLONG 38 +#define ENOLCK 39 +#define ENOSYS 40 +#define ENOTEMPTY 41 + +/* Error codes used in the Secure CRT functions */ + +#ifndef RC_INVOKED +#if !defined(_SECURECRT_ERRCODE_VALUES_DEFINED) +#define _SECURECRT_ERRCODE_VALUES_DEFINED +#define EINVAL 22 +#define ERANGE 34 +#define EILSEQ 42 +#define STRUNCATE 80 +#endif +#endif + + +/* + * Support EDEADLOCK for compatibiity with older MS-C versions. + */ +#define EDEADLOCK EDEADLK + +#ifdef __cplusplus +} +#endif + +#endif /* _INC_ERRNO */ + #endif //_WIN32_WCE \ No newline at end of file diff --git a/mkdmg.sh b/mkdmg.sh index a4a3ce8..89f83c6 100755 --- a/mkdmg.sh +++ b/mkdmg.sh @@ -97,5 +97,7 @@ hdiutil flatten gpac_sla.dmg hdiutil internet-enable -yes gpac_sla.dmg echo "GPAC-$full_version.dmg ready" +chmod o+rx gpac_sla.dmg +chmod g+rx gpac_sla.dmg mv gpac_sla.dmg GPAC-$full_version.dmg diff --git a/modules/Makefile b/modules/Makefile index 2838b4e..863654b 100644 --- a/modules/Makefile +++ b/modules/Makefile @@ -64,6 +64,10 @@ ifeq ($(CONFIG_X11),yes) PLUGDIRS+=x11_out endif +ifeq ($(CONFIG_DIRECTFB),yes) +PLUGDIRS+=directfb_out +endif + ifeq ($(CONFIG_JS),no) else PLUGDIRS+=gpac_js diff --git a/modules/aac_in/Makefile b/modules/aac_in/Makefile index 27eb47b..980c110 100644 --- a/modules/aac_in/Makefile +++ b/modules/aac_in/Makefile @@ -44,7 +44,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(EXTRALIBS) ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_aac_in-static.so $(OBJS) -L../../bin/gcc -lgpac_static $(EXTRALIBS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_aac_in-static.$(DYN_LIB_SUFFIX) $(OBJS) -L../../bin/gcc -lgpac_static $(EXTRALIBS) endif diff --git a/modules/aac_in/aac_in.c b/modules/aac_in/aac_in.c index 5b41a88..c051c75 100644 --- a/modules/aac_in/aac_in.c +++ b/modules/aac_in/aac_in.c @@ -21,7 +21,6 @@ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ - #ifndef DONT_USE_TERMINAL_MODULE_API #include #endif @@ -31,12 +30,15 @@ #include #include +#include + #ifndef GPAC_DISABLE_AV_PARSERS typedef struct { #ifndef DONT_USE_TERMINAL_MODULE_API GF_ClientService *service; + GF_InputService *input; LPNETCHANNEL ch; #endif @@ -70,6 +72,9 @@ typedef struct char *icy_name; char *icy_genre; char *icy_track_name; + + Bool hybrid_on; + u64 prev_map_time; } AACReader; typedef struct @@ -80,7 +85,7 @@ typedef struct #ifndef DONT_USE_TERMINAL_MODULE_API -static const char * AAC_MIMES[] = { "audio/x-m4a", "audio/aac", "audio/aacp", 0 }; +static const char * AAC_MIMES[] = { "audio/x-m4a", "audio/aac", "audio/aacp", "audio/x-aac", 0 }; static const char * AAC_EXTENSIONS = "aac mp4a"; @@ -164,7 +169,8 @@ static void AAC_SetupObject(AACReader *read) { GF_ESD *esd; GF_ObjectDescriptor *od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG); - od->objectDescriptorID = 1; + od->objectDescriptorID = 0; + od->service_ifce = read->input; esd = AAC_GetESD(read); esd->OCRESID = 0; gf_list_add(od->ESDescriptors, esd); @@ -334,6 +340,41 @@ static void AAC_OnLiveData(AACReader *read, const char *data, u32 data_size) SampleCallBack(audio_prog, AUDIO_DATA_ESID, read->data + pos, hdr.frame_size, read->sl_hdr.compositionTimeStamp); #endif gf_bs_skip_bytes(bs, hdr.frame_size); + +#ifndef DONT_USE_TERMINAL_MODULE_API +#ifndef _WIN32_WCE + /* For Hybrid scenarios*/ + if (read->hybrid_on && (!read->prev_map_time || (read->sl_hdr.compositionTimeStamp - read->prev_map_time) > read->sample_rate*5)) { + Double hybrid_delay = 0.0; + time_t now; + struct tm *now_tm; + const char *opt; + + opt = gf_modules_get_option((GF_BaseInterface *)read->input, "HybRadio", "AudioDelay"); + if (opt) { + hybrid_delay = atof(opt); + } + time(&now); + now += (s32)hybrid_delay; + now_tm = gmtime(&now); + { + GF_NetworkCommand com; + memset(&com, 0, sizeof(com)); + com.command_type = GF_NET_CHAN_MAP_TIME; + com.map_time.media_time = now_tm->tm_hour*3600+now_tm->tm_min*60+now_tm->tm_sec + hybrid_delay; + com.map_time.timestamp = read->sl_hdr.compositionTimeStamp; + com.map_time.reset_buffers = 0; + com.base.on_channel = read->ch; + gf_term_on_command(read->service, &com, GF_OK); + GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[AAC In] Mapping WC Time %04d/%02d/%02d %02d:%02d:%02d and AAC time "LLD" (audio delay %f)\n", + (now_tm->tm_year + 1900), (now_tm->tm_mon + 1), now_tm->tm_mday, now_tm->tm_hour, now_tm->tm_min, now_tm->tm_sec, + com.map_time.timestamp, hybrid_delay)); + + } + read->prev_map_time = read->sl_hdr.compositionTimeStamp; + } +#endif +#endif } pos = (u32) gf_bs_get_position(bs); @@ -532,9 +573,9 @@ static void AAC_Reader_del(AACReader * read) } static AACReader * AAC_Reader_new(){ - AACReader *reader = gf_malloc(sizeof(AACReader)); - memset(reader, 0, sizeof(AACReader)); - return reader; + AACReader *reader = gf_malloc(sizeof(AACReader)); + memset(reader, 0, sizeof(AACReader)); + return reader; } @@ -550,9 +591,16 @@ static GF_Err AAC_ConnectService(GF_InputService *plug, GF_ClientService *serv, { char szURL[2048]; char *ext; + const char *opt; GF_Err reply; AACReader *read = plug->priv; - read->service = serv; + read->service = serv; + read->input = plug; + + opt = gf_modules_get_option((GF_BaseInterface *)read->input, "HybRadio", "Activated"); + if (opt && !strcmp(opt, "true")) { + read->hybrid_on = 1; + } AAC_disconnect_from_http_and_free(read); @@ -770,6 +818,19 @@ fetch_next: if (!sync) { gf_bs_del(bs); if (!read->dnload) { + if (read->input->query_proxy) { + GF_NetworkCommand param; + param.command_type = GF_NET_SERVICE_QUERY_NEXT; + if ((read->input->query_proxy(read->input, ¶m)==GF_OK) + && param.url_query.next_url + ) { + fclose(read->stream); + read->stream = gf_f64_open(param.url_query.next_url, "rb"); + *out_reception_status = GF_OK; + return GF_OK; + } + } + *out_reception_status = GF_EOS; read->done = 1; } else { diff --git a/modules/aac_in/faad_dec.c b/modules/aac_in/faad_dec.c index 2c5621d..b7a1999 100644 --- a/modules/aac_in/faad_dec.c +++ b/modules/aac_in/faad_dec.c @@ -50,7 +50,6 @@ typedef struct static GF_Err FAAD_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) { - s8 Test; #ifndef GPAC_DISABLE_AV_PARSERS GF_Err e; GF_M4ADecSpecInfo a_cfg; @@ -73,26 +72,35 @@ static GF_Err FAAD_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) e = gf_m4a_get_config((unsigned char *) esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &a_cfg); if (e) return e; #endif - GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("ctx->sample_rate:%d ctx->num_channels:%d esd->decoderConfig->decoderSpecificInfo->dataLength:%d esd->decoderConfig->decoderSpecificInfo->data:%s \n",ctx->sample_rate,ctx->num_channels,esd->decoderConfig->decoderSpecificInfo->dataLength,esd->decoderConfig->decoderSpecificInfo->data)); - Test = (s8) faacDecInit2(ctx->codec, (unsigned char *) esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, (unsigned long *) &ctx->sample_rate, (u8 *) &ctx->num_channels); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("Test: %d \n",Test)); - if ( Test < 0) + if (faacDecInit2(ctx->codec, (unsigned char *)esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, (unsigned long*)&ctx->sample_rate, (u8*)&ctx->num_channels) < 0) { #ifndef GPAC_DISABLE_AV_PARSERS s8 res; - char *dsi; + char *dsi, *s_base_object_type; u32 dsi_len; switch (a_cfg.base_object_type) { - case GF_M4A_AAC_MAIN: - case GF_M4A_AAC_LC: - case GF_M4A_AAC_SSR: - case GF_M4A_AAC_LTP: - case GF_M4A_AAC_SBR: - case GF_M4A_AAC_PS: - GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FAAD] 1 Error initializing stream %d\n", esd->ESID)); - return GF_NOT_SUPPORTED; - default: - break; + case GF_M4A_AAC_MAIN: + s_base_object_type = gf_stringizer(GF_M4A_AAC_MAIN); + goto base_object_type_error; + case GF_M4A_AAC_LC: + s_base_object_type = gf_stringizer(GF_M4A_AAC_LC); + goto base_object_type_error; + case GF_M4A_AAC_SSR: + s_base_object_type = gf_stringizer(GF_M4A_AAC_SSR); + goto base_object_type_error; + case GF_M4A_AAC_LTP: + s_base_object_type = gf_stringizer(GF_M4A_AAC_LTP); + goto base_object_type_error; + case GF_M4A_AAC_SBR: + s_base_object_type = gf_stringizer(GF_M4A_AAC_SBR); + goto base_object_type_error; + case GF_M4A_AAC_PS: + s_base_object_type = gf_stringizer(GF_M4A_AAC_PS); + base_object_type_error: /*error case*/ + GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FAAD] Error: unsupported %s format for stream %d\n", s_base_object_type, esd->ESID)); + return GF_NOT_SUPPORTED; + default: + break; } a_cfg.base_object_type = GF_M4A_AAC_LC; a_cfg.has_sbr = 0; @@ -104,7 +112,7 @@ static GF_Err FAAD_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) if (res < 0) #endif { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FAAD] 2 Error initializing stream %d\n", esd->ESID)); + GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FAAD] Error when initializing AAC decoder for stream %d\n", esd->ESID)); return GF_NOT_SUPPORTED; } } @@ -319,15 +327,16 @@ static const char *FAAD_GetCodecName(GF_BaseDecoder *ifcg) return "FAAD2 " FAAD2_VERSION; } -static Bool FAAD_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, u8 PL) +static u32 FAAD_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, u8 PL) { #ifndef GPAC_DISABLE_AV_PARSERS GF_M4ADecSpecInfo a_cfg; #endif + /*audio decs*/ - if (StreamType != GF_STREAM_AUDIO) return 0; + if (StreamType != GF_STREAM_AUDIO) return GF_CODEC_NOT_SUPPORTED; /*media type query*/ - if (!esd) return 1; + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; switch (esd->decoderConfig->objectTypeIndication) { /*MPEG2 aac*/ @@ -338,16 +347,32 @@ static Bool FAAD_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *es case GPAC_OTI_AUDIO_AAC_MPEG4: break; default: - return 0; + return GF_CODEC_NOT_SUPPORTED; } - if (!esd->decoderConfig->decoderSpecificInfo || !esd->decoderConfig->decoderSpecificInfo->data) return 0; + /*this codec currently requires AAC config in ESD*/ + if (!esd->decoderConfig->decoderSpecificInfo || !esd->decoderConfig->decoderSpecificInfo->data) return GF_CODEC_NOT_SUPPORTED; #ifndef GPAC_DISABLE_AV_PARSERS - if (gf_m4a_get_config((unsigned char *) esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &a_cfg) != GF_OK) return 0; - /*BSAC not supported*/ - if (a_cfg.base_object_type == GF_M4A_ER_BSAC) return 0; + if (gf_m4a_get_config((unsigned char *) esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &a_cfg) != GF_OK) return GF_CODEC_NOT_SUPPORTED; + + switch (a_cfg.base_object_type) { + case GF_M4A_AAC_MAIN: + case GF_M4A_AAC_LC: + case GF_M4A_AAC_SSR: + case GF_M4A_AAC_LTP: + case GF_M4A_AAC_SBR: + return GF_CODEC_SUPPORTED; + case GF_M4A_ER_AAC_LC: + case GF_M4A_ER_AAC_LTP: + case GF_M4A_ER_AAC_SCALABLE: + case GF_M4A_ER_AAC_LD: + case GF_M4A_AAC_PS: + return GF_CODEC_MAYBE_SUPPORTED; + default: + return GF_CODEC_NOT_SUPPORTED; + } #endif - return 1; + return GF_CODEC_SUPPORTED; } GF_BaseDecoder *NewFAADDec() diff --git a/modules/ac3_in/liba52_dec.c b/modules/ac3_in/liba52_dec.c index 2ed4f27..265f088 100644 --- a/modules/ac3_in/liba52_dec.c +++ b/modules/ac3_in/liba52_dec.c @@ -293,17 +293,17 @@ static const char *AC3_GetCodecName(GF_BaseDecoder *ifcg) return "LIBA52 AC3 Decoder"; } -static Bool AC3_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, u8 PL) +static u32 AC3_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, u8 PL) { /*audio decs*/ - if (StreamType != GF_STREAM_AUDIO) return 0; + if (StreamType != GF_STREAM_AUDIO) return GF_CODEC_NOT_SUPPORTED; /*media type query*/ - if (!esd) return 1; + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; switch (esd->decoderConfig->objectTypeIndication) { case 0xA5: - return 1; + return GF_CODEC_SUPPORTED; } - return 0; + return GF_CODEC_NOT_SUPPORTED; } GF_BaseDecoder *NewAC3Dec() diff --git a/modules/amr_dec/amr_dec.c b/modules/amr_dec/amr_dec.c index 2477a8f..6c1a755 100644 --- a/modules/amr_dec/amr_dec.c +++ b/modules/amr_dec/amr_dec.c @@ -241,17 +241,17 @@ static u32 AMR_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, { char *dsi; /*we handle audio only*/ - if (StreamType!=GF_STREAM_AUDIO) return 0; + if (StreamType!=GF_STREAM_AUDIO) return GF_CODEC_NOT_SUPPORTED; /*media type query*/ - if (!esd) return 1; + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; - if (esd->decoderConfig->objectTypeIndication != GPAC_OTI_MEDIA_GENERIC) return 0; + if (esd->decoderConfig->objectTypeIndication != GPAC_OTI_MEDIA_GENERIC) return GF_CODEC_NOT_SUPPORTED; dsi = esd->decoderConfig->decoderSpecificInfo ? esd->decoderConfig->decoderSpecificInfo->data : NULL; - if (!dsi) return 0; - if (esd->decoderConfig->decoderSpecificInfo->dataLength < 4) return 0; + if (!dsi) return GF_CODEC_NOT_SUPPORTED; + if (esd->decoderConfig->decoderSpecificInfo->dataLength < 4) return GF_CODEC_NOT_SUPPORTED; - if (!strnicmp(dsi, "samr", 4) || !strnicmp(dsi, "amr ", 4)) return 1; - return 0; + if (!strnicmp(dsi, "samr", 4) || !strnicmp(dsi, "amr ", 4)) return GF_CODEC_SUPPORTED; + return GF_CODEC_NOT_SUPPORTED; } diff --git a/modules/amr_float_dec/amr_float_dec.c b/modules/amr_float_dec/amr_float_dec.c index fb20c7b..c4d45b3 100644 --- a/modules/amr_float_dec/amr_float_dec.c +++ b/modules/amr_float_dec/amr_float_dec.c @@ -252,22 +252,22 @@ static u32 AMR_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, { char *dsi; /*we handle audio only*/ - if (StreamType!=GF_STREAM_AUDIO) return 0; + if (StreamType!=GF_STREAM_AUDIO) return GF_CODEC_NOT_SUPPORTED; /*media type query*/ - if (!esd) return 1; + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; - if (esd->decoderConfig->objectTypeIndication != GPAC_OTI_MEDIA_GENERIC) return 0; + if (esd->decoderConfig->objectTypeIndication != GPAC_OTI_MEDIA_GENERIC) return GF_CODEC_NOT_SUPPORTED; dsi = esd->decoderConfig->decoderSpecificInfo ? esd->decoderConfig->decoderSpecificInfo->data : NULL; - if (!dsi) return 0; - if (esd->decoderConfig->decoderSpecificInfo->dataLength < 4) return 0; + if (!dsi) return GF_CODEC_NOT_SUPPORTED; + if (esd->decoderConfig->decoderSpecificInfo->dataLength < 4) return GF_CODEC_NOT_SUPPORTED; #ifdef GPAC_HAS_AMR_FT - if (!strnicmp(dsi, "samr", 4) || !strnicmp(dsi, "amr ", 4)) return 1; + if (!strnicmp(dsi, "samr", 4) || !strnicmp(dsi, "amr ", 4)) return GF_CODEC_SUPPORTED; #endif #ifdef GPAC_HAS_AMR_FT_WB - if (!strnicmp(dsi, "sawb", 4)) return 1; + if (!strnicmp(dsi, "sawb", 4)) return GF_CODEC_SUPPORTED; #endif - return 0; + return GF_CODEC_NOT_SUPPORTED; } diff --git a/modules/bifs_dec/Makefile b/modules/bifs_dec/Makefile index 9600afe..516bd85 100644 --- a/modules/bifs_dec/Makefile +++ b/modules/bifs_dec/Makefile @@ -31,7 +31,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_bifs_dec-static.so $(OBJS) -L../../bin/gcc -lgpac_static + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_bifs_dec-static.$(DYN_LIB_SUFFIX) $(OBJS) -L../../bin/gcc -lgpac_static endif diff --git a/modules/bifs_dec/bifs_dec.c b/modules/bifs_dec/bifs_dec.c index 819edfe..ea08deb 100644 --- a/modules/bifs_dec/bifs_dec.c +++ b/modules/bifs_dec/bifs_dec.c @@ -112,12 +112,12 @@ static GF_Err BIFS_ProcessData(GF_SceneDecoder*plug, const char *inBuffer, u32 i return e; } -Bool BIFS_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, GF_ESD *esd, u8 PL) +static u32 BIFS_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, GF_ESD *esd, u8 PL) { BIFSPriv *priv = (BIFSPriv *)ifce->privateStack; - if (StreamType!=GF_STREAM_SCENE) return 0; + if (StreamType!=GF_STREAM_SCENE) return GF_CODEC_NOT_SUPPORTED; /*media type query*/ - if (!esd) return 1; + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; switch (esd->decoderConfig->objectTypeIndication) { case GPAC_OTI_SCENE_BIFS: @@ -126,9 +126,9 @@ Bool BIFS_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, GF_ESD *esd, u8 shall be treated as if the ObjectTypeIndication had been set to 0x01*/ case 0xFF: priv->PL = PL; - return 1; + return GF_CODEC_SUPPORTED; default: - return 0; + return GF_CODEC_NOT_SUPPORTED; } } diff --git a/modules/ctx_load/Makefile b/modules/ctx_load/Makefile index 654d00f..ac62a0b 100644 --- a/modules/ctx_load/Makefile +++ b/modules/ctx_load/Makefile @@ -31,7 +31,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_ctx_load-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_ctx_load-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static endif diff --git a/modules/ctx_load/ctx_load.c b/modules/ctx_load/ctx_load.c index 40352ca..0a273e8 100644 --- a/modules/ctx_load/ctx_load.c +++ b/modules/ctx_load/ctx_load.c @@ -692,25 +692,37 @@ const char *CTXLoad_GetName(struct _basedecoder *plug) } } -Bool CTXLoad_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, GF_ESD *esd, u8 PL) +static u32 CTXLoad_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, GF_ESD *esd, u8 PL) { if (StreamType==GF_STREAM_PRIVATE_SCENE) { /*media type query*/ - if (!esd) return 1; + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; switch (esd->decoderConfig->objectTypeIndication) { case GPAC_OTI_PRIVATE_SCENE_GENERIC: - return 1; + return GF_CODEC_SUPPORTED; /*LASeR ML: we use this plugin since it has command handling*/ case GPAC_OTI_PRIVATE_SCENE_LASER: - return 1; + return GF_CODEC_SUPPORTED; /* XBL */ case GPAC_OTI_PRIVATE_SCENE_XBL: - return 1; + return GF_CODEC_SUPPORTED; + /*SVG*/ + case GPAC_OTI_PRIVATE_SCENE_SVG: + return GF_CODEC_MAYBE_SUPPORTED; + } + } else if (StreamType==GF_STREAM_SCENE) { + /*media type query*/ + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; + switch (esd->decoderConfig->objectTypeIndication) { + case GPAC_OTI_SCENE_SVG: + case GPAC_OTI_SCENE_SVG_GZ: + case GPAC_OTI_SCENE_DIMS: + return GF_CODEC_MAYBE_SUPPORTED; + default: + break; } } - /*SVG*/ - //if ((StreamType==GF_STREAM_PRIVATE_SCENE) && (ObjectType==2)) return 1; - return 0; + return GF_CODEC_NOT_SUPPORTED; } void DeleteContextLoader(GF_BaseDecoder *plug) diff --git a/modules/directfb_out/Makefile b/modules/directfb_out/Makefile index 3650a7d..dff6a44 100644 --- a/modules/directfb_out/Makefile +++ b/modules/directfb_out/Makefile @@ -4,7 +4,7 @@ vpath %.c $(SRC_PATH)/modules/directfb_out CFLAGS= $(OPTFLAGS) CFLAGS+=-I"$(SRC_PATH)/include" -I$(DIRECTFB_INC_PATH) -LDFLAGS+=-ldirectfb -lfusion -ldirect +LDFLAGS+=$(DIRECTFB_LIB) ifeq ($(DEBUGBUILD), yes) CFLAGS+=-g diff --git a/modules/directfb_out/directfb_out.c b/modules/directfb_out/directfb_out.c index d36d2c8..a751bd7 100755 --- a/modules/directfb_out/directfb_out.c +++ b/modules/directfb_out/directfb_out.c @@ -15,9 +15,6 @@ u32 DirectFBVid_TranslatePixelFormatToGPAC(u32 dfbpf) case DSPF_RGB24: return GF_PIXEL_RGB_24; case DSPF_RGB32: return GF_PIXEL_RGB_32; case DSPF_ARGB: return GF_PIXEL_ARGB; -// case DSPF_YUY2: return GF_PIXEL_YUY2; -// case DSPF_YV12: return GF_PIXEL_YV12; -// case DSPF_I420: return GF_PIXEL_YV12; default: return 0; } } @@ -32,10 +29,9 @@ u32 DirectFBVid_TranslatePixelFormatFromGPAC(u32 gpacpf) case GF_PIXEL_RGB_32 : return DSPF_RGB32; case GF_PIXEL_ARGB: return DSPF_ARGB; case GF_PIXEL_RGBA: return DSPF_ARGB; - case GF_PIXEL_BGRA: return DSPF_ARGB; case GF_PIXEL_YUY2 : return DSPF_YUY2; case GF_PIXEL_YV12 : return DSPF_YV12; - default: + default: GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[DirectFB] pixel format %s not supported\n", gf_4cc_to_str(gpacpf))); return 0; } @@ -62,10 +58,10 @@ static void directfb_translate_key(DFBInputDeviceKeySymbol DirectFBkey, GF_Event evt->flags = 0; evt->hw_code = DirectFBkey; switch (DirectFBkey){ - case DIKS_BACKSPACE: - evt->key_code = GF_KEY_BACKSPACE; break; - case DIKS_RETURN: - evt->key_code = GF_KEY_ENTER; break; + case DIKS_BACKSPACE: + evt->key_code = GF_KEY_BACKSPACE; break; + case DIKS_RETURN: + evt->key_code = GF_KEY_ENTER; break; case DIKS_CANCEL: evt->key_code = GF_KEY_CANCEL; break; case DIKS_ESCAPE: @@ -224,7 +220,7 @@ static void directfb_translate_key(DFBInputDeviceKeySymbol DirectFBkey, GF_Event case DIKS_INSERT: evt->key_code = GF_KEY_INSERT; break; case DIKS_HOME: - evt->key_code = GF_KEY_HOME; break; + evt->key_code = GF_KEY_HOME; break; case DIKS_END: evt->key_code = GF_KEY_END; break; case DIKS_PAGE_UP: @@ -251,51 +247,51 @@ static void directfb_translate_key(DFBInputDeviceKeySymbol DirectFBkey, GF_Event case DIKS_PAUSE: evt->key_code = GF_KEY_MEDIAPLAYPAUSE; break; case DIKS_PLAY: - evt->key_code = GF_KEY_PLAY; break; + evt->key_code = GF_KEY_PLAY; break; case DIKS_STOP: - evt->key_code = GF_KEY_MEDIASTOP; break; + evt->key_code = GF_KEY_MEDIASTOP; break; case DIKS_PREVIOUS: evt->key_code = GF_KEY_MEDIAPREVIOUSTRACK; break; case DIKS_F1: - evt->key_code = GF_KEY_F1; break; + evt->key_code = GF_KEY_F1; break; case DIKS_F2: - evt->key_code = GF_KEY_F2; break; + evt->key_code = GF_KEY_F2; break; case DIKS_F3: - evt->key_code = GF_KEY_F3; break; + evt->key_code = GF_KEY_F3; break; case DIKS_F4: - evt->key_code = GF_KEY_F4; break; + evt->key_code = GF_KEY_F4; break; case DIKS_F5: - evt->key_code = GF_KEY_F5; break; + evt->key_code = GF_KEY_F5; break; case DIKS_F6: - evt->key_code = GF_KEY_F6; break; + evt->key_code = GF_KEY_F6; break; case DIKS_F7: - evt->key_code = GF_KEY_F7; break; + evt->key_code = GF_KEY_F7; break; case DIKS_F8: - evt->key_code = GF_KEY_F8; break; + evt->key_code = GF_KEY_F8; break; case DIKS_F9: - evt->key_code = GF_KEY_F9; break; + evt->key_code = GF_KEY_F9; break; case DIKS_F10: - evt->key_code = GF_KEY_F10; break; + evt->key_code = GF_KEY_F10; break; case DIKS_F11: - evt->key_code = GF_KEY_F11; break; + evt->key_code = GF_KEY_F11; break; case DIKS_F12: - evt->key_code = GF_KEY_F12; break; + evt->key_code = GF_KEY_F12; break; case DIKS_SHIFT: - evt->key_code = GF_KEY_SHIFT; break; + evt->key_code = GF_KEY_SHIFT; break; case DIKS_CONTROL: - evt->key_code = GF_KEY_CONTROL; break; + evt->key_code = GF_KEY_CONTROL; break; case DIKS_ALT: - evt->key_code = GF_KEY_ALT; break; + evt->key_code = GF_KEY_ALT; break; case DIKS_ALTGR: - evt->key_code = GF_KEY_ALTGRAPH; break; + evt->key_code = GF_KEY_ALTGRAPH; break; case DIKS_META: - evt->key_code = GF_KEY_META; break; + evt->key_code = GF_KEY_META; break; case DIKS_CAPS_LOCK: - evt->key_code = GF_KEY_CAPSLOCK; break; + evt->key_code = GF_KEY_CAPSLOCK; break; case DIKS_NUM_LOCK: - evt->key_code = GF_KEY_NUMLOCK; break; + evt->key_code = GF_KEY_NUMLOCK; break; case DIKS_SCROLL_LOCK: - evt->key_code = GF_KEY_SCROLL; break; + evt->key_code = GF_KEY_SCROLL; break; case DIKS_FAVORITES: evt->key_code = GF_KEY_BROWSERFAVORITES; break; case DIKS_CUSTOM0: @@ -323,9 +319,9 @@ static void directfb_translate_key(DFBInputDeviceKeySymbol DirectFBkey, GF_Event case DIKS_REWIND: evt->key_code = GF_KEY_BROWSERBACK; break; case DIKS_FASTFORWARD: - evt->key_code = GF_KEY_BROWSERFORWARD; break; + evt->key_code = GF_KEY_BROWSERFORWARD; break; case DIKS_SUBTITLE: - evt->key_code = GF_KEY_DEL; break; + evt->key_code = GF_KEY_DEL; break; case DIKS_CHANNEL_UP: evt->key_code = GF_KEY_CHANNELUP; break; case DIKS_CHANNEL_DOWN: @@ -346,7 +342,7 @@ static void directfb_translate_key(DFBInputDeviceKeySymbol DirectFBkey, GF_Event } #if 0 -static int compare_symbol( const void *a, const void *b ) +static int compare_symbol( const void *a, const void *b ) { u32 *keycode = (u32 *) a; struct predef_keyid *idname = (struct predef_keyid *) b; @@ -363,7 +359,7 @@ static const char *get_local_key_name(u32 key_code) { } static void show_key_event(DirectFBVidCtx *ctx, GF_EventKey *evt ) -{ +{ //DirectFBVID(); char buf[16]; struct predef_keyid *predefine_keyid; @@ -389,17 +385,17 @@ static void DirectFBVid_DrawHLine(GF_VideoOutput *driv, u32 x, u32 y, u32 length { DirectFBVID(); u8 r, g, b; - + //GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DirectFB] in DirectFBVid_DrawHLine(). Drawing line x %d y %d length %d color %08X\n", x, y, length, color)); SET_DRAWING_FLAGS( DSDRAW_NOFX ); r = GF_COL_R(color); g = GF_COL_G(color); b = GF_COL_B(color); - + ctx->primary->SetColor(ctx->primary, r, g, b, 0xFF); // no alpha //ctx->primary->DrawLine(ctx->primary, x, y, x+length, y); // no acceleration - ctx->primary->FillRectangle(ctx->primary, x, y,length, 1); + ctx->primary->FillRectangle(ctx->primary, x, y,length, 1); } @@ -410,12 +406,12 @@ static void DirectFBVid_DrawHLineAlpha(GF_VideoOutput *driv, u32 x, u32 y, u32 l //GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DirectFB] in DirectFBVid_DrawHLineAlpha(). Alpha line drawing x %d y %d length %d color %08X alpha %d\n", x, y, length, color, alpha)); - SET_DRAWING_FLAGS( DSDRAW_BLEND ); // use alpha + SET_DRAWING_FLAGS( DSDRAW_BLEND ); // use alpha r = GF_COL_R(color); g = GF_COL_G(color); - b = GF_COL_B(color); - + b = GF_COL_B(color); + ctx->primary->SetColor(ctx->primary, r, g, b, alpha); //ctx->primary->DrawLine(ctx->primary, x, y, x+length, y); ctx->primary->FillRectangle(ctx->primary, x, y, length, 1); // with acceleration @@ -433,8 +429,8 @@ static void DirectFBVid_DrawRectangle(GF_VideoOutput *driv, u32 x, u32 y, u32 wi g = GF_COL_G(color); b = GF_COL_B(color); a = GF_COL_A(color); - - SET_DRAWING_FLAGS( DSDRAW_NOFX ); + + SET_DRAWING_FLAGS( DSDRAW_NOFX ); ctx->primary->SetColor(ctx->primary, r, g, b, a); ctx->primary->FillRectangle(ctx->primary, x, y, width, height); @@ -450,18 +446,18 @@ GF_Err DirectFBVid_Setup(GF_VideoOutput *driv, void *os_handle, void *os_display DFBSurfacePixelFormat dfbpf; DFBAccelerationMask mask; DeviceInfo *devices = NULL; - + DirectFBVID(); ctx->is_init = 0; argc=0; - DFBCHECK(DirectFBInit(&argc, & (argv) )); - + DFBCHECK(DirectFBInit(&argc, & (argv) )); + DirectFBSetOption ("bg-none", NULL); DirectFBSetOption ("no-init-layer", NULL); - + /* create the super interface */ DFBCHECK(DirectFBCreate( &(ctx->dfb) )); - + GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DirectFB] Initialization\n")); /* create a list of input devices */ @@ -469,18 +465,18 @@ GF_Err DirectFBVid_Setup(GF_VideoOutput *driv, void *os_handle, void *os_display /* create an event buffer for all devices */ DFBCHECK(ctx->dfb->CreateInputEventBuffer(ctx->dfb, DICAPS_KEYS, DFB_FALSE, &(ctx->events) )); - + /* Set the cooperative level */ err = ctx->dfb->SetCooperativeLevel( ctx->dfb, DFSCL_FULLSCREEN ); if (err) DirectFBError( "Failed to set cooperative level", err ); - + /* Get the primary surface, i.e. the surface of the primary layer. */ dsc.flags = DSDESC_CAPS; dsc.caps = DSCAPS_PRIMARY | DSCAPS_DOUBLE; if (ctx->use_systems_memory) dsc.caps |= DSCAPS_SYSTEMONLY; - + DFBCHECK(ctx->dfb->CreateSurface( ctx->dfb, &dsc, &(ctx->primary) )); ctx->primary->GetPixelFormat( ctx->primary, &dfbpf ); @@ -510,11 +506,11 @@ GF_Err DirectFBVid_Setup(GF_VideoOutput *driv, void *os_handle, void *os_display opt = gf_modules_get_option((GF_BaseInterface *)driv, "DirectFB", "DisableBlit"); if (!opt) gf_modules_set_option((GF_BaseInterface *)driv, "DirectFB", "DisableBlit", "no"); if (opt && !strcmp(opt, "all")) { - driv->hw_caps &= ~(GF_VIDEO_HW_HAS_RGB | GF_VIDEO_HW_HAS_RGBA | GF_VIDEO_HW_HAS_YUV); + driv->hw_caps &= ~(GF_VIDEO_HW_HAS_RGB | GF_VIDEO_HW_HAS_RGBA | GF_VIDEO_HW_HAS_YUV); } - else if (opt && !strcmp(opt, "yuv")) driv->hw_caps &= ~GF_VIDEO_HW_HAS_YUV; - else if (opt && !strcmp(opt, "rgb")) driv->hw_caps &= ~GF_VIDEO_HW_HAS_RGB; - else if (opt && !strcmp(opt, "rgba")) driv->hw_caps &= ~GF_VIDEO_HW_HAS_RGBA; + else if (opt && !strcmp(opt, "yuv")) driv->hw_caps &= ~GF_VIDEO_HW_HAS_YUV; + else if (opt && !strcmp(opt, "rgb")) driv->hw_caps &= ~GF_VIDEO_HW_HAS_RGB; + else if (opt && !strcmp(opt, "rgba")) driv->hw_caps &= ~GF_VIDEO_HW_HAS_RGBA; if (!ctx->disable_acceleration){ @@ -528,26 +524,31 @@ GF_Err DirectFBVid_Setup(GF_VideoOutput *driv, void *os_handle, void *os_display GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[DirectFB] hardware acceleration mask %08x - Line: %d Rectangle: %d\n", mask, ctx->accel_drawline, ctx->accel_fillrect)); - driv->hw_caps |= GF_VIDEO_HW_HAS_LINE_BLIT; + driv->hw_caps |= GF_VIDEO_HW_HAS_LINE_BLIT; driv->DrawHLine = DirectFBVid_DrawHLine; driv->DrawHLineAlpha = DirectFBVid_DrawHLineAlpha; driv->DrawRectangle = DirectFBVid_DrawRectangle; } - + ctx->is_init = 1; - GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DirectFB] Initialization success\n")); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DirectFB] Initialization success - HW caps %08x\n", driv->hw_caps)); + // GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DirectFB] Pixel format %s\n", gf_4cc_to_str(ctx->pixel_format))); - return GF_OK; + return GF_OK; } static void DirectFBVid_Shutdown(GF_VideoOutput *driv) { DirectFBVID(); if (!ctx->is_init) return; + //ctx->primary->Clear(ctx->primary,0,0,0,0); + //ctx->primary->Flip( ctx->primary, NULL, DSFLIP_NONE); + //ctx->primary->Clear(ctx->primary,0,0,0,0); ctx->primary->Release( ctx->primary ); ctx->events->Release( ctx->events ); ctx->dfb->Release( ctx->dfb ); ctx->is_init = 0; + system("stgfb_control /dev/fb0 a 0"); } static GF_Err DirectFBVid_Flush(GF_VideoOutput *driv, GF_Window *dest) @@ -565,8 +566,8 @@ static GF_Err DirectFBVid_Flush(GF_VideoOutput *driv, GF_Window *dest) GF_Err DirectFBVid_SetFullScreen(GF_VideoOutput *driv, u32 bFullScreenOn, u32 *screen_width, u32 *screen_height) { DFBResult err; - DirectFBVID(); - + DirectFBVID(); + *screen_width = ctx->width; *screen_height = ctx->height; @@ -578,8 +579,8 @@ Bool DirectFBVid_ProcessMessageQueue(DirectFBVidCtx *ctx, GF_VideoOutput *driv) { DFBInputEvent directfb_evt; GF_Event gpac_evt; - - while (ctx->events->GetEvent( ctx->events, DFB_EVENT(&directfb_evt) ) == DFB_OK) + + while (ctx->events->GetEvent( ctx->events, DFB_EVENT(&directfb_evt) ) == DFB_OK) { u32 i; switch (directfb_evt.type){ @@ -589,21 +590,21 @@ Bool DirectFBVid_ProcessMessageQueue(DirectFBVidCtx *ctx, GF_VideoOutput *driv) directfb_translate_key(directfb_evt.key_symbol, &gpac_evt.key); gpac_evt.type = (directfb_evt.type == DIET_KEYPRESS) ? GF_EVENT_KEYDOWN : GF_EVENT_KEYUP; #if 0 - fprintf(stderr, "before %d %s\n", gpac_evt.key.key_code, + fprintf(stderr, "before %d %s\n", gpac_evt.key.key_code, gf_dom_get_key_name(gpac_evt.key.key_code)); - - for (i=0;i<200; i++) { + + for (i=0;i<200; i++) { fprintf(stderr, "%03d %s\n", i, gf_dom_get_key_name(i)); } #endif driv->on_event(driv->evt_cbk_hdl, &gpac_evt); - //fprintf(stderr, "after %d %s\n", gpac_evt.key.key_code, gf_dom_get_key_name(gpac_evt.key.key_code)); - default: + //fprintf(stderr, "after %d %s\n", gpac_evt.key.key_code, gf_dom_get_key_name(gpac_evt.key.key_code)); + default: break; } - + } - + return GF_OK; } @@ -627,10 +628,10 @@ static GF_Err DirectFBVid_ProcessEvent(GF_VideoOutput *driv, GF_Event *evt) driv->on_event(driv->evt_cbk_hdl, &gpac_evt); } return GF_OK; - + case GF_EVENT_VIDEO_SETUP: if (evt->setup.opengl_mode) return GF_NOT_SUPPORTED; - + if ((ctx->width !=evt->setup.width) || (ctx->height != evt->setup.height)) { GF_Event gpac_evt; gpac_evt.type = GF_EVENT_SIZE; @@ -651,7 +652,7 @@ static GF_Err DirectFBVid_LockBackBuffer(GF_VideoOutput *driv, GF_VideoSurface * void *buf; u32 width, height; DFBSurfacePixelFormat format; - + DirectFBVID(); if (!ctx->primary) return GF_BAD_PARAM; if (do_lock) @@ -666,7 +667,7 @@ static GF_Err DirectFBVid_LockBackBuffer(GF_VideoOutput *driv, GF_VideoSurface * video_info->pitch_y = pitch; video_info->video_buffer = buf; video_info->pixel_format = ctx->pixel_format; - video_info->is_hardware_memory = !ctx->use_systems_memory; + video_info->is_hardware_memory = !ctx->use_systems_memory; GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DirectFB] backbuffer locked\n")); } else { @@ -674,7 +675,7 @@ static GF_Err DirectFBVid_LockBackBuffer(GF_VideoOutput *driv, GF_VideoSurface * GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DirectFB] backbuffer unlocked\n")); } return GF_OK; - + } static GF_Err DirectFBVid_Blit(GF_VideoOutput *driv, GF_VideoSurface *video_src, GF_Window *src_wnd, GF_Window *dst_wnd, u32 overlay_type) @@ -699,13 +700,10 @@ static GF_Err DirectFBVid_Blit(GF_VideoOutput *driv, GF_VideoSurface *video_src, srcdesc.preallocated[0].data = video_src->video_buffer; srcdesc.preallocated[0].pitch = video_src->pitch_y; - GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DirectFB] video_src->pitch_y %d \n",video_src->pitch_y )); - switch (video_src->pixel_format){ case GF_PIXEL_ARGB: //return DSPF_ARGB; case GF_PIXEL_RGBA: //return DSPF_ARGB; - case GF_PIXEL_BGRA: //return DSPF_ARGB; ctx->primary->SetBlittingFlags(ctx->primary, DSBLIT_BLEND_ALPHACHANNEL); break; default: @@ -718,9 +716,8 @@ static GF_Err DirectFBVid_Blit(GF_VideoOutput *driv, GF_VideoSurface *video_src, GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[DirectFB] cannot create blit source surface for pixel format %s: %s (%d)\n", gf_4cc_to_str(video_src->pixel_format), DirectFBErrorString(res), res)); return GF_IO_ERR; } - - GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DirectFB] blit source surface created\n")); - + + dfbsrc.x = src_wnd->x; dfbsrc.y = src_wnd->y; dfbsrc.w = src_wnd->w; @@ -728,7 +725,7 @@ static GF_Err DirectFBVid_Blit(GF_VideoOutput *driv, GF_VideoSurface *video_src, if (!src_wnd->x && !src_wnd->y && (dst_wnd->w==src_wnd->w) && (dst_wnd->h==src_wnd->h)) { ctx->primary->Blit(ctx->primary, src, &dfbsrc, dst_wnd->x, dst_wnd->y); - } else { + } else { dfbdst.x = dst_wnd->x; dfbdst.y = dst_wnd->y; dfbdst.w = dst_wnd->w; @@ -737,6 +734,7 @@ static GF_Err DirectFBVid_Blit(GF_VideoOutput *driv, GF_VideoSurface *video_src, } src->Release(src); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DirectFB] blit successful\n")); return GF_OK; } @@ -745,14 +743,14 @@ void *DirectFBNewVideo() { DirectFBVidCtx *ctx; GF_VideoOutput *driv; - + driv = gf_malloc(sizeof(GF_VideoOutput)); memset(driv, 0, sizeof(GF_VideoOutput)); GF_REGISTER_MODULE_INTERFACE(driv, GF_VIDEO_OUTPUT_INTERFACE, "DirectFB Video Output", "gpac distribution"); - + ctx = gf_malloc(sizeof(DirectFBVidCtx)); memset(ctx, 0, sizeof(DirectFBVidCtx)); - + /* GF_VideoOutput */ driv->opaque = ctx; driv->Setup = DirectFBVid_Setup; @@ -763,9 +761,9 @@ void *DirectFBNewVideo() driv->LockBackBuffer = DirectFBVid_LockBackBuffer; driv->LockOSContext = NULL; driv->Blit = DirectFBVid_Blit; - driv->hw_caps |= GF_VIDEO_HW_HAS_RGB | GF_VIDEO_HW_HAS_RGBA | GF_VIDEO_HW_HAS_YUV; - - return driv; + driv->hw_caps |= GF_VIDEO_HW_HAS_RGB | GF_VIDEO_HW_HAS_RGBA | GF_VIDEO_HW_HAS_YUV | GF_VIDEO_HW_HAS_STRETCH; + + return driv; } void DirectFBDeleteVideo(void *ifce) @@ -778,13 +776,13 @@ void DirectFBDeleteVideo(void *ifce) /*interface query*/ -const u32 *QueryInterfaces() +const u32 *QueryInterfaces() { static u32 si [] = { GF_VIDEO_OUTPUT_INTERFACE, 0 }; - return si; + return si; } /*interface create*/ diff --git a/modules/droid_audio/droidaudio.c b/modules/droid_audio/droidaudio.c index 711429a..b0b6c4f 100644 --- a/modules/droid_audio/droidaudio.c +++ b/modules/droid_audio/droidaudio.c @@ -1,452 +1,452 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) ENST 2009- - * Authors: Jean Le Feuvre - * All rights reserved - * - * Created by NGO Van Luyen / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010 - * nvluyen81@gmail.com - * - * This file is part of GPAC / Wrapper - * - * 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 "javaenv.h" - -#include -#include -#include -#include - -#define STREAM_MUSIC 3 -#define CHANNEL_CONFIGURATION_MONO 2 -#define CHANNEL_CONFIGURATION_STEREO 3 -#define ENCODING_PCM_8BIT 3 -#define ENCODING_PCM_16BIT 2 -#define MODE_STREAM 1 -#define CHANNEL_OUT_MONO 4 -#define CHANNEL_IN_STEREO 12 -#define CHANNEL_IN_MONO 16 - - -/*for channel codes*/ -#include - -static const char android_device[] = "Android Default"; - -static jclass cAudioTrack = NULL; -static jobject mtrack = NULL; - -static jmethodID mAudioTrack; -static jmethodID setStereoVolume; -static jmethodID mGetMinBufferSize; -static jmethodID mPlay; -static jmethodID mStop; -static jmethodID mRelease; -static jmethodID mWrite; -static jmethodID mFlush; - -#include -#define TAG "GPAC Android Audio" -#define LOGV(X, Y) __android_log_print(ANDROID_LOG_VERBOSE, TAG, X, Y) -#define LOGV3(X, Y, Z, K) __android_log_print(ANDROID_LOG_VERBOSE, TAG, X, Y, Z, K) -#define LOGD(X, Y) __android_log_print(ANDROID_LOG_DEBUG, TAG, X, Y) -#define LOGD2(X, Y, Z) __android_log_print(ANDROID_LOG_DEBUG, TAG, X, Y, Z) -#define LOGE(X, Y) __android_log_print(ANDROID_LOG_ERROR, TAG, X, Y) -#define LOGE3(X, Y, Z, W) __android_log_print(ANDROID_LOG_ERROR, TAG, X, Y, Z, W) -#define LOGW(X, Y) __android_log_print(ANDROID_LOG_WARN, TAG, X, Y) -#define LOGI(X, Y) __android_log_print(ANDROID_LOG_INFO, TAG, X, Y) - - -/* Uncomment the next line if you want to debug */ -/* #define DROID_EXTREME_LOGS */ - -typedef struct -{ - JNIEnv* env; - - jobject mtrack; - - u32 num_buffers; - - u32 delay, total_length_ms; - - Bool force_config; - u32 cfg_num_buffers, cfg_duration; - - u32 sampleRateInHz; - u32 channelConfig; //AudioFormat.CHANNEL_OUT_MONO - u32 audioFormat; //AudioFormat.ENCODING_PCM_16BIT - s32 mbufferSizeInBytes; - u32 volume; - u32 pan; - jarray buff; -} DroidContext; - -//---------------------------------------------------------------------- -//---------------------------------------------------------------------- -// Called by the main thread -static GF_Err WAV_Setup(GF_AudioOutput *dr, void *os_handle, u32 num_buffers, u32 total_duration) -{ - DroidContext *ctx = (DroidContext *)dr->opaque; - JNIEnv* env = GetEnv(); - int channels; - int bytes; - LOGV("[Android Audio] Setup for %d buffers", num_buffers); - - ctx->force_config = (num_buffers && total_duration) ? 1 : 0; - ctx->cfg_num_buffers = num_buffers; - if (ctx->cfg_num_buffers <= 1) ctx->cfg_num_buffers = 2; - ctx->cfg_duration = total_duration; - if (!ctx->force_config) ctx->num_buffers = 1; - ctx->volume = 100; - ctx->pan = 50; - - if (!cAudioTrack){ - cAudioTrack = (*env)->FindClass(env, "android/media/AudioTrack"); - if (!cAudioTrack) { - return GF_NOT_SUPPORTED; - } - - cAudioTrack = (*env)->NewGlobalRef(env, cAudioTrack); - - mAudioTrack = (*env)->GetMethodID(env, cAudioTrack, "", "(IIIIII)V"); - mGetMinBufferSize = (*env)->GetStaticMethodID(env, cAudioTrack, "getMinBufferSize", "(III)I"); - mPlay = (*env)->GetMethodID(env, cAudioTrack, "play", "()V"); - mStop = (*env)->GetMethodID(env, cAudioTrack, "stop", "()V"); - mRelease = (*env)->GetMethodID(env, cAudioTrack, "release", "()V"); - mWrite = (*env)->GetMethodID(env, cAudioTrack, "write", "([BII)I"); - mFlush = (*env)->GetMethodID(env, cAudioTrack, "flush", "()V"); - setStereoVolume = (*env)->GetMethodID(env, cAudioTrack, "setStereoVolume", "(FF)I"); - } - - return GF_OK; -} -//---------------------------------------------------------------------- -// Called by the audio thread -static void WAV_Shutdown(GF_AudioOutput *dr) -{ - DroidContext *ctx = (DroidContext *)dr->opaque; - JNIEnv* env = ctx->env; - - (*env)->CallNonvirtualVoidMethod(env, mtrack, cAudioTrack, mStop); - (*env)->CallNonvirtualVoidMethod(env, mtrack, cAudioTrack, mRelease); - - (*env)->PopLocalFrame(env, NULL); - - (*GetJavaVM())->DetachCurrentThread(GetJavaVM()); -} - - -/*we assume what was asked is what we got*/ -/* Called by the audio thread */ -static GF_Err WAV_ConfigureOutput(GF_AudioOutput *dr, u32 *SampleRate, u32 *NbChannels, u32 *nbBitsPerSample, u32 channel_cfg) -{ - JNIEnv* env = NULL; - u32 i; - DroidContext *ctx = (DroidContext *)dr->opaque; - - LOGI("[Android Audio] Configure Output for %u channels...", *NbChannels); - - if (!ctx) return GF_BAD_PARAM; - - ctx->sampleRateInHz = *SampleRate; - ctx->channelConfig = (*NbChannels == 1) ? CHANNEL_CONFIGURATION_MONO : CHANNEL_CONFIGURATION_STEREO; //AudioFormat.CHANNEL_CONFIGURATION_MONO - ctx->audioFormat = (*nbBitsPerSample == 8)? ENCODING_PCM_8BIT : ENCODING_PCM_16BIT; //AudioFormat.ENCODING_PCM_16BIT - - // Get the java environment in the new thread - (*GetJavaVM())->AttachCurrentThread(GetJavaVM(), &env, NULL); - ctx->env = env; - LOGV("[Android Audio] SampleRate : %d",ctx->sampleRateInHz); - LOGV("[Android Audio] BitPerSample : %d", *nbBitsPerSample); - - (*env)->PushLocalFrame(env, 2); - - ctx->num_buffers = 1; - ctx->mbufferSizeInBytes = (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, - ctx->sampleRateInHz, ctx->channelConfig, ctx->audioFormat); - - i = 1; - if ( ctx->channelConfig == CHANNEL_CONFIGURATION_STEREO ) - i *= 2; - if ( ctx->audioFormat == ENCODING_PCM_16BIT ) - i *= 2; - - ctx->total_length_ms = 1000 * ctx->num_buffers * ctx->mbufferSizeInBytes / i / ctx->sampleRateInHz; - - /*initial delay is full buffer size*/ - ctx->delay = ctx->total_length_ms; - - mtrack = (*env)->NewObject(env, cAudioTrack, mAudioTrack, STREAM_MUSIC, ctx->sampleRateInHz, - ctx->channelConfig, ctx->audioFormat, ctx->mbufferSizeInBytes, MODE_STREAM); //AudioTrack.MODE_STREAM - if (mtrack){ - mtrack = (*env)->NewGlobalRef(env, mtrack); - ctx->mtrack = mtrack; - (*env)->CallNonvirtualVoidMethod(env, mtrack, cAudioTrack, mPlay); - } else { - LOGV("[Android Audio] mtrack = %p", mtrack); - return GF_NOT_SUPPORTED; - } - - ctx->buff = (*env)->NewByteArray(env, ctx->mbufferSizeInBytes); - LOGV("[Android Audio] ConfigureOutput DONE.", *NbChannels); - return GF_OK; -} - -/* Called by the audio thread */ -static void WAV_WriteAudio(GF_AudioOutput *dr) -{ - DroidContext *ctx = (DroidContext *)dr->opaque; - if (!ctx) - return; - JNIEnv* env = ctx->env; - u32 written; - void* pBuffer; - if (!env) - return; -#ifdef DROID_EXTREME_LOGS - LOGV("[Android Audio] WAV_WriteAudio() : entering",ctx->sampleRateInHz); -#endif /* DROID_EXTREME_LOGS */ - pBuffer = (*env)->GetPrimitiveArrayCritical(env, ctx->buff, NULL); - if (pBuffer) - { - written = dr->FillBuffer(dr->audio_renderer, pBuffer, ctx->mbufferSizeInBytes); - (*env)->ReleasePrimitiveArrayCritical(env, ctx->buff, pBuffer, 0); - if (written) - { - (*env)->CallNonvirtualIntMethod(env, mtrack, cAudioTrack, mWrite, ctx->buff, 0, ctx->mbufferSizeInBytes); - } - } - else - { - LOGV("[Android Audio] Failed to get pointer to array bytes = %p", pBuffer); - } -#ifdef DROID_EXTREME_LOGS - LOGV("[Android Audio] WAV_WriteAudio() : done",ctx->sampleRateInHz); -#endif /* DROID_EXTREME_LOGS */ -} - -/* Called by the main thread */ -static void WAV_Play(GF_AudioOutput *dr, u32 PlayType) -{ - DroidContext *ctx = (DroidContext *)dr->opaque; - JNIEnv* env = GetEnv(); - - LOGV("[Android Audio] Play: %d\n", PlayType); - - switch ( PlayType ) - { - case 0: - // Stop playing - (*env)->CallNonvirtualVoidMethod(env, mtrack, cAudioTrack, mStop); - // Clear the internal buffers - (*env)->CallNonvirtualVoidMethod(env, mtrack, cAudioTrack, mFlush); - break; - case 1: - case 2: - (*env)->CallNonvirtualVoidMethod(env, mtrack, cAudioTrack, mPlay); - break; - default: - LOGW("[Android Audio] Unknown Play method=%d.\n", PlayType); - } - LOGV("[Android Audio] Play DONE (%d).\n", PlayType); -} - -static void WAV_UpdateVolume(DroidContext *ctx){ - float lV, rV; - JNIEnv* env = GetEnv(); - if (!ctx) - return; - if (ctx->pan > 100) - ctx->pan = 100; - lV =rV = ctx->volume / 100.0; - if (ctx->pan > 50){ - float m = (100 - ctx->pan) / 50.0; - lV*=m; - } else if (ctx->pan < 50){ - float m = ctx->pan / 50.0; - rV*=m; - } - if (env && setStereoVolume && mtrack && cAudioTrack){ - int success; - if (0!= (success=((*env)->CallNonvirtualIntMethod(env, mtrack, cAudioTrack, setStereoVolume, lV, rV)))) - LOGE3("SetVolume(%f,%f) returned Error code %d", lV, rV, success ); - } else { - LOGD2("SetVolume(%f,%f)", lV, rV ); - } -} - -static void WAV_SetVolume(GF_AudioOutput *dr, u32 Volume) { - DroidContext *ctx = (DroidContext *)dr->opaque; - ctx->volume = Volume; - WAV_UpdateVolume(ctx); -} - -static void WAV_SetPan(GF_AudioOutput *dr, u32 Pan) -{ - DroidContext *ctx = (DroidContext *)dr->opaque; - WAV_UpdateVolume(ctx); -} - -/* Called by the audio thread */ -static GF_Err WAV_QueryOutputSampleRate(GF_AudioOutput *dr, u32 *desired_samplerate, u32 *NbChannels, u32 *nbBitsPerSample) -{ - DroidContext *ctx = (DroidContext *)dr->opaque; - JNIEnv* env = ctx->env; - u32 sampleRateInHz, channelConfig, audioFormat; - - LOGV("Query sample=%d", *desired_samplerate ); - -#ifdef TEST_QUERY_SAMPLE - sampleRateInHz = *desired_samplerate; - channelConfig = (*NbChannels == 1) ? CHANNEL_CONFIGURATION_MONO : CHANNEL_CONFIGURATION_STEREO; - audioFormat = (*nbBitsPerSample == 8)? ENCODING_PCM_8BIT : ENCODING_PCM_16BIT; - - LOGV3("[Android Audio] Query: SampleRate ChannelConfig AudioFormat: %d %d %d \n", - sampleRateInHz, - (channelConfig == CHANNEL_CONFIGURATION_MONO)? 1 : 2, - (ctx->audioFormat == ENCODING_PCM_8BIT)? 8 : 16); - - switch (*desired_samplerate) { - case 11025: - *desired_samplerate = 11025; - if ( (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, - *desired_samplerate, channelConfig, audioFormat) > 0 ) - return GF_OK; - case 22050: - *desired_samplerate = 22050; - if ( (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, - *desired_samplerate, channelConfig, audioFormat) > 0 ) - return GF_OK; - break; - case 8000: - *desired_samplerate = 8000; - if ( (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, - *desired_samplerate, channelConfig, audioFormat) > 0 ) - return GF_OK; - case 16000: - *desired_samplerate = 16000; - if ( (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, - *desired_samplerate, channelConfig, audioFormat) > 0 ) - return GF_OK; - case 32000: - *desired_samplerate = 32000; - if ( (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, - *desired_samplerate, channelConfig, audioFormat) > 0 ) - return GF_OK; - break; - case 24000: - *desired_samplerate = 24000; - if ( (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, - *desired_samplerate, channelConfig, audioFormat) > 0 ) - return GF_OK; - case 48000: - *desired_samplerate = 48000; - if ( (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, - *desired_samplerate, channelConfig, audioFormat) > 0 ) - return GF_OK; - break; - case 44100: - *desired_samplerate = 44100; - if ( (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, - *desired_samplerate, channelConfig, audioFormat) > 0 ) - return GF_OK; - break; - default: - break; - } -#endif - - return GF_OK; -} - -static u32 WAV_GetAudioDelay(GF_AudioOutput *dr) -{ - DroidContext *ctx = (DroidContext *)dr->opaque; - - return ctx->delay; -} - -static u32 WAV_GetTotalBufferTime(GF_AudioOutput *dr) -{ - DroidContext *ctx = (DroidContext *)dr->opaque; - - return ctx->total_length_ms; -} - -//---------------------------------------------------------------------- -void *NewWAVRender() -{ - DroidContext *ctx; - GF_AudioOutput *driv; - ctx = gf_malloc(sizeof(DroidContext)); - memset(ctx, 0, sizeof(DroidContext)); - ctx->num_buffers = 1; - ctx->pan = 50; - ctx->volume = 100; - driv = gf_malloc(sizeof(GF_AudioOutput)); - memset(driv, 0, sizeof(GF_AudioOutput)); - GF_REGISTER_MODULE_INTERFACE(driv, GF_AUDIO_OUTPUT_INTERFACE, "Android Audio Output", "gpac distribution") - - driv->opaque = ctx; - - driv->SelfThreaded = 0; - driv->Setup = WAV_Setup; - driv->Shutdown = WAV_Shutdown; - driv->ConfigureOutput = WAV_ConfigureOutput; - driv->GetAudioDelay = WAV_GetAudioDelay; - driv->GetTotalBufferTime = WAV_GetTotalBufferTime; - driv->SetVolume = WAV_SetVolume; - driv->SetPan = WAV_SetPan; - driv->Play = WAV_Play; - driv->QueryOutputSampleRate = WAV_QueryOutputSampleRate; - driv->WriteAudio = WAV_WriteAudio; - return driv; -} -//---------------------------------------------------------------------- -void DeleteWAVRender(void *ifce) -{ - GF_AudioOutput *dr = (GF_AudioOutput *) ifce; - if (!ifce) - return; - gf_free(dr); -} -//---------------------------------------------------------------------- -const u32 *QueryInterfaces() -{ - static u32 si [] = { - GF_AUDIO_OUTPUT_INTERFACE, - 0 - }; - return si; -} - -GF_BaseInterface *LoadInterface(u32 InterfaceType) -{ - if (InterfaceType == GF_AUDIO_OUTPUT_INTERFACE) return NewWAVRender(); - return NULL; -} - -void ShutdownInterface(GF_BaseInterface *ifce) -{ - switch (ifce->InterfaceType) { - case GF_AUDIO_OUTPUT_INTERFACE: - DeleteWAVRender((GF_AudioOutput *) ifce); - break; - } -} +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) ENST 2009- + * Authors: Jean Le Feuvre + * All rights reserved + * + * Created by NGO Van Luyen / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010 + * nvluyen81@gmail.com + * + * This file is part of GPAC / Wrapper + * + * 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 "javaenv.h" + +#include +#include +#include +#include + +#define STREAM_MUSIC 3 +#define CHANNEL_CONFIGURATION_MONO 2 +#define CHANNEL_CONFIGURATION_STEREO 3 +#define ENCODING_PCM_8BIT 3 +#define ENCODING_PCM_16BIT 2 +#define MODE_STREAM 1 +#define CHANNEL_OUT_MONO 4 +#define CHANNEL_IN_STEREO 12 +#define CHANNEL_IN_MONO 16 + + +/*for channel codes*/ +#include + +static const char android_device[] = "Android Default"; + +static jclass cAudioTrack = NULL; +static jobject mtrack = NULL; + +static jmethodID mAudioTrack; +static jmethodID setStereoVolume; +static jmethodID mGetMinBufferSize; +static jmethodID mPlay; +static jmethodID mStop; +static jmethodID mRelease; +static jmethodID mWrite; +static jmethodID mFlush; + +#include +#define TAG "GPAC Android Audio" +#define LOGV(X, Y) __android_log_print(ANDROID_LOG_VERBOSE, TAG, X, Y) +#define LOGV3(X, Y, Z, K) __android_log_print(ANDROID_LOG_VERBOSE, TAG, X, Y, Z, K) +#define LOGD(X, Y) __android_log_print(ANDROID_LOG_DEBUG, TAG, X, Y) +#define LOGD2(X, Y, Z) __android_log_print(ANDROID_LOG_DEBUG, TAG, X, Y, Z) +#define LOGE(X, Y) __android_log_print(ANDROID_LOG_ERROR, TAG, X, Y) +#define LOGE3(X, Y, Z, W) __android_log_print(ANDROID_LOG_ERROR, TAG, X, Y, Z, W) +#define LOGW(X, Y) __android_log_print(ANDROID_LOG_WARN, TAG, X, Y) +#define LOGI(X, Y) __android_log_print(ANDROID_LOG_INFO, TAG, X, Y) + + +/* Uncomment the next line if you want to debug */ +/* #define DROID_EXTREME_LOGS */ + +typedef struct +{ + JNIEnv* env; + + jobject mtrack; + + u32 num_buffers; + + u32 delay, total_length_ms; + + Bool force_config; + u32 cfg_num_buffers, cfg_duration; + + u32 sampleRateInHz; + u32 channelConfig; //AudioFormat.CHANNEL_OUT_MONO + u32 audioFormat; //AudioFormat.ENCODING_PCM_16BIT + s32 mbufferSizeInBytes; + u32 volume; + u32 pan; + jarray buff; +} DroidContext; + +//---------------------------------------------------------------------- +//---------------------------------------------------------------------- +// Called by the main thread +static GF_Err WAV_Setup(GF_AudioOutput *dr, void *os_handle, u32 num_buffers, u32 total_duration) +{ + DroidContext *ctx = (DroidContext *)dr->opaque; + JNIEnv* env = GetEnv(); + int channels; + int bytes; + LOGV("[Android Audio] Setup for %d buffers", num_buffers); + + ctx->force_config = (num_buffers && total_duration) ? 1 : 0; + ctx->cfg_num_buffers = num_buffers; + if (ctx->cfg_num_buffers <= 1) ctx->cfg_num_buffers = 2; + ctx->cfg_duration = total_duration; + if (!ctx->force_config) ctx->num_buffers = 1; + ctx->volume = 100; + ctx->pan = 50; + + if (!cAudioTrack){ + cAudioTrack = (*env)->FindClass(env, "android/media/AudioTrack"); + if (!cAudioTrack) { + return GF_NOT_SUPPORTED; + } + + cAudioTrack = (*env)->NewGlobalRef(env, cAudioTrack); + + mAudioTrack = (*env)->GetMethodID(env, cAudioTrack, "", "(IIIIII)V"); + mGetMinBufferSize = (*env)->GetStaticMethodID(env, cAudioTrack, "getMinBufferSize", "(III)I"); + mPlay = (*env)->GetMethodID(env, cAudioTrack, "play", "()V"); + mStop = (*env)->GetMethodID(env, cAudioTrack, "stop", "()V"); + mRelease = (*env)->GetMethodID(env, cAudioTrack, "release", "()V"); + mWrite = (*env)->GetMethodID(env, cAudioTrack, "write", "([BII)I"); + mFlush = (*env)->GetMethodID(env, cAudioTrack, "flush", "()V"); + setStereoVolume = (*env)->GetMethodID(env, cAudioTrack, "setStereoVolume", "(FF)I"); + } + + return GF_OK; +} +//---------------------------------------------------------------------- +// Called by the audio thread +static void WAV_Shutdown(GF_AudioOutput *dr) +{ + DroidContext *ctx = (DroidContext *)dr->opaque; + JNIEnv* env = ctx->env; + + (*env)->CallNonvirtualVoidMethod(env, mtrack, cAudioTrack, mStop); + (*env)->CallNonvirtualVoidMethod(env, mtrack, cAudioTrack, mRelease); + + (*env)->PopLocalFrame(env, NULL); + + (*GetJavaVM())->DetachCurrentThread(GetJavaVM()); +} + + +/*we assume what was asked is what we got*/ +/* Called by the audio thread */ +static GF_Err WAV_ConfigureOutput(GF_AudioOutput *dr, u32 *SampleRate, u32 *NbChannels, u32 *nbBitsPerSample, u32 channel_cfg) +{ + JNIEnv* env = NULL; + u32 i; + DroidContext *ctx = (DroidContext *)dr->opaque; + + LOGI("[Android Audio] Configure Output for %u channels...", *NbChannels); + + if (!ctx) return GF_BAD_PARAM; + + ctx->sampleRateInHz = *SampleRate; + ctx->channelConfig = (*NbChannels == 1) ? CHANNEL_CONFIGURATION_MONO : CHANNEL_CONFIGURATION_STEREO; //AudioFormat.CHANNEL_CONFIGURATION_MONO + ctx->audioFormat = (*nbBitsPerSample == 8)? ENCODING_PCM_8BIT : ENCODING_PCM_16BIT; //AudioFormat.ENCODING_PCM_16BIT + + // Get the java environment in the new thread + (*GetJavaVM())->AttachCurrentThread(GetJavaVM(), &env, NULL); + ctx->env = env; + LOGV("[Android Audio] SampleRate : %d",ctx->sampleRateInHz); + LOGV("[Android Audio] BitPerSample : %d", *nbBitsPerSample); + + (*env)->PushLocalFrame(env, 2); + + ctx->num_buffers = 1; + ctx->mbufferSizeInBytes = (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, + ctx->sampleRateInHz, ctx->channelConfig, ctx->audioFormat); + + i = 1; + if ( ctx->channelConfig == CHANNEL_CONFIGURATION_STEREO ) + i *= 2; + if ( ctx->audioFormat == ENCODING_PCM_16BIT ) + i *= 2; + + ctx->total_length_ms = 1000 * ctx->num_buffers * ctx->mbufferSizeInBytes / i / ctx->sampleRateInHz; + + /*initial delay is full buffer size*/ + ctx->delay = ctx->total_length_ms; + + mtrack = (*env)->NewObject(env, cAudioTrack, mAudioTrack, STREAM_MUSIC, ctx->sampleRateInHz, + ctx->channelConfig, ctx->audioFormat, ctx->mbufferSizeInBytes, MODE_STREAM); //AudioTrack.MODE_STREAM + if (mtrack){ + mtrack = (*env)->NewGlobalRef(env, mtrack); + ctx->mtrack = mtrack; + (*env)->CallNonvirtualVoidMethod(env, mtrack, cAudioTrack, mPlay); + } else { + LOGV("[Android Audio] mtrack = %p", mtrack); + return GF_NOT_SUPPORTED; + } + + ctx->buff = (*env)->NewByteArray(env, ctx->mbufferSizeInBytes); + LOGV("[Android Audio] ConfigureOutput DONE.", *NbChannels); + return GF_OK; +} + +/* Called by the audio thread */ +static void WAV_WriteAudio(GF_AudioOutput *dr) +{ + DroidContext *ctx = (DroidContext *)dr->opaque; + if (!ctx) + return; + JNIEnv* env = ctx->env; + u32 written; + void* pBuffer; + if (!env) + return; +#ifdef DROID_EXTREME_LOGS + LOGV("[Android Audio] WAV_WriteAudio() : entering",ctx->sampleRateInHz); +#endif /* DROID_EXTREME_LOGS */ + pBuffer = (*env)->GetPrimitiveArrayCritical(env, ctx->buff, NULL); + if (pBuffer) + { + written = dr->FillBuffer(dr->audio_renderer, pBuffer, ctx->mbufferSizeInBytes); + (*env)->ReleasePrimitiveArrayCritical(env, ctx->buff, pBuffer, 0); + if (written) + { + (*env)->CallNonvirtualIntMethod(env, mtrack, cAudioTrack, mWrite, ctx->buff, 0, ctx->mbufferSizeInBytes); + } + } + else + { + LOGV("[Android Audio] Failed to get pointer to array bytes = %p", pBuffer); + } +#ifdef DROID_EXTREME_LOGS + LOGV("[Android Audio] WAV_WriteAudio() : done",ctx->sampleRateInHz); +#endif /* DROID_EXTREME_LOGS */ +} + +/* Called by the main thread */ +static void WAV_Play(GF_AudioOutput *dr, u32 PlayType) +{ + DroidContext *ctx = (DroidContext *)dr->opaque; + JNIEnv* env = GetEnv(); + + LOGV("[Android Audio] Play: %d\n", PlayType); + + switch ( PlayType ) + { + case 0: + // Stop playing + (*env)->CallNonvirtualVoidMethod(env, mtrack, cAudioTrack, mStop); + // Clear the internal buffers + (*env)->CallNonvirtualVoidMethod(env, mtrack, cAudioTrack, mFlush); + break; + case 1: + case 2: + (*env)->CallNonvirtualVoidMethod(env, mtrack, cAudioTrack, mPlay); + break; + default: + LOGW("[Android Audio] Unknown Play method=%d.\n", PlayType); + } + LOGV("[Android Audio] Play DONE (%d).\n", PlayType); +} + +static void WAV_UpdateVolume(DroidContext *ctx){ + float lV, rV; + JNIEnv* env = GetEnv(); + if (!ctx) + return; + if (ctx->pan > 100) + ctx->pan = 100; + lV =rV = ctx->volume / 100.0; + if (ctx->pan > 50){ + float m = (100 - ctx->pan) / 50.0; + lV*=m; + } else if (ctx->pan < 50){ + float m = ctx->pan / 50.0; + rV*=m; + } + if (env && setStereoVolume && mtrack && cAudioTrack){ + int success; + if (0!= (success=((*env)->CallNonvirtualIntMethod(env, mtrack, cAudioTrack, setStereoVolume, lV, rV)))) + LOGE3("SetVolume(%f,%f) returned Error code %d", lV, rV, success ); + } else { + LOGD2("SetVolume(%f,%f)", lV, rV ); + } +} + +static void WAV_SetVolume(GF_AudioOutput *dr, u32 Volume) { + DroidContext *ctx = (DroidContext *)dr->opaque; + ctx->volume = Volume; + WAV_UpdateVolume(ctx); +} + +static void WAV_SetPan(GF_AudioOutput *dr, u32 Pan) +{ + DroidContext *ctx = (DroidContext *)dr->opaque; + WAV_UpdateVolume(ctx); +} + +/* Called by the audio thread */ +static GF_Err WAV_QueryOutputSampleRate(GF_AudioOutput *dr, u32 *desired_samplerate, u32 *NbChannels, u32 *nbBitsPerSample) +{ + DroidContext *ctx = (DroidContext *)dr->opaque; + JNIEnv* env = ctx->env; + u32 sampleRateInHz, channelConfig, audioFormat; + + LOGV("Query sample=%d", *desired_samplerate ); + +#ifdef TEST_QUERY_SAMPLE + sampleRateInHz = *desired_samplerate; + channelConfig = (*NbChannels == 1) ? CHANNEL_CONFIGURATION_MONO : CHANNEL_CONFIGURATION_STEREO; + audioFormat = (*nbBitsPerSample == 8)? ENCODING_PCM_8BIT : ENCODING_PCM_16BIT; + + LOGV3("[Android Audio] Query: SampleRate ChannelConfig AudioFormat: %d %d %d \n", + sampleRateInHz, + (channelConfig == CHANNEL_CONFIGURATION_MONO)? 1 : 2, + (ctx->audioFormat == ENCODING_PCM_8BIT)? 8 : 16); + + switch (*desired_samplerate) { + case 11025: + *desired_samplerate = 11025; + if ( (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, + *desired_samplerate, channelConfig, audioFormat) > 0 ) + return GF_OK; + case 22050: + *desired_samplerate = 22050; + if ( (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, + *desired_samplerate, channelConfig, audioFormat) > 0 ) + return GF_OK; + break; + case 8000: + *desired_samplerate = 8000; + if ( (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, + *desired_samplerate, channelConfig, audioFormat) > 0 ) + return GF_OK; + case 16000: + *desired_samplerate = 16000; + if ( (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, + *desired_samplerate, channelConfig, audioFormat) > 0 ) + return GF_OK; + case 32000: + *desired_samplerate = 32000; + if ( (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, + *desired_samplerate, channelConfig, audioFormat) > 0 ) + return GF_OK; + break; + case 24000: + *desired_samplerate = 24000; + if ( (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, + *desired_samplerate, channelConfig, audioFormat) > 0 ) + return GF_OK; + case 48000: + *desired_samplerate = 48000; + if ( (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, + *desired_samplerate, channelConfig, audioFormat) > 0 ) + return GF_OK; + break; + case 44100: + *desired_samplerate = 44100; + if ( (*env)->CallStaticIntMethod(env, cAudioTrack, mGetMinBufferSize, + *desired_samplerate, channelConfig, audioFormat) > 0 ) + return GF_OK; + break; + default: + break; + } +#endif + + return GF_OK; +} + +static u32 WAV_GetAudioDelay(GF_AudioOutput *dr) +{ + DroidContext *ctx = (DroidContext *)dr->opaque; + + return ctx->delay; +} + +static u32 WAV_GetTotalBufferTime(GF_AudioOutput *dr) +{ + DroidContext *ctx = (DroidContext *)dr->opaque; + + return ctx->total_length_ms; +} + +//---------------------------------------------------------------------- +void *NewWAVRender() +{ + DroidContext *ctx; + GF_AudioOutput *driv; + ctx = gf_malloc(sizeof(DroidContext)); + memset(ctx, 0, sizeof(DroidContext)); + ctx->num_buffers = 1; + ctx->pan = 50; + ctx->volume = 100; + driv = gf_malloc(sizeof(GF_AudioOutput)); + memset(driv, 0, sizeof(GF_AudioOutput)); + GF_REGISTER_MODULE_INTERFACE(driv, GF_AUDIO_OUTPUT_INTERFACE, "Android Audio Output", "gpac distribution") + + driv->opaque = ctx; + + driv->SelfThreaded = 0; + driv->Setup = WAV_Setup; + driv->Shutdown = WAV_Shutdown; + driv->ConfigureOutput = WAV_ConfigureOutput; + driv->GetAudioDelay = WAV_GetAudioDelay; + driv->GetTotalBufferTime = WAV_GetTotalBufferTime; + driv->SetVolume = WAV_SetVolume; + driv->SetPan = WAV_SetPan; + driv->Play = WAV_Play; + driv->QueryOutputSampleRate = WAV_QueryOutputSampleRate; + driv->WriteAudio = WAV_WriteAudio; + return driv; +} +//---------------------------------------------------------------------- +void DeleteWAVRender(void *ifce) +{ + GF_AudioOutput *dr = (GF_AudioOutput *) ifce; + if (!ifce) + return; + gf_free(dr); +} +//---------------------------------------------------------------------- +const u32 *QueryInterfaces() +{ + static u32 si [] = { + GF_AUDIO_OUTPUT_INTERFACE, + 0 + }; + return si; +} + +GF_BaseInterface *LoadInterface(u32 InterfaceType) +{ + if (InterfaceType == GF_AUDIO_OUTPUT_INTERFACE) return NewWAVRender(); + return NULL; +} + +void ShutdownInterface(GF_BaseInterface *ifce) +{ + switch (ifce->InterfaceType) { + case GF_AUDIO_OUTPUT_INTERFACE: + DeleteWAVRender((GF_AudioOutput *) ifce); + break; + } +} diff --git a/modules/droid_audio/javaenv.c b/modules/droid_audio/javaenv.c index ce552a3..26148bf 100644 --- a/modules/droid_audio/javaenv.c +++ b/modules/droid_audio/javaenv.c @@ -1,51 +1,51 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) ENST 2009- - * Authors: Jean Le Feuvre - * All rights reserved - * - * Created by Arsov Ivica / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010 - * - * This file is part of GPAC / Wrapper - * - * 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 "javaenv.h" - -static JavaVM* javaVM = 0; - -//---------------------------------------------------------------------- -jint JNI_OnLoad(JavaVM* vm, void* reserved) -{ - javaVM = vm; - return JNI_VERSION_1_2; -} -//---------------------------------------------------------------------- -JNIEnv* GetEnv() -{ - JNIEnv* env = 0; - //if (javaVM) javaVM->GetEnv((void**)&env, JNI_VERSION_1_2); - if (javaVM) (*javaVM)->GetEnv(javaVM, (void**)&env, JNI_VERSION_1_2); - return env; -} -//---------------------------------------------------------------------- -JavaVM* GetJavaVM() -{ - return javaVM; -} -//---------------------------------------------------------------------- +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) ENST 2009- + * Authors: Jean Le Feuvre + * All rights reserved + * + * Created by Arsov Ivica / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010 + * + * This file is part of GPAC / Wrapper + * + * 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 "javaenv.h" + +static JavaVM* javaVM = 0; + +//---------------------------------------------------------------------- +jint JNI_OnLoad(JavaVM* vm, void* reserved) +{ + javaVM = vm; + return JNI_VERSION_1_2; +} +//---------------------------------------------------------------------- +JNIEnv* GetEnv() +{ + JNIEnv* env = 0; + //if (javaVM) javaVM->GetEnv((void**)&env, JNI_VERSION_1_2); + if (javaVM) (*javaVM)->GetEnv(javaVM, (void**)&env, JNI_VERSION_1_2); + return env; +} +//---------------------------------------------------------------------- +JavaVM* GetJavaVM() +{ + return javaVM; +} +//---------------------------------------------------------------------- diff --git a/modules/droid_audio/javaenv.h b/modules/droid_audio/javaenv.h index de8adc7..813ee82 100644 --- a/modules/droid_audio/javaenv.h +++ b/modules/droid_audio/javaenv.h @@ -1,36 +1,36 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) ENST 2009- - * Authors: Jean Le Feuvre - * All rights reserved - * - * Created by Arsov Ivica / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010 - * - * This file is part of GPAC / Wrapper - * - * 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. - * - */ - -#ifndef JAVA_ENV -#define JAVA_ENV - -#include - -JavaVM* GetJavaVM(); -JNIEnv* GetEnv(); - -#endif //JAVA_ENV +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) ENST 2009- + * Authors: Jean Le Feuvre + * All rights reserved + * + * Created by Arsov Ivica / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010 + * + * This file is part of GPAC / Wrapper + * + * 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. + * + */ + +#ifndef JAVA_ENV +#define JAVA_ENV + +#include + +JavaVM* GetJavaVM(); +JNIEnv* GetEnv(); + +#endif //JAVA_ENV diff --git a/modules/droid_out/droid_vout-bitmap.c b/modules/droid_out/droid_vout-bitmap.c index 98d5a51..09933c1 100644 --- a/modules/droid_out/droid_vout-bitmap.c +++ b/modules/droid_out/droid_vout-bitmap.c @@ -1,216 +1,216 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) ENST 2009- - * Authors: Jean Le Feuvre - * All rights reserved - * - * Created by NGO Van Luyen, Ivica ARSOV / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010 - * - * This file is part of GPAC / Wrapper - * - * 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. - * - */ - - -/*driver interfaces*/ -#include -#include -#include - -#include - -#include - -typedef struct -{ - JNIEnv * env; - jobject * bitmap; - u32 width, height; - void * locked_data; -} AndroidContext; - - -#define RAW_OUT_PIXEL_FORMAT GF_PIXEL_RGB_32 -#define NBPP 4 - -#define RAWCTX AndroidContext *rc = (AndroidContext *)dr->opaque - -static GF_Err raw_resize(GF_VideoOutput *dr, u32 w, u32 h) -{ - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout raw_resize\n")); - return GF_OK; -} - -GF_Err RAW_Setup(GF_VideoOutput *dr, void *os_handle, void *os_display, u32 init_flags) -{ - AndroidBitmapInfo info; - RAWCTX; - void * pixels; - int ret; - - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout RAW_Setup\n")); - - if (!rc->width) - { - rc->env = (JNIEnv *)os_handle; - rc->bitmap = (jobject *)os_display; - - AndroidBitmap_getInfo(rc->env, *(rc->bitmap), &info); - rc->width = info.width; - rc->height = info.height; - rc->locked_data = NULL; - } - else - { - rc->env = (JNIEnv *)os_handle; - rc->bitmap = (jobject *)os_display; - } - - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout rc dims: %d:%d\n", rc->height, rc->width)); - - return GF_OK; -} - - -static void RAW_Shutdown(GF_VideoOutput *dr) -{ - RAWCTX; - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout RAW_Shutdown\n")); - rc->bitmap = NULL; -} - - -static GF_Err RAW_Flush(GF_VideoOutput *dr, GF_Window *dest) -{ - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout RAW_Flush\n")); - return GF_OK; -} - -static GF_Err RAW_LockBackBuffer(GF_VideoOutput *dr, GF_VideoSurface *vi, Bool do_lock) -{ - RAWCTX; - int ret; - void * pixels; - - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout RAW_LockBackBuffer: %d\n", do_lock)); - if (do_lock) { - if (!vi) return GF_BAD_PARAM; - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout locked_data: %d\n", rc->locked_data)); - if (!rc->locked_data) - { - if ((ret = AndroidBitmap_lockPixels(rc->env, *(rc->bitmap), &pixels)) < 0) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout lock failed\n")); - } - rc->locked_data = pixels; - } - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout rc dims: %d:%d\n", rc->height, rc->width)); - vi->height = rc->height; - vi->width = rc->width; - vi->video_buffer = rc->locked_data; - vi->is_hardware_memory = 0; - vi->pitch_x = NBPP; - vi->pitch_y = NBPP * vi->width; - vi->pixel_format = RAW_OUT_PIXEL_FORMAT; - } - else - { - if (rc->locked_data) - { - AndroidBitmap_unlockPixels(rc->env, *(rc->bitmap)); - rc->locked_data = NULL; - } - } - return GF_OK; -} - -static GF_Err RAW_ProcessEvent(GF_VideoOutput *dr, GF_Event *evt) -{ - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout RAW_ProcessEvent\n")); - if (evt) { - switch (evt->type) { - case GF_EVENT_SIZE: - //if (evt->setup.opengl_mode) return GF_OK; - return raw_resize(dr, evt->setup.width, evt->setup.height); - case GF_EVENT_VIDEO_SETUP: - return GF_OK; - } - } - return GF_OK; -} - -GF_VideoOutput *NewRawVideoOutput() -{ - AndroidContext *pCtx; - GF_VideoOutput *driv = (GF_VideoOutput *) gf_malloc(sizeof(GF_VideoOutput)); - memset(driv, 0, sizeof(GF_VideoOutput)); - GF_REGISTER_MODULE_INTERFACE(driv, GF_VIDEO_OUTPUT_INTERFACE, "Android Video Output", "gpac distribution") - - pCtx = gf_malloc(sizeof(AndroidContext)); - memset(pCtx, 0, sizeof(AndroidContext)); - - driv->opaque = pCtx; - - driv->Flush = RAW_Flush; - driv->LockBackBuffer = RAW_LockBackBuffer; - driv->Setup = RAW_Setup; - driv->Shutdown = RAW_Shutdown; - driv->ProcessEvent = RAW_ProcessEvent; - - driv->hw_caps = GF_VIDEO_HW_OPENGL; - - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout init\n")); - return (void *)driv; -} - -void DeleteVideoOutput(void *ifce) -{ - AndroidContext *rc; - GF_VideoOutput *driv = (GF_VideoOutput *) ifce; - - RAW_Shutdown(driv); - rc = (AndroidContext *)driv->opaque; - gf_free(rc); - gf_free(driv); - - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout deinit\n")); -} - -/*interface query*/ -GF_EXPORT -const u32 *QueryInterfaces() -{ - static u32 si [] = { - GF_VIDEO_OUTPUT_INTERFACE, - 0 - }; - return si; -} -/*interface create*/ -GF_BaseInterface *LoadInterface(u32 InterfaceType) -{ - if (InterfaceType == GF_VIDEO_OUTPUT_INTERFACE) return (GF_BaseInterface *) NewRawVideoOutput(); - return NULL; -} -/*interface destroy*/ -void ShutdownInterface(GF_BaseInterface *ifce) -{ - switch (ifce->InterfaceType) { - case GF_VIDEO_OUTPUT_INTERFACE: - DeleteVideoOutput((GF_VideoOutput *)ifce); - break; - } -} +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) ENST 2009- + * Authors: Jean Le Feuvre + * All rights reserved + * + * Created by NGO Van Luyen, Ivica ARSOV / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010 + * + * This file is part of GPAC / Wrapper + * + * 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. + * + */ + + +/*driver interfaces*/ +#include +#include +#include + +#include + +#include + +typedef struct +{ + JNIEnv * env; + jobject * bitmap; + u32 width, height; + void * locked_data; +} AndroidContext; + + +#define RAW_OUT_PIXEL_FORMAT GF_PIXEL_RGB_32 +#define NBPP 4 + +#define RAWCTX AndroidContext *rc = (AndroidContext *)dr->opaque + +static GF_Err raw_resize(GF_VideoOutput *dr, u32 w, u32 h) +{ + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout raw_resize\n")); + return GF_OK; +} + +GF_Err RAW_Setup(GF_VideoOutput *dr, void *os_handle, void *os_display, u32 init_flags) +{ + AndroidBitmapInfo info; + RAWCTX; + void * pixels; + int ret; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout RAW_Setup\n")); + + if (!rc->width) + { + rc->env = (JNIEnv *)os_handle; + rc->bitmap = (jobject *)os_display; + + AndroidBitmap_getInfo(rc->env, *(rc->bitmap), &info); + rc->width = info.width; + rc->height = info.height; + rc->locked_data = NULL; + } + else + { + rc->env = (JNIEnv *)os_handle; + rc->bitmap = (jobject *)os_display; + } + + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout rc dims: %d:%d\n", rc->height, rc->width)); + + return GF_OK; +} + + +static void RAW_Shutdown(GF_VideoOutput *dr) +{ + RAWCTX; + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout RAW_Shutdown\n")); + rc->bitmap = NULL; +} + + +static GF_Err RAW_Flush(GF_VideoOutput *dr, GF_Window *dest) +{ + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout RAW_Flush\n")); + return GF_OK; +} + +static GF_Err RAW_LockBackBuffer(GF_VideoOutput *dr, GF_VideoSurface *vi, Bool do_lock) +{ + RAWCTX; + int ret; + void * pixels; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout RAW_LockBackBuffer: %d\n", do_lock)); + if (do_lock) { + if (!vi) return GF_BAD_PARAM; + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout locked_data: %d\n", rc->locked_data)); + if (!rc->locked_data) + { + if ((ret = AndroidBitmap_lockPixels(rc->env, *(rc->bitmap), &pixels)) < 0) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout lock failed\n")); + } + rc->locked_data = pixels; + } + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout rc dims: %d:%d\n", rc->height, rc->width)); + vi->height = rc->height; + vi->width = rc->width; + vi->video_buffer = rc->locked_data; + vi->is_hardware_memory = 0; + vi->pitch_x = NBPP; + vi->pitch_y = NBPP * vi->width; + vi->pixel_format = RAW_OUT_PIXEL_FORMAT; + } + else + { + if (rc->locked_data) + { + AndroidBitmap_unlockPixels(rc->env, *(rc->bitmap)); + rc->locked_data = NULL; + } + } + return GF_OK; +} + +static GF_Err RAW_ProcessEvent(GF_VideoOutput *dr, GF_Event *evt) +{ + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout RAW_ProcessEvent\n")); + if (evt) { + switch (evt->type) { + case GF_EVENT_SIZE: + //if (evt->setup.opengl_mode) return GF_OK; + return raw_resize(dr, evt->setup.width, evt->setup.height); + case GF_EVENT_VIDEO_SETUP: + return GF_OK; + } + } + return GF_OK; +} + +GF_VideoOutput *NewRawVideoOutput() +{ + AndroidContext *pCtx; + GF_VideoOutput *driv = (GF_VideoOutput *) gf_malloc(sizeof(GF_VideoOutput)); + memset(driv, 0, sizeof(GF_VideoOutput)); + GF_REGISTER_MODULE_INTERFACE(driv, GF_VIDEO_OUTPUT_INTERFACE, "Android Video Output", "gpac distribution") + + pCtx = gf_malloc(sizeof(AndroidContext)); + memset(pCtx, 0, sizeof(AndroidContext)); + + driv->opaque = pCtx; + + driv->Flush = RAW_Flush; + driv->LockBackBuffer = RAW_LockBackBuffer; + driv->Setup = RAW_Setup; + driv->Shutdown = RAW_Shutdown; + driv->ProcessEvent = RAW_ProcessEvent; + + driv->hw_caps = GF_VIDEO_HW_OPENGL; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout init\n")); + return (void *)driv; +} + +void DeleteVideoOutput(void *ifce) +{ + AndroidContext *rc; + GF_VideoOutput *driv = (GF_VideoOutput *) ifce; + + RAW_Shutdown(driv); + rc = (AndroidContext *)driv->opaque; + gf_free(rc); + gf_free(driv); + + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("Android vout deinit\n")); +} + +/*interface query*/ +GF_EXPORT +const u32 *QueryInterfaces() +{ + static u32 si [] = { + GF_VIDEO_OUTPUT_INTERFACE, + 0 + }; + return si; +} +/*interface create*/ +GF_BaseInterface *LoadInterface(u32 InterfaceType) +{ + if (InterfaceType == GF_VIDEO_OUTPUT_INTERFACE) return (GF_BaseInterface *) NewRawVideoOutput(); + return NULL; +} +/*interface destroy*/ +void ShutdownInterface(GF_BaseInterface *ifce) +{ + switch (ifce->InterfaceType) { + case GF_VIDEO_OUTPUT_INTERFACE: + DeleteVideoOutput((GF_VideoOutput *)ifce); + break; + } +} diff --git a/modules/droid_out/droid_vout.c b/modules/droid_out/droid_vout.c index dcdd350..ac199e9 100644 --- a/modules/droid_out/droid_vout.c +++ b/modules/droid_out/droid_vout.c @@ -1,664 +1,664 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) ENST 2009- - * Authors: Jean Le Feuvre - * All rights reserved - * - * Created by NGO Van Luyen, Ivica ARSOV / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010 - * - * This file is part of GPAC / Wrapper - * - * 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. - * - */ - -/*driver interfaces*/ -#include -#include -#include - -#include - -#include -#include - -#include - -#define TAG "DROID_VIDEO" - -#define LOG __android_log_print - -#ifdef PI -#undef PI -#endif - -#define PI 3.1415926535897932f - -/* Uncomment the next line if you want to debug */ -/* #define DROID_EXTREME_LOGS */ - -typedef struct -{ - u32 width, height; - void * locked_data; - u8 out_3d_type; - - u32 tex_width, tex_height; - - GLuint texID; - GLuint framebuff; - GLuint depthbuff; - - GLubyte* texData; - - u8 draw_texture; - u8 non_power_two; -} AndroidContext; - - -#define RAW_OUT_PIXEL_FORMAT GF_PIXEL_RGBA -#define NBPP 4 - -#define RAWCTX AndroidContext *rc = (AndroidContext *)dr->opaque - -//#define GLES_FRAMEBUFFER_TEST - -#ifdef GLES_FRAMEBUFFER_TEST -#warning "Using FrameBuffer" -#endif - -void initGL(AndroidContext *rc) -{ - char* ext; - - LOG( ANDROID_LOG_DEBUG, TAG, "Android InitGL"); - - ext = (char*)glGetString(GL_VENDOR); - LOG( ANDROID_LOG_INFO, TAG, "OpenGL ES Vendor: %s", ext); - - ext = (char*)glGetString(GL_RENDERER); - LOG( ANDROID_LOG_INFO, TAG, "OpenGL ES Renderer: %s", ext); - - ext = (char*)glGetString(GL_VERSION); - LOG( ANDROID_LOG_INFO, TAG, "OpenGL ES Version: %s", ext); - - ext = (char*)glGetString(GL_EXTENSIONS); - LOG( ANDROID_LOG_INFO, TAG, "OpenGL ES Extensions: %s", ext); - - if ( strstr(ext, "GL_OES_draw_texture") ) - { - rc->draw_texture = 1; - LOG( ANDROID_LOG_INFO, TAG, "Using GL_OES_draw_texture"); - } - if ( strstr(ext, "GL_ARB_texture_non_power_of_two") ) - { - rc->non_power_two = 0; - LOG( ANDROID_LOG_INFO, TAG, "Using GL_ARB_texture_non_power_of_two"); - } - - /* Enable smooth shading */ - glShadeModel(GL_SMOOTH); - - /* Set the background black */ - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - - /* Depth buffer setup */ - glClearDepthf(1.0f); - - /* Enables Depth Testing */ - glEnable(GL_DEPTH_TEST); - - /* The Type Of Depth Test To Do */ - glDepthFunc(GL_LEQUAL); - - /* Really Nice Perspective Calculations */ - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - - glDisable(GL_CULL_FACE | GL_NORMALIZE | GL_LIGHTING | GL_BLEND | GL_FOG | GL_COLOR_MATERIAL | GL_TEXTURE_2D); -} - -void gluPerspective(GLfloat fovy, GLfloat aspect, - GLfloat zNear, GLfloat zFar) -{ - GLfloat xmin, xmax, ymin, ymax; - - ymax = zNear * (GLfloat)tan(fovy * PI / 360); - ymin = -ymax; - xmin = ymin * aspect; - xmax = ymax * aspect; - - glFrustumx((GLfixed)(xmin * 65536), (GLfixed)(xmax * 65536), - (GLfixed)(ymin * 65536), (GLfixed)(ymax * 65536), - (GLfixed)(zNear * 65536), (GLfixed)(zFar * 65536)); -} - -void resizeWindow(AndroidContext *rc) -{ - LOG( ANDROID_LOG_VERBOSE, TAG, "resizeWindow : start"); - /* Height / width ration */ - GLfloat ratio; - - /* Protect against a divide by zero */ - if (rc->height==0) - { - rc->height=1; - } - - ratio=(GLfloat)rc->width/(GLfloat)rc->height; - - /* Setup our viewport. */ - glViewport(0, 0, (GLsizei)rc->width, (GLsizei)rc->height); - - /* change to the projection matrix and set our viewing volume. */ - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - /* Set our perspective */ - glOrthox(0, INT2FIX(rc->width), 0, INT2FIX(rc->height), INT2FIX(-1), INT2FIX(1)); - - /* Make sure we're chaning the model view and not the projection */ - glMatrixMode(GL_MODELVIEW); - - /* Reset The View */ - glLoadIdentity(); - LOG( ANDROID_LOG_VERBOSE, TAG, "resizeWindow : end"); -} - -void drawGLScene(AndroidContext *rc) -{ -#ifdef DROID_EXTREME_LOGS - LOG( ANDROID_LOG_VERBOSE, TAG, "drawGLScene : start"); -#endif /* DROID_EXTREME_LOGS */ - GLfloat vertices[4][3]; - GLfloat texcoord[4][2]; -// int i, j; - - float rgba[4]; - -#ifdef GLES_FRAMEBUFFER_TEST - glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); -#endif - - // Reset states - rgba[0] = rgba[1] = rgba[2] = 0.f; - rgba[0] = 1.f; - glColor4f(1.f, 1.f, 1.f, 1.f); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, rgba); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, rgba); - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, rgba); - glDisable(GL_CULL_FACE | GL_NORMALIZE | GL_LIGHTING | GL_BLEND | GL_FOG | GL_COLOR_MATERIAL | GL_TEXTURE_2D); - - /* Clear The Screen And The Depth Buffer */ - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - //glEnable(GL_BLEND); - //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glEnable(GL_TEXTURE_2D); - glBindTexture( GL_TEXTURE_2D, rc->texID); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); - glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - -// for ( i = 0; i < rc->height/2; i++ ) -// for ( j = 0; j < rc->width; j++ ) -// rc->texData[ i*rc->width*NBPP + j*NBPP + 3] = 200; - -// memset(rc->texData, 255, 4 * rc->width * rc->height ); -#ifndef GLES_FRAMEBUFFER_TEST - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, rc->tex_width, rc->tex_height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, rc->texData ); -#endif - - if ( rc->draw_texture ) - { - int cropRect[4] = {0,rc->height,rc->width,-rc->height}; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); - - glDrawTexsOES(0, 0, 0, rc->width, rc->height); - } - else - { - /* Enable VERTEX array */ - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - /* Setup pointer to VERTEX array */ - glVertexPointer(3, GL_FLOAT, 0, vertices); - glTexCoordPointer(2, GL_FLOAT, 0, texcoord); - - /* Move Left 1.5 Units And Into The Screen 6.0 */ - glLoadIdentity(); - //glTranslatef(0.0f, 0.0f, -3.3f); - //glTranslatef(0.0f, 0.0f, -2.3f); - - /* Top Right Of The Quad */ - vertices[0][0]=rc->tex_width; vertices[0][1]=rc->tex_height; vertices[0][2]=0.0f; - texcoord[0][0]=1.f; texcoord[0][1]=0.f; - /* Top Left Of The Quad */ - vertices[1][0]=0.f; vertices[1][1]=rc->tex_height; vertices[1][2]=0.0f; - texcoord[1][0]=0.f; texcoord[1][1]=0.f; - /* Bottom Left Of The Quad */ - vertices[2][0]=rc->tex_width; vertices[2][1]=0.f; vertices[2][2]=0.0f; - texcoord[2][0]=1.f; texcoord[2][1]=1.f; - /* Bottom Right Of The Quad */ - vertices[3][0]=0.f; vertices[3][1]=0.f; vertices[3][2]=0.0f; - texcoord[3][0]=0.f; texcoord[3][1]=1.f; - - /* Drawing using triangle strips, draw triangles using 4 vertices */ - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - /* Disable vertex array */ - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - - glDisable(GL_TEXTURE_2D); - - /* Flush all drawings */ - glFinish(); -#ifdef GLES_FRAMEBUFFER_TEST - glBindFramebufferOES(GL_FRAMEBUFFER_OES, rc->framebuff); -#endif -#ifdef DROID_EXTREME_LOGS - LOG( ANDROID_LOG_VERBOSE, TAG, "drawGLScene : end"); -#endif /* DROID_EXTREME_LOGS */ -} - -int releaseTexture(AndroidContext *rc) -{ - if (!rc) - return 0; - LOG( ANDROID_LOG_DEBUG, TAG, "Android Delete Texture"); - - if ( rc->texID >= 0 ) - { - glDeleteTextures(1, &(rc->texID)); - rc->texID = -1; - } - if (rc->texData) - { - gf_free(rc->texData); - rc->texData = NULL; - } - LOG( ANDROID_LOG_VERBOSE, TAG, "Android Delete Texture DONE"); - return 0; -} - -int createTexture(AndroidContext *rc) -{ - if (!rc) - return 0; - if ( rc->texID >= 0 ) - releaseTexture(rc); - - LOG( ANDROID_LOG_INFO, TAG, "Android Create Texture Size: WxH: %dx%d", - rc->tex_width, rc->tex_height); - - glGenTextures( 1, &(rc->texID) ); - - rc->texData = (GLubyte*)gf_malloc( 4 * rc->tex_width * rc->tex_height ); - memset(rc->texData, 255, 4 * rc->tex_width * rc->tex_height ); - //memset(data, 0, 4 * width * height/2 ); - - glBindTexture( GL_TEXTURE_2D, rc->texID); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); - glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, rc->tex_width, rc->tex_height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL/*rc->texData*/ ); - - glBindTexture( GL_TEXTURE_2D, 0); - LOG( ANDROID_LOG_VERBOSE, TAG, "Android Create Texture DONE"); - return 0; -} - -#ifdef GLES_FRAMEBUFFER_TEST - -int releaseFrameBuffer(AndroidContext *rc) -{ - LOG( ANDROID_LOG_DEBUG, TAG, "Android Delete FrameBuffer"); - - glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); - - if ( rc->framebuff >= 0 ) - { - glDeleteFramebuffersOES(1, &(rc->framebuff)); - rc->framebuff = -1; - } - if ( rc->depthbuff >= 0 ) - { - glDeleteRenderbuffersOES(1, &(rc->depthbuff)); - rc->depthbuff = -1; - } -} - -int createFrameBuffer(AndroidContext *rc) -{ - int backingWidth; - int backingHeight; - int res; - - if ( rc->framebuff >= 0 ) - releaseFrameBuffer(rc); - - LOG( ANDROID_LOG_DEBUG, TAG, "Android Create FrameBuffer")); - - glGenFramebuffersOES(1, &(rc->framebuff)); - glBindFramebufferOES(GL_FRAMEBUFFER_OES, rc->framebuff); - -// glGenRenderbuffersOES(1, &(rc->depthbuff)); -// glBindRenderbufferOES(GL_RENDERBUFFER_OES, rc->depthbuff); - -// glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); -// glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); - -// LOG( ANDROID_LOG_ERROR, TAG, "Android Depth Buffer Size: %dx%d\n", backingWidth, backingHeight)); - -// glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, rc->width, rc->height); - -// glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, -// GL_RENDERBUFFER_OES, rc->depthbuff); - - glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, - GL_TEXTURE_2D, rc->texID, 0); - - if ( (res=(int)glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)) != GL_FRAMEBUFFER_COMPLETE_OES ) - { - LOG( ANDROID_LOG_ERROR, TAG, "Android failed to make complete framebuffer object:"); - switch (res) - { - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES: - LOG( ANDROID_LOG_ERROR, TAG, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES: - LOG( ANDROID_LOG_ERROR, TAG, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES: - LOG( ANDROID_LOG_ERROR, TAG, "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES"); - break; - case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES: - LOG( ANDROID_LOG_ERROR, TAG, "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES"); - break; - case GL_FRAMEBUFFER_UNSUPPORTED_OES: - LOG( ANDROID_LOG_ERROR, TAG, "GL_FRAMEBUFFER_UNSUPPORTED_OES"); - break; - default : - LOG( ANDROID_LOG_ERROR, TAG, "Unknown error: %d", res); - break; - } - - return 1; - } - - //glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); - - return 0; -} - -#endif - -u32 find_pow_2(u32 num) -{ - u32 res = 1; - while (res < num) - res *= 2; - return res; -} - -static GF_Err droid_Resize(GF_VideoOutput *dr, u32 w, u32 h) -{ - RAWCTX; - LOG( ANDROID_LOG_DEBUG, TAG, "Android Resize: %dx%d", w, h); - - rc->width = w; - rc->height = h; - - if ( rc->non_power_two ) - { - rc->tex_width = rc->width; - rc->tex_height = rc->height; - } - else - { - rc->tex_width = find_pow_2(rc->width); - rc->tex_height = find_pow_2(rc->height); - } - - resizeWindow(rc); - - if ( rc->out_3d_type == 0 ) - { - createTexture(rc); -#ifdef GLES_FRAMEBUFFER_TEST - createFrameBuffer(rc); -#endif - } - LOG( ANDROID_LOG_VERBOSE, TAG, "Android Resize DONE", w, h); - return GF_OK; -} - -GF_Err droid_Setup(GF_VideoOutput *dr, void *os_handle, void *os_display, u32 init_flags) -{ - RAWCTX; - void * pixels; - int ret; - - LOG( ANDROID_LOG_DEBUG, TAG, "Android Setup: %d", init_flags); - -#ifndef GLES_FRAMEBUFFER_TEST - if ( rc->out_3d_type == 0 ) -#endif - initGL(rc); - LOG( ANDROID_LOG_VERBOSE, TAG, "Android Setup DONE"); - return GF_OK; -} - - -static void droid_Shutdown(GF_VideoOutput *dr) -{ - RAWCTX; - LOG( ANDROID_LOG_DEBUG, TAG, "Android Shutdown\n"); - - releaseTexture(rc); -#ifdef GLES_FRAMEBUFFER_TEST - releaseFrameBuffer(rc); -#endif - LOG( ANDROID_LOG_VERBOSE, TAG, "Android Shutdown DONE"); -} - - -static GF_Err droid_Flush(GF_VideoOutput *dr, GF_Window *dest) -{ - RAWCTX; -#ifdef DROID_EXTREME_LOGS - LOG( ANDROID_LOG_VERBOSE, TAG, "Android Flush\n"); -#endif /* DROID_EXTREME_LOGS */ - -#ifndef GLES_FRAMEBUFFER_TEST - if ( rc->out_3d_type == 0 ) -#endif - drawGLScene(rc); -#ifdef DROID_EXTREME_LOGS - LOG( ANDROID_LOG_VERBOSE, TAG, "Android Flush DONE"); -#endif /* DROID_EXTREME_LOGS */ - return GF_OK; -} - -static GF_Err droid_LockBackBuffer(GF_VideoOutput *dr, GF_VideoSurface *vi, Bool do_lock) -{ - RAWCTX; - int ret; - void * pixels; - int i,j,t; -#ifdef DROID_EXTREME_LOGS - LOG( ANDROID_LOG_VERBOSE, TAG, "Android LockBackBuffer: %d", do_lock); -#endif /* DROID_EXTREME_LOGS */ - if (do_lock) { - if (!vi) return GF_BAD_PARAM; - - if ( rc->out_3d_type != 0 ) - return GF_NOT_SUPPORTED; - - vi->height = rc->height; - vi->width = rc->width; - vi->video_buffer = rc->texData; - vi->is_hardware_memory = 0; - vi->pitch_x = NBPP; - vi->pitch_y = NBPP * rc->tex_width; - vi->pixel_format = RAW_OUT_PIXEL_FORMAT; - } - else - { - if (rc->locked_data) - { - //glBindTexture( GL_TEXTURE_2D, rc->texID); - //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); - //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); - - //glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, rc->width, rc->height, 0, - // GL_RGBA, GL_UNSIGNED_BYTE, rc->locked_data ); - } - } -#ifdef DROID_EXTREME_LOGS - LOG( ANDROID_LOG_VERBOSE, TAG, "Android LockBackBuffer DONE"); -#endif /* DROID_EXTREME_LOGS */ - return GF_OK; -} - -static GF_Err droid_ProcessEvent(GF_VideoOutput *dr, GF_Event *evt) -{ - RAWCTX; - - if (evt) { - switch (evt->type) { - case GF_EVENT_SIZE: - LOG( ANDROID_LOG_VERBOSE, TAG, "GF_EVENT_SIZE( %d x %d)", - evt->setup.width, evt->setup.height); - //if (evt->setup.opengl_mode) return GF_OK; - return droid_Resize(dr, evt->setup.width, evt->setup.height); - case GF_EVENT_VIDEO_SETUP: - LOG( ANDROID_LOG_DEBUG, TAG, "Android OpenGL mode: %d", evt->setup.opengl_mode); - switch (evt->setup.opengl_mode) - { - case 0: - rc->out_3d_type = 0; -// initGL(rc); - droid_Resize(dr, evt->setup.width, evt->setup.height); - return GF_OK; - case 1: - rc->out_3d_type = 1; - droid_Resize(dr, evt->setup.width, evt->setup.height); - return GF_OK; - case 2: - rc->out_3d_type = 2; - droid_Resize(dr, evt->setup.width, evt->setup.height); - return GF_OK; - case GF_EVENT_SET_CURSOR: - LOG( ANDROID_LOG_VERBOSE, TAG, "GF_EVENT_SET_CURSOR"); - return GF_OK; - case GF_EVENT_SET_CAPTION: - LOG( ANDROID_LOG_VERBOSE, TAG, "GF_EVENT_SET_CAPTION"); - return GF_OK; - case GF_EVENT_SHOWHIDE: - LOG( ANDROID_LOG_VERBOSE, TAG, "GF_EVENT_SHOWHIDE"); - return GF_OK; - default: - LOG( ANDROID_LOG_DEBUG, TAG, "Process Unknown Event: %d", evt->type); - return GF_OK; - } - break; - } - } - return GF_OK; -} - -GF_VideoOutput *NewRawVideoOutput() -{ - AndroidContext *pCtx; - GF_VideoOutput *driv = (GF_VideoOutput *) gf_malloc(sizeof(GF_VideoOutput)); - LOG( ANDROID_LOG_INFO, TAG, "Android Video Initialization in progress..."); - memset(driv, 0, sizeof(GF_VideoOutput)); - GF_REGISTER_MODULE_INTERFACE(driv, GF_VIDEO_OUTPUT_INTERFACE, "Android Video Output", "gpac distribution") - - pCtx = gf_malloc(sizeof(AndroidContext)); - memset(pCtx, 0, sizeof(AndroidContext)); - - pCtx->texID = -1; - pCtx->framebuff = -1; - pCtx->depthbuff = -1; - driv->opaque = pCtx; - - driv->Flush = droid_Flush; - driv->LockBackBuffer = droid_LockBackBuffer; - driv->Setup = droid_Setup; - driv->Shutdown = droid_Shutdown; - driv->ProcessEvent = droid_ProcessEvent; - - driv->max_screen_width = 1024; - driv->max_screen_height = 1024; - - driv->hw_caps = GF_VIDEO_HW_OPENGL;// | GF_VIDEO_HW_OPENGL_OFFSCREEN_ALPHA;//GF_VIDEO_HW_DIRECT_ONLY;// - - LOG( ANDROID_LOG_INFO, TAG, "Android Video Init Done.\n"); - return (void *)driv; -} - -void DeleteVideoOutput(void *ifce) -{ - AndroidContext *rc; - GF_VideoOutput *driv = (GF_VideoOutput *) ifce; - if (!ifce) - return; - droid_Shutdown(driv); - rc = (AndroidContext *)driv->opaque; - if (rc) - gf_free(rc); - driv->opaque = NULL; - gf_free(driv); - LOG( ANDROID_LOG_DEBUG, TAG, "Android vout deinit\n"); -} - -/*interface query*/ -GF_EXPORT -const u32 *QueryInterfaces() -{ - static u32 si [] = { - GF_VIDEO_OUTPUT_INTERFACE, - 0 - }; - return si; -} -/*interface create*/ -GF_BaseInterface *LoadInterface(u32 InterfaceType) -{ - if (InterfaceType == GF_VIDEO_OUTPUT_INTERFACE) return (GF_BaseInterface *) NewRawVideoOutput(); - return NULL; -} -/*interface destroy*/ -void ShutdownInterface(GF_BaseInterface *ifce) -{ - switch (ifce->InterfaceType) { - case GF_VIDEO_OUTPUT_INTERFACE: - DeleteVideoOutput((GF_VideoOutput *)ifce); - break; - } -} +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) ENST 2009- + * Authors: Jean Le Feuvre + * All rights reserved + * + * Created by NGO Van Luyen, Ivica ARSOV / ARTEMIS / Telecom SudParis /Institut TELECOM on Oct, 2010 + * + * This file is part of GPAC / Wrapper + * + * 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. + * + */ + +/*driver interfaces*/ +#include +#include +#include + +#include + +#include +#include + +#include + +#define TAG "DROID_VIDEO" + +#define LOG __android_log_print + +#ifdef PI +#undef PI +#endif + +#define PI 3.1415926535897932f + +/* Uncomment the next line if you want to debug */ +/* #define DROID_EXTREME_LOGS */ + +typedef struct +{ + u32 width, height; + void * locked_data; + u8 out_3d_type; + + u32 tex_width, tex_height; + + GLuint texID; + GLuint framebuff; + GLuint depthbuff; + + GLubyte* texData; + + u8 draw_texture; + u8 non_power_two; +} AndroidContext; + + +#define RAW_OUT_PIXEL_FORMAT GF_PIXEL_RGBA +#define NBPP 4 + +#define RAWCTX AndroidContext *rc = (AndroidContext *)dr->opaque + +//#define GLES_FRAMEBUFFER_TEST + +#ifdef GLES_FRAMEBUFFER_TEST +#warning "Using FrameBuffer" +#endif + +void initGL(AndroidContext *rc) +{ + char* ext; + + LOG( ANDROID_LOG_DEBUG, TAG, "Android InitGL"); + + ext = (char*)glGetString(GL_VENDOR); + LOG( ANDROID_LOG_INFO, TAG, "OpenGL ES Vendor: %s", ext); + + ext = (char*)glGetString(GL_RENDERER); + LOG( ANDROID_LOG_INFO, TAG, "OpenGL ES Renderer: %s", ext); + + ext = (char*)glGetString(GL_VERSION); + LOG( ANDROID_LOG_INFO, TAG, "OpenGL ES Version: %s", ext); + + ext = (char*)glGetString(GL_EXTENSIONS); + LOG( ANDROID_LOG_INFO, TAG, "OpenGL ES Extensions: %s", ext); + + if ( strstr(ext, "GL_OES_draw_texture") ) + { + rc->draw_texture = 1; + LOG( ANDROID_LOG_INFO, TAG, "Using GL_OES_draw_texture"); + } + if ( strstr(ext, "GL_ARB_texture_non_power_of_two") ) + { + rc->non_power_two = 0; + LOG( ANDROID_LOG_INFO, TAG, "Using GL_ARB_texture_non_power_of_two"); + } + + /* Enable smooth shading */ + glShadeModel(GL_SMOOTH); + + /* Set the background black */ + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + + /* Depth buffer setup */ + glClearDepthf(1.0f); + + /* Enables Depth Testing */ + glEnable(GL_DEPTH_TEST); + + /* The Type Of Depth Test To Do */ + glDepthFunc(GL_LEQUAL); + + /* Really Nice Perspective Calculations */ + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + + glDisable(GL_CULL_FACE | GL_NORMALIZE | GL_LIGHTING | GL_BLEND | GL_FOG | GL_COLOR_MATERIAL | GL_TEXTURE_2D); +} + +void gluPerspective(GLfloat fovy, GLfloat aspect, + GLfloat zNear, GLfloat zFar) +{ + GLfloat xmin, xmax, ymin, ymax; + + ymax = zNear * (GLfloat)tan(fovy * PI / 360); + ymin = -ymax; + xmin = ymin * aspect; + xmax = ymax * aspect; + + glFrustumx((GLfixed)(xmin * 65536), (GLfixed)(xmax * 65536), + (GLfixed)(ymin * 65536), (GLfixed)(ymax * 65536), + (GLfixed)(zNear * 65536), (GLfixed)(zFar * 65536)); +} + +void resizeWindow(AndroidContext *rc) +{ + LOG( ANDROID_LOG_VERBOSE, TAG, "resizeWindow : start"); + /* Height / width ration */ + GLfloat ratio; + + /* Protect against a divide by zero */ + if (rc->height==0) + { + rc->height=1; + } + + ratio=(GLfloat)rc->width/(GLfloat)rc->height; + + /* Setup our viewport. */ + glViewport(0, 0, (GLsizei)rc->width, (GLsizei)rc->height); + + /* change to the projection matrix and set our viewing volume. */ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + /* Set our perspective */ + glOrthox(0, INT2FIX(rc->width), 0, INT2FIX(rc->height), INT2FIX(-1), INT2FIX(1)); + + /* Make sure we're chaning the model view and not the projection */ + glMatrixMode(GL_MODELVIEW); + + /* Reset The View */ + glLoadIdentity(); + LOG( ANDROID_LOG_VERBOSE, TAG, "resizeWindow : end"); +} + +void drawGLScene(AndroidContext *rc) +{ +#ifdef DROID_EXTREME_LOGS + LOG( ANDROID_LOG_VERBOSE, TAG, "drawGLScene : start"); +#endif /* DROID_EXTREME_LOGS */ + GLfloat vertices[4][3]; + GLfloat texcoord[4][2]; +// int i, j; + + float rgba[4]; + +#ifdef GLES_FRAMEBUFFER_TEST + glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); +#endif + + // Reset states + rgba[0] = rgba[1] = rgba[2] = 0.f; + rgba[0] = 1.f; + glColor4f(1.f, 1.f, 1.f, 1.f); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, rgba); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, rgba); + glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, rgba); + glDisable(GL_CULL_FACE | GL_NORMALIZE | GL_LIGHTING | GL_BLEND | GL_FOG | GL_COLOR_MATERIAL | GL_TEXTURE_2D); + + /* Clear The Screen And The Depth Buffer */ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //glEnable(GL_BLEND); + //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glEnable(GL_TEXTURE_2D); + glBindTexture( GL_TEXTURE_2D, rc->texID); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + +// for ( i = 0; i < rc->height/2; i++ ) +// for ( j = 0; j < rc->width; j++ ) +// rc->texData[ i*rc->width*NBPP + j*NBPP + 3] = 200; + +// memset(rc->texData, 255, 4 * rc->width * rc->height ); +#ifndef GLES_FRAMEBUFFER_TEST + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, rc->tex_width, rc->tex_height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, rc->texData ); +#endif + + if ( rc->draw_texture ) + { + int cropRect[4] = {0,rc->height,rc->width,-rc->height}; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); + + glDrawTexsOES(0, 0, 0, rc->width, rc->height); + } + else + { + /* Enable VERTEX array */ + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + /* Setup pointer to VERTEX array */ + glVertexPointer(3, GL_FLOAT, 0, vertices); + glTexCoordPointer(2, GL_FLOAT, 0, texcoord); + + /* Move Left 1.5 Units And Into The Screen 6.0 */ + glLoadIdentity(); + //glTranslatef(0.0f, 0.0f, -3.3f); + //glTranslatef(0.0f, 0.0f, -2.3f); + + /* Top Right Of The Quad */ + vertices[0][0]=rc->tex_width; vertices[0][1]=rc->tex_height; vertices[0][2]=0.0f; + texcoord[0][0]=1.f; texcoord[0][1]=0.f; + /* Top Left Of The Quad */ + vertices[1][0]=0.f; vertices[1][1]=rc->tex_height; vertices[1][2]=0.0f; + texcoord[1][0]=0.f; texcoord[1][1]=0.f; + /* Bottom Left Of The Quad */ + vertices[2][0]=rc->tex_width; vertices[2][1]=0.f; vertices[2][2]=0.0f; + texcoord[2][0]=1.f; texcoord[2][1]=1.f; + /* Bottom Right Of The Quad */ + vertices[3][0]=0.f; vertices[3][1]=0.f; vertices[3][2]=0.0f; + texcoord[3][0]=0.f; texcoord[3][1]=1.f; + + /* Drawing using triangle strips, draw triangles using 4 vertices */ + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + /* Disable vertex array */ + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + + glDisable(GL_TEXTURE_2D); + + /* Flush all drawings */ + glFinish(); +#ifdef GLES_FRAMEBUFFER_TEST + glBindFramebufferOES(GL_FRAMEBUFFER_OES, rc->framebuff); +#endif +#ifdef DROID_EXTREME_LOGS + LOG( ANDROID_LOG_VERBOSE, TAG, "drawGLScene : end"); +#endif /* DROID_EXTREME_LOGS */ +} + +int releaseTexture(AndroidContext *rc) +{ + if (!rc) + return 0; + LOG( ANDROID_LOG_DEBUG, TAG, "Android Delete Texture"); + + if ( rc->texID >= 0 ) + { + glDeleteTextures(1, &(rc->texID)); + rc->texID = -1; + } + if (rc->texData) + { + gf_free(rc->texData); + rc->texData = NULL; + } + LOG( ANDROID_LOG_VERBOSE, TAG, "Android Delete Texture DONE"); + return 0; +} + +int createTexture(AndroidContext *rc) +{ + if (!rc) + return 0; + if ( rc->texID >= 0 ) + releaseTexture(rc); + + LOG( ANDROID_LOG_INFO, TAG, "Android Create Texture Size: WxH: %dx%d", + rc->tex_width, rc->tex_height); + + glGenTextures( 1, &(rc->texID) ); + + rc->texData = (GLubyte*)gf_malloc( 4 * rc->tex_width * rc->tex_height ); + memset(rc->texData, 255, 4 * rc->tex_width * rc->tex_height ); + //memset(data, 0, 4 * width * height/2 ); + + glBindTexture( GL_TEXTURE_2D, rc->texID); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, rc->tex_width, rc->tex_height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL/*rc->texData*/ ); + + glBindTexture( GL_TEXTURE_2D, 0); + LOG( ANDROID_LOG_VERBOSE, TAG, "Android Create Texture DONE"); + return 0; +} + +#ifdef GLES_FRAMEBUFFER_TEST + +int releaseFrameBuffer(AndroidContext *rc) +{ + LOG( ANDROID_LOG_DEBUG, TAG, "Android Delete FrameBuffer"); + + glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); + + if ( rc->framebuff >= 0 ) + { + glDeleteFramebuffersOES(1, &(rc->framebuff)); + rc->framebuff = -1; + } + if ( rc->depthbuff >= 0 ) + { + glDeleteRenderbuffersOES(1, &(rc->depthbuff)); + rc->depthbuff = -1; + } +} + +int createFrameBuffer(AndroidContext *rc) +{ + int backingWidth; + int backingHeight; + int res; + + if ( rc->framebuff >= 0 ) + releaseFrameBuffer(rc); + + LOG( ANDROID_LOG_DEBUG, TAG, "Android Create FrameBuffer")); + + glGenFramebuffersOES(1, &(rc->framebuff)); + glBindFramebufferOES(GL_FRAMEBUFFER_OES, rc->framebuff); + +// glGenRenderbuffersOES(1, &(rc->depthbuff)); +// glBindRenderbufferOES(GL_RENDERBUFFER_OES, rc->depthbuff); + +// glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); +// glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); + +// LOG( ANDROID_LOG_ERROR, TAG, "Android Depth Buffer Size: %dx%d\n", backingWidth, backingHeight)); + +// glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, rc->width, rc->height); + +// glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, +// GL_RENDERBUFFER_OES, rc->depthbuff); + + glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, + GL_TEXTURE_2D, rc->texID, 0); + + if ( (res=(int)glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)) != GL_FRAMEBUFFER_COMPLETE_OES ) + { + LOG( ANDROID_LOG_ERROR, TAG, "Android failed to make complete framebuffer object:"); + switch (res) + { + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES: + LOG( ANDROID_LOG_ERROR, TAG, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES: + LOG( ANDROID_LOG_ERROR, TAG, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES: + LOG( ANDROID_LOG_ERROR, TAG, "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES"); + break; + case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES: + LOG( ANDROID_LOG_ERROR, TAG, "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES"); + break; + case GL_FRAMEBUFFER_UNSUPPORTED_OES: + LOG( ANDROID_LOG_ERROR, TAG, "GL_FRAMEBUFFER_UNSUPPORTED_OES"); + break; + default : + LOG( ANDROID_LOG_ERROR, TAG, "Unknown error: %d", res); + break; + } + + return 1; + } + + //glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); + + return 0; +} + +#endif + +u32 find_pow_2(u32 num) +{ + u32 res = 1; + while (res < num) + res *= 2; + return res; +} + +static GF_Err droid_Resize(GF_VideoOutput *dr, u32 w, u32 h) +{ + RAWCTX; + LOG( ANDROID_LOG_DEBUG, TAG, "Android Resize: %dx%d", w, h); + + rc->width = w; + rc->height = h; + + if ( rc->non_power_two ) + { + rc->tex_width = rc->width; + rc->tex_height = rc->height; + } + else + { + rc->tex_width = find_pow_2(rc->width); + rc->tex_height = find_pow_2(rc->height); + } + + resizeWindow(rc); + + if ( rc->out_3d_type == 0 ) + { + createTexture(rc); +#ifdef GLES_FRAMEBUFFER_TEST + createFrameBuffer(rc); +#endif + } + LOG( ANDROID_LOG_VERBOSE, TAG, "Android Resize DONE", w, h); + return GF_OK; +} + +GF_Err droid_Setup(GF_VideoOutput *dr, void *os_handle, void *os_display, u32 init_flags) +{ + RAWCTX; + void * pixels; + int ret; + + LOG( ANDROID_LOG_DEBUG, TAG, "Android Setup: %d", init_flags); + +#ifndef GLES_FRAMEBUFFER_TEST + if ( rc->out_3d_type == 0 ) +#endif + initGL(rc); + LOG( ANDROID_LOG_VERBOSE, TAG, "Android Setup DONE"); + return GF_OK; +} + + +static void droid_Shutdown(GF_VideoOutput *dr) +{ + RAWCTX; + LOG( ANDROID_LOG_DEBUG, TAG, "Android Shutdown\n"); + + releaseTexture(rc); +#ifdef GLES_FRAMEBUFFER_TEST + releaseFrameBuffer(rc); +#endif + LOG( ANDROID_LOG_VERBOSE, TAG, "Android Shutdown DONE"); +} + + +static GF_Err droid_Flush(GF_VideoOutput *dr, GF_Window *dest) +{ + RAWCTX; +#ifdef DROID_EXTREME_LOGS + LOG( ANDROID_LOG_VERBOSE, TAG, "Android Flush\n"); +#endif /* DROID_EXTREME_LOGS */ + +#ifndef GLES_FRAMEBUFFER_TEST + if ( rc->out_3d_type == 0 ) +#endif + drawGLScene(rc); +#ifdef DROID_EXTREME_LOGS + LOG( ANDROID_LOG_VERBOSE, TAG, "Android Flush DONE"); +#endif /* DROID_EXTREME_LOGS */ + return GF_OK; +} + +static GF_Err droid_LockBackBuffer(GF_VideoOutput *dr, GF_VideoSurface *vi, Bool do_lock) +{ + RAWCTX; + int ret; + void * pixels; + int i,j,t; +#ifdef DROID_EXTREME_LOGS + LOG( ANDROID_LOG_VERBOSE, TAG, "Android LockBackBuffer: %d", do_lock); +#endif /* DROID_EXTREME_LOGS */ + if (do_lock) { + if (!vi) return GF_BAD_PARAM; + + if ( rc->out_3d_type != 0 ) + return GF_NOT_SUPPORTED; + + vi->height = rc->height; + vi->width = rc->width; + vi->video_buffer = rc->texData; + vi->is_hardware_memory = 0; + vi->pitch_x = NBPP; + vi->pitch_y = NBPP * rc->tex_width; + vi->pixel_format = RAW_OUT_PIXEL_FORMAT; + } + else + { + if (rc->locked_data) + { + //glBindTexture( GL_TEXTURE_2D, rc->texID); + //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + + //glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, rc->width, rc->height, 0, + // GL_RGBA, GL_UNSIGNED_BYTE, rc->locked_data ); + } + } +#ifdef DROID_EXTREME_LOGS + LOG( ANDROID_LOG_VERBOSE, TAG, "Android LockBackBuffer DONE"); +#endif /* DROID_EXTREME_LOGS */ + return GF_OK; +} + +static GF_Err droid_ProcessEvent(GF_VideoOutput *dr, GF_Event *evt) +{ + RAWCTX; + + if (evt) { + switch (evt->type) { + case GF_EVENT_SIZE: + LOG( ANDROID_LOG_VERBOSE, TAG, "GF_EVENT_SIZE( %d x %d)", + evt->setup.width, evt->setup.height); + //if (evt->setup.opengl_mode) return GF_OK; + return droid_Resize(dr, evt->setup.width, evt->setup.height); + case GF_EVENT_VIDEO_SETUP: + LOG( ANDROID_LOG_DEBUG, TAG, "Android OpenGL mode: %d", evt->setup.opengl_mode); + switch (evt->setup.opengl_mode) + { + case 0: + rc->out_3d_type = 0; +// initGL(rc); + droid_Resize(dr, evt->setup.width, evt->setup.height); + return GF_OK; + case 1: + rc->out_3d_type = 1; + droid_Resize(dr, evt->setup.width, evt->setup.height); + return GF_OK; + case 2: + rc->out_3d_type = 2; + droid_Resize(dr, evt->setup.width, evt->setup.height); + return GF_OK; + case GF_EVENT_SET_CURSOR: + LOG( ANDROID_LOG_VERBOSE, TAG, "GF_EVENT_SET_CURSOR"); + return GF_OK; + case GF_EVENT_SET_CAPTION: + LOG( ANDROID_LOG_VERBOSE, TAG, "GF_EVENT_SET_CAPTION"); + return GF_OK; + case GF_EVENT_SHOWHIDE: + LOG( ANDROID_LOG_VERBOSE, TAG, "GF_EVENT_SHOWHIDE"); + return GF_OK; + default: + LOG( ANDROID_LOG_DEBUG, TAG, "Process Unknown Event: %d", evt->type); + return GF_OK; + } + break; + } + } + return GF_OK; +} + +GF_VideoOutput *NewRawVideoOutput() +{ + AndroidContext *pCtx; + GF_VideoOutput *driv = (GF_VideoOutput *) gf_malloc(sizeof(GF_VideoOutput)); + LOG( ANDROID_LOG_INFO, TAG, "Android Video Initialization in progress..."); + memset(driv, 0, sizeof(GF_VideoOutput)); + GF_REGISTER_MODULE_INTERFACE(driv, GF_VIDEO_OUTPUT_INTERFACE, "Android Video Output", "gpac distribution") + + pCtx = gf_malloc(sizeof(AndroidContext)); + memset(pCtx, 0, sizeof(AndroidContext)); + + pCtx->texID = -1; + pCtx->framebuff = -1; + pCtx->depthbuff = -1; + driv->opaque = pCtx; + + driv->Flush = droid_Flush; + driv->LockBackBuffer = droid_LockBackBuffer; + driv->Setup = droid_Setup; + driv->Shutdown = droid_Shutdown; + driv->ProcessEvent = droid_ProcessEvent; + + driv->max_screen_width = 1024; + driv->max_screen_height = 1024; + + driv->hw_caps = GF_VIDEO_HW_OPENGL;// | GF_VIDEO_HW_OPENGL_OFFSCREEN_ALPHA;//GF_VIDEO_HW_DIRECT_ONLY;// + + LOG( ANDROID_LOG_INFO, TAG, "Android Video Init Done.\n"); + return (void *)driv; +} + +void DeleteVideoOutput(void *ifce) +{ + AndroidContext *rc; + GF_VideoOutput *driv = (GF_VideoOutput *) ifce; + if (!ifce) + return; + droid_Shutdown(driv); + rc = (AndroidContext *)driv->opaque; + if (rc) + gf_free(rc); + driv->opaque = NULL; + gf_free(driv); + LOG( ANDROID_LOG_DEBUG, TAG, "Android vout deinit\n"); +} + +/*interface query*/ +GF_EXPORT +const u32 *QueryInterfaces() +{ + static u32 si [] = { + GF_VIDEO_OUTPUT_INTERFACE, + 0 + }; + return si; +} +/*interface create*/ +GF_BaseInterface *LoadInterface(u32 InterfaceType) +{ + if (InterfaceType == GF_VIDEO_OUTPUT_INTERFACE) return (GF_BaseInterface *) NewRawVideoOutput(); + return NULL; +} +/*interface destroy*/ +void ShutdownInterface(GF_BaseInterface *ifce) +{ + switch (ifce->InterfaceType) { + case GF_VIDEO_OUTPUT_INTERFACE: + DeleteVideoOutput((GF_VideoOutput *)ifce); + break; + } +} diff --git a/modules/dummy_in/Makefile b/modules/dummy_in/Makefile index ef3c462..2576530 100644 --- a/modules/dummy_in/Makefile +++ b/modules/dummy_in/Makefile @@ -31,7 +31,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_dummy_in-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_dummy_in-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static endif diff --git a/modules/dx_hw/copy_pixels.c b/modules/dx_hw/copy_pixels.c index 9d0edb4..9e39708 100644 --- a/modules/dx_hw/copy_pixels.c +++ b/modules/dx_hw/copy_pixels.c @@ -81,7 +81,7 @@ static Bool is_planar_yuv(u32 pf) } -static void VR_write_yv12_to_yuv(GF_VideoSurface *vs, unsigned char *src, u32 src_stride, u32 src_pf, +static void write_yv12_to_yuv(GF_VideoSurface *vs, unsigned char *src, u32 src_stride, u32 src_pf, u32 src_width, u32 src_height, const GF_Window *src_wnd) { unsigned char *pY, *pU, *pV; @@ -211,6 +211,124 @@ static void VR_write_yv12_to_yuv(GF_VideoSurface *vs, unsigned char *src, u32 s } +static void write_yvyu_to_yuv(GF_VideoSurface *vs, unsigned char *src, u32 src_stride, u32 src_pf, + u32 src_width, u32 src_height, const GF_Window *src_wnd) +{ + u32 i, j, base_pf; + unsigned char *pY, *pU, *pV; + + switch (get_yuv_base(src_pf) ) { + case GF_PIXEL_UYVY: + pU = src + src_stride * src_wnd->y + src_wnd->x; + pY = src + src_stride * src_wnd->y + src_wnd->x + 1; + pV = src + src_stride * src_wnd->y + src_wnd->x + 3; + break; + case GF_PIXEL_YUY2: + pY = src + src_stride * src_wnd->y + src_wnd->x; + pU = src + src_stride * src_wnd->y + src_wnd->x + 1; + pV = src + src_stride * src_wnd->y + src_wnd->x + 3; + break; + case GF_PIXEL_YVYU: + pY = src + src_stride * src_wnd->y + src_wnd->x; + pV = src + src_stride * src_wnd->y + src_wnd->x + 1; + pU = src + src_stride * src_wnd->y + src_wnd->x + 3; + break; + default: + return; + } + + if (is_planar_yuv(vs->pixel_format)) { + u32 i, j; + unsigned char *dst_y, *dst_u, *dst_v; + + dst_y = vs->video_buffer; + if (vs->pixel_format == GF_PIXEL_YV12) { + dst_v = vs->video_buffer + vs->pitch_y * vs->height; + dst_u = vs->video_buffer + 5*vs->pitch_y * vs->height/4; + } else { + dst_u = vs->video_buffer + vs->pitch_y * vs->height; + dst_v = vs->video_buffer + 5*vs->pitch_y * vs->height/4; + } + for (i=0; ih; i++) { + for (j=0; jw; j+=2) { + *dst_y = * pY; + *(dst_y+1) = * (pY+2); + dst_y += 2; + pY += 4; + if (i%2) continue; + + *dst_u = (*pU + *(pU + src_stride)) / 2; + *dst_v = (*pV + *(pV + src_stride)) / 2; + dst_u++; + dst_v++; + pU += 4; + pV += 4; + } + if (i%2) { + pU += src_stride; + pV += src_stride; + } + } + return; + } + + if (get_yuv_base(src_pf) == get_yuv_base(vs->pixel_format)) { + u32 i; + for (i=0; ih; i++) { + char *dst = vs->video_buffer + i*vs->pitch_y; + pY = src + src_stride * (i+src_wnd->y) + src_wnd->x; + memcpy(dst, pY, sizeof(char)*2*src_wnd->w); + } + return; + } + + base_pf = get_yuv_base(vs->pixel_format); + for (i=0; ih; i++) { + char *dst = vs->video_buffer + i*vs->pitch_y; + char *y = pY + src_stride * i; + char *u = pU + src_stride * i; + char *v = pV + src_stride * i; + switch (base_pf) { + case GF_PIXEL_UYVY: + for (j=0; jw; j+=2) { + dst[0] = *u; + dst[1] = *y; + dst[2] = *v; + dst[3] = *(y+2); + dst += 4; + y+=4; + u+=4; + v+=4; + } + break; + case GF_PIXEL_YVYU: + for (j=0; jw; j+=2) { + dst[0] = *y; + dst[1] = *v; + dst[2] = *(y+2); + dst[3] = *u; + dst += 4; + y+=4; + u+=4; + v+=4; + } + break; + case GF_PIXEL_YUY2: + for (j=0; jw; j+=2) { + dst[0] = *y; + dst[1] = *u; + dst[2] = *(y+2); + dst[3] = *v; + dst += 4; + y+=4; + u+=4; + v+=4; + } + break; + } + } +} + u32 get_bpp(u32 pf) { switch (pf) { @@ -433,31 +551,37 @@ void dx_copy_pixels(GF_VideoSurface *dst_s, const GF_VideoSurface *src_s, const if (get_yuv_base(src_s->pixel_format)==GF_PIXEL_YV12) { if (format_is_yuv(dst_s->pixel_format)) { /*generic YV planar to YUV (planar or not) */ - VR_write_yv12_to_yuv(dst_s, src_s->video_buffer, src_s->pitch_y, src_s->pixel_format, src_s->width, src_s->height, src_wnd); - } else { - gf_stretch_bits(dst_s, (GF_VideoSurface*) src_s, NULL, (GF_Window *)src_wnd, 0xFF, 0, NULL, NULL); + write_yv12_to_yuv(dst_s, src_s->video_buffer, src_s->pitch_y, src_s->pixel_format, src_s->width, src_s->height, src_wnd); + return; + } + } else if (format_is_yuv(src_s->pixel_format)) { + if (format_is_yuv(dst_s->pixel_format)) { + write_yvyu_to_yuv(dst_s, src_s->video_buffer, src_s->pitch_y, src_s->pixel_format, src_s->width, src_s->height, src_wnd); + return; } } else { switch (dst_s->pixel_format) { case GF_PIXEL_RGB_555: rgb_to_555(dst_s, src_s->video_buffer, src_s->pitch_y, src_s->width, src_s->height, src_s->pixel_format, src_wnd); - break; + return; case GF_PIXEL_RGB_565: rgb_to_565(dst_s, src_s->video_buffer, src_s->pitch_y, src_s->width, src_s->height, src_s->pixel_format, src_wnd); - break; + return; case GF_PIXEL_RGB_24: case GF_PIXEL_RGBS: case GF_PIXEL_BGR_24: rgb_to_24(dst_s, src_s->video_buffer, src_s->pitch_y, src_s->width, src_s->height, src_s->pixel_format, src_wnd); - break; + return; case GF_PIXEL_RGB_32: case GF_PIXEL_RGBD: case GF_PIXEL_RGBDS: case GF_PIXEL_BGR_32: rgb_to_32(dst_s, src_s->video_buffer, src_s->pitch_y, src_s->width, src_s->height, src_s->pixel_format, src_wnd); - break; + return; } } + + gf_stretch_bits(dst_s, (GF_VideoSurface*) src_s, NULL, (GF_Window *)src_wnd, 0xFF, 0, NULL, NULL); } diff --git a/modules/dx_hw/dx_2d.c b/modules/dx_hw/dx_2d.c index ab3e25c..bf6ebd8 100644 --- a/modules/dx_hw/dx_2d.c +++ b/modules/dx_hw/dx_2d.c @@ -415,7 +415,7 @@ static GF_Err DD_BlitSurface(DDContext *dd, DDSurface *src, GF_Window *src_wnd, src_h = src_wnd ? src_wnd->h : src->height; dst_w = dst_wnd ? dst_wnd->w : dd->width; dst_h = dst_wnd ? dst_wnd->h : dd->height; - + if (src_wnd != NULL) MAKERECT(r_src, src_wnd); if (dst_wnd != NULL) MAKERECT(r_dst, dst_wnd); @@ -439,11 +439,11 @@ static GF_Err DD_BlitSurface(DDContext *dd, DDSurface *src, GF_Window *src_wnd, if (key) flags |= DDBLT_KEYSRC; hr = IDirectDrawSurface_Blt(dd->pBack, dst_wnd ? &r_dst : NULL, src->pSurface, src_wnd ? &r_src : NULL, flags, NULL); } - GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DX Out] Hardware blit result: %d (%08x)\n", hr, hr)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DX Out] Hardware blit src w=%d,h=%d to dst w=%d,h=%d - result: %08x\n", src_w, src_h, dst_w, dst_h, hr)); return FAILED(hr) ? GF_IO_ERR : GF_OK; } -static DDSurface *DD_GetSurface(GF_VideoOutput *dr, u32 width, u32 height, u32 pixel_format) +static DDSurface *DD_GetSurface(GF_VideoOutput *dr, u32 width, u32 height, u32 pixel_format, Bool check_caps) { #ifdef USE_DX_3 DDSURFACEDESC ddsd; @@ -477,19 +477,42 @@ static DDSurface *DD_GetSurface(GF_VideoOutput *dr, u32 width, u32 height, u32 p ddsd.dwSize = sizeof(ddsd); ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; - ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY; + + ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY; + if (dr->hw_caps & GF_VIDEO_HW_HAS_YUV_OVERLAY) + ddsd.ddsCaps.dwCaps |= DDSCAPS_OVERLAY; + ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC; ddsd.dwWidth = width; ddsd.dwHeight = height; ddsd.ddpfPixelFormat.dwFourCC = get_win_4CC(dr->yuv_pixel_format); #ifdef USE_DX_3 - if( FAILED( hr = IDirectDraw_CreateSurface(dd->pDD, &ddsd, &yuvp->pSurface, NULL ) ) ) - return NULL; + if( FAILED( hr = IDirectDraw_CreateSurface(dd->pDD, &ddsd, &yuvp->pSurface, NULL ) ) ) { +#else + if( FAILED( hr = IDirectDraw7_CreateSurface(dd->pDD, &ddsd, &yuvp->pSurface, NULL ) ) ) { +#endif + if (!check_caps) return NULL; + + /*try withou overlay cap*/ + if (dr->hw_caps & GF_VIDEO_HW_HAS_YUV_OVERLAY) { + dr->hw_caps &= ~GF_VIDEO_HW_HAS_YUV_OVERLAY; + ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY; + +#ifdef USE_DX_3 + if( FAILED( hr = IDirectDraw_CreateSurface(dd->pDD, &ddsd, &yuvp->pSurface, NULL ) ) ) { #else - if( FAILED( hr = IDirectDraw7_CreateSurface(dd->pDD, &ddsd, &yuvp->pSurface, NULL ) ) ) - return NULL; + if( FAILED( hr = IDirectDraw7_CreateSurface(dd->pDD, &ddsd, &yuvp->pSurface, NULL ) ) ) { #endif + return NULL; + } + } + /*YUV not supported*/ + else { + return NULL; + } + + } yuvp->format = dr->yuv_pixel_format; yuvp->width = width; yuvp->height = height; @@ -550,7 +573,7 @@ static GF_Err DD_Blit(GF_VideoOutput *dr, GF_VideoSurface *video_src, GF_Window /*get RGB or YUV pool surface*/ //if (video_src->pixel_format==GF_PIXEL_YUVD) return GF_NOT_SUPPORTED; if (video_src->pixel_format==GF_PIXEL_YUVD) video_src->pixel_format=GF_PIXEL_YV12; - pool = DD_GetSurface(dr, w, h, video_src->pixel_format); + pool = DD_GetSurface(dr, w, h, video_src->pixel_format, 0); if (!pool) return GF_IO_ERR; @@ -695,6 +718,10 @@ void DD_InitYUV(GF_VideoOutput *dr) if (formats[num_yuv]) num_yuv++; } gf_free(codes); + + + dr->hw_caps |= GF_VIDEO_HW_HAS_YUV | GF_VIDEO_HW_HAS_YUV_OVERLAY; + /*too bad*/ if (!num_yuv) { dr->hw_caps &= ~(GF_VIDEO_HW_HAS_YUV | GF_VIDEO_HW_HAS_YUV_OVERLAY); @@ -714,7 +741,7 @@ void DD_InitYUV(GF_VideoOutput *dr) } dr->yuv_pixel_format = formats[i]; - if (DD_GetSurface(dr, w, h, dr->yuv_pixel_format) == NULL) + if (DD_GetSurface(dr, w, h, dr->yuv_pixel_format, 1) == NULL) goto rem_fmt; now = gf_sys_clock(); @@ -779,7 +806,6 @@ rem_fmt: dr->yuv_pixel_format = GF_PIXEL_YV12; GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[DX Out] Picked YUV format %s - drawn in %d ms\n", gf_4cc_to_str(dr->yuv_pixel_format), min_planar)); - dr->hw_caps |= GF_VIDEO_HW_HAS_YUV_OVERLAY; /*enable YUV->RGB on the backbuffer ?*/ opt = gf_modules_get_option((GF_BaseInterface *)dr, "Video", "EnableOffscreenYUV"); @@ -788,7 +814,7 @@ rem_fmt: opt = "yes"; gf_modules_set_option((GF_BaseInterface *)dr, "Video", "EnableOffscreenYUV", "yes"); } - if (!strcmp(opt, "yes")) dr->hw_caps |= GF_VIDEO_HW_HAS_YUV; + if (opt && strcmp(opt, "yes")) dr->hw_caps &= ~GF_VIDEO_HW_HAS_YUV; /*get YUV overlay key*/ diff --git a/modules/dx_hw/dx_hw.h b/modules/dx_hw/dx_hw.h index 2da1a1c..0a89cda 100644 --- a/modules/dx_hw/dx_hw.h +++ b/modules/dx_hw/dx_hw.h @@ -87,6 +87,10 @@ typedef struct # endif #endif +#ifndef WM_UNICHAR +#define WM_UNICHAR 0x0109 +#endif //WM_UNICHAR + typedef struct { HWND os_hwnd, fs_hwnd, cur_hwnd, parent_wnd; diff --git a/modules/dx_hw/dx_window.c b/modules/dx_hw/dx_window.c index f7da3a2..20cc9a7 100644 --- a/modules/dx_hw/dx_window.c +++ b/modules/dx_hw/dx_window.c @@ -419,6 +419,30 @@ LRESULT APIENTRY DD_WindowProc(HWND hWnd, UINT msg, UINT wParam, LONG lParam) if (ctx->cur_hwnd==hWnd) DD_SetCursor(vout, ctx->cursor_type); break; + case WM_DROPFILES: + { + char szFile[GF_MAX_PATH]; + GF_Event evt; + u32 i; + + HDROP hDrop = (HDROP) wParam; + evt.type = GF_EVENT_OPENFILE; + evt.open_file.nb_files = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0); + evt.open_file.files = gf_malloc(sizeof(char *)*evt.open_file.nb_files); + for (i=0; ion_event(vout->evt_cbk_hdl, &evt); + for (i=0; icur_hwnd!=hWnd) break; @@ -587,8 +611,11 @@ LRESULT APIENTRY DD_WindowProc(HWND hWnd, UINT msg, UINT wParam, LONG lParam) ret = vout->on_event(vout->evt_cbk_hdl, &evt); break; + case WM_UNICHAR: case WM_CHAR: - if (wParam>=32) { + /*no reason to filter out things*/ +// if (wParam>=32) + { evt.type = GF_EVENT_TEXTINPUT; evt.character.unicode_char = wParam; ret = vout->on_event(vout->evt_cbk_hdl, &evt); @@ -726,6 +753,8 @@ Bool DD_InitWindows(GF_VideoOutput *vout, DDContext *ctx) if (ctx->os_hwnd == NULL) { return 0; } + DragAcceptFiles(ctx->os_hwnd, TRUE); + if (flags & GF_TERM_INIT_HIDE) { ShowWindow(ctx->os_hwnd, SW_HIDE); } else { diff --git a/modules/epoc_hw/epoc_codec.cpp b/modules/epoc_hw/epoc_codec.cpp index 3a499a0..ca4b6ef 100644 --- a/modules/epoc_hw/epoc_codec.cpp +++ b/modules/epoc_hw/epoc_codec.cpp @@ -332,7 +332,7 @@ static const char *EDEC_GetCodecName(GF_BaseDecoder *ifcg) return ctx->codec_name; } -static Bool EDEC_CanHandleStream(GF_BaseDecoder *ifcg, u32 StreamType, GF_ESD *esd, u8 PL) +static u32 EDEC_CanHandleStream(GF_BaseDecoder *ifcg, u32 StreamType, GF_ESD *esd, u8 PL) { char *dsi; GF_M4ADecSpecInfo a_cfg; @@ -341,7 +341,7 @@ static Bool EDEC_CanHandleStream(GF_BaseDecoder *ifcg, u32 StreamType, GF_ESD *e /*audio decs*/ if (StreamType == GF_STREAM_AUDIO) { /*media type query*/ - if (!esd) return 1; + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; dsi = esd->decoderConfig->decoderSpecificInfo ? esd->decoderConfig->decoderSpecificInfo->data : NULL; switch (esd->decoderConfig->objectTypeIndication) { /*MPEG2 aac*/ @@ -350,13 +350,13 @@ static Bool EDEC_CanHandleStream(GF_BaseDecoder *ifcg, u32 StreamType, GF_ESD *e case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP: /*MPEG4 aac*/ case GPAC_OTI_AUDIO_AAC_MPEG4: - if (!dsi) return 0; - if (gf_m4a_get_config(dsi, esd->decoderConfig->decoderSpecificInfo->dataLength, &a_cfg) != GF_OK) return 0; + if (!dsi) return GF_CODEC_NOT_SUPPORTED; + if (gf_m4a_get_config(dsi, esd->decoderConfig->decoderSpecificInfo->dataLength, &a_cfg) != GF_OK) return GF_CODEC_MAYBE_SUPPORTED; switch (a_cfg.base_object_type) { /*only LTP and LC supported*/ case GF_M4A_AAC_LC: case GF_M4A_AAC_LTP: - if ((ctx->caps & GF_EPOC_HAS_AAC) || (ctx->caps & GF_EPOC_HAS_HEAAC) ) return 1; + if ((ctx->caps & GF_EPOC_HAS_AAC) || (ctx->caps & GF_EPOC_HAS_HEAAC) ) return GF_CODEC_SUPPORTED; default: break; } @@ -369,20 +369,20 @@ static Bool EDEC_CanHandleStream(GF_BaseDecoder *ifcg, u32 StreamType, GF_ESD *e break; /*non-mpeg4 codecs*/ case GPAC_OTI_MEDIA_GENERIC: - if (!dsi) return 0; - if (esd->decoderConfig->decoderSpecificInfo->data < 4) return 0; + if (!dsi) return GF_CODEC_NOT_SUPPORTED; + if (esd->decoderConfig->decoderSpecificInfo->data < 4) return GF_CODEC_NOT_SUPPORTED; if (!strnicmp(dsi, "samr", 4) || !strnicmp(dsi, "amr ", 4)) { - if (ctx->caps & GF_EPOC_HAS_AMR) return 1; + if (ctx->caps & GF_EPOC_HAS_AMR) return GF_CODEC_SUPPORTED; } if (!strnicmp(dsi, "sawb", 4)) { - if (ctx->caps & GF_EPOC_HAS_AMR_WB) return 1; + if (ctx->caps & GF_EPOC_HAS_AMR_WB) return GF_CODEC_SUPPORTED; } break; default: - return 0; + return GF_CODEC_NOT_SUPPORTED; } } - return 0; + return GF_CODEC_NOT_SUPPORTED; } #ifdef __cplusplus diff --git a/modules/ffmpeg_in/Makefile b/modules/ffmpeg_in/Makefile index 58935f6..c561bd6 100644 --- a/modules/ffmpeg_in/Makefile +++ b/modules/ffmpeg_in/Makefile @@ -2,7 +2,7 @@ include ../../config.mak vpath %.c $(SRC_PATH)/modules/ffmpeg_in -CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include" +CFLAGS=$(OPTFLAGS) -I"$(SRC_PATH)/include" $(ffmpeg_cflags) ifeq ($(DEBUGBUILD), yes) CFLAGS+=-g @@ -15,7 +15,7 @@ LDFLAGS+=-pg endif LOCAL_LIB= -LINKLIBS=-lgpac -lavcodec -lavformat -lavutil -lz +LINKLIBS=-lgpac -lz $(ffmpeg_lflags) #darwin needs bz2 ifeq ($(CONFIG_DARWIN),yes) @@ -24,7 +24,7 @@ endif #old ffmpeg lib ifeq ($(CONFIG_FFMPEG_OLD), yes) -CFLAGS+=-DFFMPEG_OLD_HEADERS +CFLAGS+=-DFFMPEG_OLD_HEADERS -I/usr/include else LINKLIBS+=-lswscale endif diff --git a/modules/ffmpeg_in/ffmpeg_decode.c b/modules/ffmpeg_in/ffmpeg_decode.c index 7c30833..19808a9 100644 --- a/modules/ffmpeg_in/ffmpeg_decode.c +++ b/modules/ffmpeg_in/ffmpeg_decode.c @@ -317,7 +317,8 @@ static GF_Err FFDEC_AttachStream(GF_BaseDecoder *plug, GF_ESD *esd) /*setup audio streams*/ if (ffd->st==GF_STREAM_AUDIO) { - if ((*codec)->type == CODEC_ID_MP2) { + /* souchay : test was wrong I think, was codec->type but must be codec->id */ + if ((*codec)->id == CODEC_ID_MP2) { (*ctx)->frame_size = ((*ctx)->sample_rate > 24000) ? 1152 : 576; } /*may be 0 (cfg not known yet)*/ @@ -510,11 +511,13 @@ static GF_Err FFDEC_GetCapabilities(GF_BaseDecoder *plug, GF_CodecCapability *ca static GF_Err FFDEC_SetCapabilities(GF_BaseDecoder *plug, GF_CodecCapability capability) { FFDec *ffd = (FFDec *)plug->privateStack; + assert(plug); + assert( ffd ); switch (capability.CapCode) { case GF_CODEC_WAIT_RAP: ffd->frame_start = 0; if (ffd->st==GF_STREAM_VISUAL) { - avcodec_flush_buffers(ffd->base_ctx); + if (ffd->base_ctx) avcodec_flush_buffers(ffd->base_ctx); if (ffd->depth_ctx) avcodec_flush_buffers(ffd->depth_ctx); } return GF_OK; @@ -646,6 +649,7 @@ redecode: return GF_PACKED_FRAMES; } + *outBufferLength = 0; /*visual stream*/ w = ctx->width; h = ctx->height; @@ -720,6 +724,12 @@ redecode: } } + if (!gotpic && (!ctx->width || !ctx->height) ) { + ctx->width = w; + ctx->height = h; + return GF_OK; + } + /*some streams use odd width/height frame values*/ if (ffd->out_pix_fmt == GF_PIXEL_YV12) { if (ctx->width%2) ctx->width++; @@ -730,6 +740,10 @@ redecode: if ((w != ctx->width) || (h != ctx->height)) { outsize = ctx->width * ctx->height * 3; if (ffd->out_pix_fmt != GF_PIXEL_RGB_24) outsize /= 2; + if (ffd->depth_codec) { + outsize = 5 * ctx->width * ctx->height / 2; + ffd->yuv_size = 3 * ctx->width * ctx->height / 2; + } ffd->out_size = outsize; *outBufferLength = ffd->out_size; if (ffd->check_h264_isma) { @@ -742,6 +756,9 @@ redecode: *cached_sws = NULL; } #endif + if (!ffd->no_par_update && ctx->sample_aspect_ratio.num && ctx->sample_aspect_ratio.den) { + ffd->previous_par = (ctx->sample_aspect_ratio.num<<16) | ctx->sample_aspect_ratio.den; + } return GF_BUFFER_TOO_SMALL; } /*check PAR in case on-the-fly change*/ @@ -754,7 +771,6 @@ redecode: } } - *outBufferLength = 0; if (mmlevel == GF_CODEC_LEVEL_SEEK) return GF_OK; if (!gotpic) return GF_OK; @@ -762,6 +778,7 @@ redecode: if (ES_ID == ffd->depth_ES_ID) { s32 i; u8 *pYO, *pYD; + pYO = frame->data[0]; pYD = outBuffer+ffd->yuv_size; for (i=0; iheight; i++) { @@ -841,7 +858,7 @@ redecode: return GF_OK; } -static Bool FFDEC_CanHandleStream(GF_BaseDecoder *plug, u32 StreamType, GF_ESD *esd, u8 PL) +static u32 FFDEC_CanHandleStream(GF_BaseDecoder *plug, u32 StreamType, GF_ESD *esd, u8 PL) { GF_BitStream *bs; u32 codec_id; @@ -850,8 +867,8 @@ static Bool FFDEC_CanHandleStream(GF_BaseDecoder *plug, u32 StreamType, GF_ESD * /*media type query*/ if (!esd) { - if ((StreamType==GF_STREAM_VISUAL) || (StreamType==GF_STREAM_AUDIO)) return 1; - return 0; + if ((StreamType==GF_STREAM_VISUAL) || (StreamType==GF_STREAM_AUDIO)) return GF_CODEC_STREAM_TYPE_SUPPORTED; + return GF_CODEC_NOT_SUPPORTED; } /*store types*/ @@ -883,6 +900,33 @@ static Bool FFDEC_CanHandleStream(GF_BaseDecoder *plug, u32 StreamType, GF_ESD * /*std MPEG-4 visual*/ else if (StreamType==GF_STREAM_VISUAL) { + + /*fixme - we should use some priority rather than declare ffmpeg can't handle svc*/ + if (esd->decoderConfig->objectTypeIndication == GPAC_OTI_VIDEO_AVC) { + if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) { + Bool is_svc = 0; + u32 i, count; + GF_AVCConfig *cfg = gf_odf_avc_cfg_read(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); + if (!cfg) return GF_CODEC_SUPPORTED; + + /*decode all NALUs*/ + count = gf_list_count(cfg->sequenceParameterSets); + for (i=0; isequenceParameterSets, i); + u8 nal_type = slc->data[0] & 0x1F; + + if (nal_type==GF_AVC_NALU_SVC_SUBSEQ_PARAM) { + is_svc = 1; + break; + } + } + gf_odf_avc_cfg_del(cfg); + return (is_svc || esd->decoderConfig->rvc_config || esd->decoderConfig->predefined_rvc_config) ? GF_CODEC_MAYBE_SUPPORTED : GF_CODEC_SUPPORTED; + } + if (esd->decoderConfig->rvc_config || esd->decoderConfig->predefined_rvc_config) return GF_CODEC_MAYBE_SUPPORTED; + return GF_CODEC_SUPPORTED; + } + switch (ffd->oti) { /*MPEG-4 v1 simple profile*/ case GPAC_OTI_VIDEO_MPEG4_PART2: codec_id = CODEC_ID_MPEG4; break; @@ -900,25 +944,33 @@ static Bool FFDEC_CanHandleStream(GF_BaseDecoder *plug, u32 StreamType, GF_ESD * codec_id = CODEC_ID_MPEG2VIDEO; break; /*JPEG*/ case GPAC_OTI_IMAGE_JPEG: -// return 0; /*I'm having troubles with ffmpeg & jpeg, it appears to crash randomly*/ codec_id = CODEC_ID_MJPEG; - //break; - /* SOUCHAY : the JPEG handler has some issues with some JPEG files, - * since GPAC also has img_in plugin for images, do not use FFMPEG one - */ - return 0; + /*return maybe supported as FFMPEG JPEG decoder has some issues with many files, so let's use it only if no + other dec is available*/ + if (avcodec_find_decoder(codec_id) != NULL) + return GF_CODEC_MAYBE_SUPPORTED; + + return GF_CODEC_NOT_SUPPORTED; default: - return 0; + return GF_CODEC_NOT_SUPPORTED; } } /*NeroDigital DVD subtitles*/ else if ((StreamType==GF_STREAM_ND_SUBPIC) && (ffd->oti==0xe0)) - return 1; + return GF_CODEC_SUPPORTED; - if (!codec_id) return 0; - if (check_4cc && (ffmpeg_get_codec(codec_id) != NULL)) return 1; - if (avcodec_find_decoder(codec_id) != NULL) return 1; - return 0; + if (!codec_id) return GF_CODEC_NOT_SUPPORTED; + + if (check_4cc && (ffmpeg_get_codec(codec_id) != NULL)) { + if (esd->decoderConfig->rvc_config || esd->decoderConfig->predefined_rvc_config) return GF_CODEC_MAYBE_SUPPORTED; + return GF_CODEC_SUPPORTED; + } + + if (avcodec_find_decoder(codec_id) != NULL) { + if (esd->decoderConfig->rvc_config || esd->decoderConfig->predefined_rvc_config) return GF_CODEC_MAYBE_SUPPORTED; + return GF_CODEC_SUPPORTED; + } + return GF_CODEC_NOT_SUPPORTED; } static const char *FFDEC_GetCodecName(GF_BaseDecoder *dec) @@ -970,6 +1022,7 @@ void FFDEC_Delete(void *ifce) if (!ifce) return; ffd = dec->privateStack; + dec->privateStack = NULL; if (ffd){ if (ffd->base_ctx) avcodec_close(ffd->base_ctx); ffd->base_ctx = NULL; @@ -983,6 +1036,5 @@ void FFDEC_Delete(void *ifce) #endif gf_free(ffd); } - dec->privateStack = NULL; - gf_free(dec); + gf_free(dec); } diff --git a/modules/ffmpeg_in/ffmpeg_demux.c b/modules/ffmpeg_in/ffmpeg_demux.c index 948897c..6f87ae2 100644 --- a/modules/ffmpeg_in/ffmpeg_demux.c +++ b/modules/ffmpeg_in/ffmpeg_demux.c @@ -36,6 +36,22 @@ #include #endif +/** + * New versions of ffmpeg do not declare AVERROR_NOMEM, AVERROR_IO, AVERROR_NOFMT + */ + +#ifndef AVERROR_NOMEM +#define AVERROR_NOMEM AVERROR(ENOMEM) +#endif /* AVERROR_NOMEM */ + +#ifndef AVERROR_IO +#define AVERROR_IO AVERROR(EIO) +#endif /* AVERROR_IO */ + +#ifndef AVERROR_NOFMT +#define AVERROR_NOFMT AVERROR(EINVAL) +#endif /* AVERROR_NOFMT */ + static u32 FFDemux_Run(void *par) { AVPacket pkt; @@ -224,6 +240,8 @@ static Bool FFD_CanHandleURL(GF_InputService *plug, const char *url) if (ext) ext[0] = 0; ext = strrchr(szName, '.'); + if (ext && strlen(ext) > 19) ext = NULL; + if (ext && strlen(ext) > 1) { strcpy(szExt, &ext[1]); strlwr(szExt); @@ -248,7 +266,7 @@ static Bool FFD_CanHandleURL(GF_InputService *plug, const char *url) { u32 i; for (i = 0 ; FFD_MIME_TYPES[i]; i+=3){ - if (gf_term_check_extension(plug, FFD_MIME_TYPES[0], FFD_MIME_TYPES[i+1], FFD_MIME_TYPES[i+2], ext)) + if (gf_term_check_extension(plug, FFD_MIME_TYPES[i], FFD_MIME_TYPES[i+1], FFD_MIME_TYPES[i+2], ext)) return 1; } } @@ -264,8 +282,8 @@ static Bool FFD_CanHandleURL(GF_InputService *plug, const char *url) return 0; } } - if (!ctx || av_find_stream_info(ctx) <0) goto exit; + /*figure out if we can use codecs or not*/ has_video = has_audio = 0; for(i = 0; i < (s32)ctx->nb_streams; i++) { @@ -460,7 +478,7 @@ static int ff_url_read(void *h, unsigned char *buf, int size) full_size = 0; if (ffd->buffer_used) { - if (ffd->buffer_used > (u32) size) { + if (ffd->buffer_used >= (u32) size) { ffd->buffer_used-=size; memcpy(ffd->buffer, ffd->buffer+size, sizeof(char)*ffd->buffer_used); #ifdef FFMPEG_DUMP_REMOTE @@ -502,10 +520,6 @@ static int ff_url_read(void *h, unsigned char *buf, int size) return full_size ? (int) full_size : -1; } -static void FFD_NetIO(void *cbk, GF_NETIO_Parameter *param) -{ -} - static GF_Err FFD_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url) { @@ -559,27 +573,34 @@ static GF_Err FFD_ConnectService(GF_InputService *plug, GF_ClientService *serv, init_put_byte(&ffd->io, ffd->buffer, ffd->buffer_size, 0, ffd, ff_url_read, NULL, NULL); ffd->io.is_streamed = 1; - ffd->dnload = gf_term_download_new(ffd->service, url, GF_NETIO_SESSION_NOT_THREADED | GF_NETIO_SESSION_NOT_CACHED, FFD_NetIO, ffd); + ffd->dnload = gf_term_download_new(ffd->service, url, GF_NETIO_SESSION_NOT_THREADED | GF_NETIO_SESSION_NOT_CACHED, NULL, ffd); if (!ffd->dnload) return GF_URL_ERROR; while (1) { - e = gf_dm_sess_fetch_data(ffd->dnload, ffd->buffer, ffd->buffer_size, &ffd->buffer_used); + u32 read; + e = gf_dm_sess_fetch_data(ffd->dnload, ffd->buffer + ffd->buffer_used, ffd->buffer_size - ffd->buffer_used, &read); if (e==GF_EOS) break; /*we're sync!!*/ if (e==GF_IP_NETWORK_EMPTY) continue; if (e) goto err_exit; - if (ffd->buffer_used) break; + ffd->buffer_used += read; + if (ffd->buffer_used == ffd->buffer_size) break; } - - pd.filename = szName; - pd.buf_size = ffd->buffer_used; - pd.buf = ffd->buffer; - av_in = av_probe_input_format(&pd, 1); - if (!av_in) { - return GF_NOT_SUPPORTED; + if (e==GF_EOS) { + const char *cache_file = gf_dm_sess_get_cache_name(ffd->dnload); + res = av_open_input_file(&ffd->ctx, cache_file, av_in, 0, NULL); + } else { + pd.filename = szName; + pd.buf_size = ffd->buffer_used; + pd.buf = ffd->buffer; + av_in = av_probe_input_format(&pd, 1); + if (!av_in) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[FFMPEG] error probing file %s - probe start with %c %c %c %c\n", url, ffd->buffer[0], ffd->buffer[1], ffd->buffer[2], ffd->buffer[3])); + return GF_NOT_SUPPORTED; + } + /*setup downloader*/ + av_in->flags |= AVFMT_NOFILE; + res = av_open_input_stream(&ffd->ctx, &ffd->io, szName, av_in, NULL); } - /*setup downloader*/ - av_in->flags |= AVFMT_NOFILE; - res = av_open_input_stream(&ffd->ctx, &ffd->io, szName, av_in, NULL); } else { res = av_open_input_file(&ffd->ctx, szName, av_in, 0, NULL); } @@ -895,16 +916,15 @@ void *New_FFMPEG_Demux() GF_InputService *ffd = gf_malloc(sizeof(GF_InputService)); memset(ffd, 0, sizeof(GF_InputService)); - priv = gf_malloc(sizeof(FFDemux)); - memset(priv, 0, sizeof(FFDemux)); + GF_SAFEALLOC(priv, FFDemux); - GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[FFMPEG Demuxer] Registering all ffmpeg plugins...\n") ); - /* register all codecs, demux and protocols */ - av_register_all(); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[FFMPEG Demuxer] Registering all ffmpeg plugins DONE.\n") ); + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[FFMPEG Demuxer] Registering all ffmpeg plugins...\n") ); + /* register all codecs, demux and protocols */ + av_register_all(); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[FFMPEG Demuxer] Registering all ffmpeg plugins DONE.\n") ); ffd->RegisterMimeTypes = FFD_RegisterMimeTypes; - ffd->CanHandleURL = FFD_CanHandleURL; + ffd->CanHandleURL = FFD_CanHandleURL; ffd->CloseService = FFD_CloseService; ffd->ConnectChannel = FFD_ConnectChannel; ffd->ConnectService = FFD_ConnectService; diff --git a/modules/ft_font/Makefile b/modules/ft_font/Makefile index 58e29c3..1b5fa80 100644 --- a/modules/ft_font/Makefile +++ b/modules/ft_font/Makefile @@ -38,7 +38,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(LINKVAR) $(EXTRALIBS) ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_ft_font-static.so $(OBJS) $(LINKVAR) $(EXTRALIBS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_ft_font-static.$(DYN_LIB_SUFFIX) $(OBJS) $(LINKVAR) $(EXTRALIBS) endif diff --git a/modules/gpac_js/gpac_js.c b/modules/gpac_js/gpac_js.c index 0ecfc28..62e5046 100644 --- a/modules/gpac_js/gpac_js.c +++ b/modules/gpac_js/gpac_js.c @@ -50,6 +50,8 @@ #include #include +#define GPAC_JS_RTI_REFRESH_RATE 200 + typedef struct { u32 nb_loaded; @@ -64,7 +66,11 @@ typedef struct GF_Event *evt; JSContext *c; - JSObject *obj, *evt_obj; + JSObject *evt_filter_obj, *evt_obj; + JSObject *gpac_obj; + + u32 rti_refresh_rate; + GF_SystemRTInfo rti; } GF_GPACJSExt; @@ -170,6 +176,23 @@ static JSBool gpac_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, js else if (!strcmp(prop_name, "hardware_stretch")) { *vp = INT_TO_JSVAL( (term->compositor->video_out->hw_caps & GF_VIDEO_HW_HAS_STRETCH) ? 1 : 0 ); } + else if (!strcmp(prop_name, "http_bitrate")) { + *vp = INT_TO_JSVAL( gf_dm_get_data_rate(term->downloader)*8/1024); + } + else if (!strcmp(prop_name, "fps")) { + Double fps = gf_sc_get_fps(term->compositor, 0); + *vp = DOUBLE_TO_JSVAL(JS_NewDouble(c, fps) ); + } + else if (!strcmp(prop_name, "cpu_load")) { + GF_GPACJSExt *ext = (GF_GPACJSExt *)JS_GetPrivate(c, obj); + gf_sys_get_rti(ext->rti_refresh_rate, &ext->rti, 0); + *vp = INT_TO_JSVAL(ext->rti.process_cpu_usage); + } + else if (!strcmp(prop_name, "memory")) { + GF_GPACJSExt *ext = (GF_GPACJSExt *)JS_GetPrivate(c, obj); + gf_sys_get_rti(ext->rti_refresh_rate, &ext->rti, 0); + *vp = INT_TO_JSVAL(ext->rti.process_memory); + } SMJS_FREE(c, prop_name); @@ -237,6 +260,11 @@ static JSBool gpac_setProperty(JSContext *c, JSObject *obj, SMJS_PROP_SETTER, js gf_sc_set_option(term->compositor, GF_OPT_REFRESH, 0); } } + else if (!strcmp(prop_name, "http_bitrate")) { + u32 new_rate = JSVAL_TO_INT(*vp); + gf_dm_set_data_rate(term->downloader, new_rate * 128 /*1024/8*/); + } + SMJS_FREE(c, prop_name); return JS_TRUE; } @@ -330,6 +358,8 @@ static Bool enum_dir_fct(void *cbck, char *file_name, char *file_path) JSObject *obj; enum_dir_cbk *cbk = (enum_dir_cbk*)cbck; + if (file_name && (file_name[0]=='.')) return 0; + obj = JS_NewObject(cbk->c, 0, 0, 0); s = JS_NewStringCopyZ(cbk->c, file_name); JS_DefineProperty(cbk->c, obj, "name", STRING_TO_JSVAL(s), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); @@ -366,8 +396,10 @@ static JSBool SMJS_FUNCTION(gpac_enum_directory) char *url = NULL; char *dir = NULL; char *filter = NULL; + char *an_url; Bool dir_only = 0; Bool browse_root = 0; + GF_Terminal *term; SMJS_OBJ SMJS_ARGS @@ -413,15 +445,15 @@ static JSBool SMJS_FUNCTION(gpac_enum_directory) cbk.array = JS_NewArrayObject(c, 0, 0); cbk.is_dir = 1; - err = gf_enum_directory(url ? url : dir, 1, enum_dir_fct, &cbk, NULL); - if (err==GF_IO_ERR) { - GF_Terminal *term = gpac_get_term(c, obj); - /*try to concatenate with service url*/ - char *an_url = gf_url_concatenate(term->root_scene->root_od->net_service->url, url ? url : dir); + + term = gpac_get_term(c, obj); + /*concatenate with service url*/ + an_url = gf_url_concatenate(term->root_scene->root_od->net_service->url, url ? url : dir); + if (an_url) { gf_free(url); url = an_url; - gf_enum_directory(url ? url : dir, 1, enum_dir_fct, &cbk, NULL); } + err = gf_enum_directory(url ? url : dir, 1, enum_dir_fct, &cbk, NULL); if (!dir_only) { cbk.is_dir = 0; @@ -665,6 +697,19 @@ static JSBool gpacevt_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, if (!strcmp(name, "target_url")) { *vp = STRING_TO_JSVAL( JS_NewStringCopyZ(c, evt->navigate.to_url) ); } + else if (!strcmp(name, "files")) { + u32 i, idx; + jsval v; + JSObject *files_array = JS_NewArrayObject(c, 0, NULL); + for (i=0; iopen_file.nb_files; i++) { + if (evt->open_file.files[i]) { + JS_GetArrayLength(c, files_array, &idx); + v = STRING_TO_JSVAL( JS_NewStringCopyZ(c, evt->open_file.files[i]) ); + JS_SetElement(c, files_array, idx, &v); + } + } + *vp = OBJECT_TO_JSVAL(files_array); + } SMJS_FREE(c, name); } @@ -680,18 +725,18 @@ static Bool gjs_event_filter(void *udta, GF_Event *evt, Bool consumed_by_composi if (gjs->evt != NULL) return 0; gf_sg_lock_javascript(gjs->c, 1); - + rval = JSVAL_VOID; gjs->evt = evt; JS_SetPrivate(gjs->c, gjs->evt_obj, gjs); argv[0] = OBJECT_TO_JSVAL(gjs->evt_obj); - JS_CallFunctionValue(gjs->c, gjs->obj, gjs->evt_fun, 1, argv, &rval); + rval = JSVAL_VOID; + JS_CallFunctionValue(gjs->c, gjs->evt_filter_obj, gjs->evt_fun, 1, argv, &rval); JS_SetPrivate(gjs->c, gjs->evt_obj, NULL); gjs->evt = NULL; - if (rval==JSVAL_VOID) { - res = 0; - } else if (JSVAL_IS_BOOLEAN(rval) ) { + res = 0; + if (JSVAL_IS_BOOLEAN(rval) ) { res = (JSVAL_TO_BOOLEAN(rval)==JS_TRUE) ? 1 : 0; } else if (JSVAL_IS_INT(rval) ) { res = (JSVAL_TO_INT(rval)) ? 1 : 0; @@ -710,7 +755,7 @@ static JSBool SMJS_FUNCTION(gpac_set_event_filter) if (gjs->evt_fun) return JS_TRUE; gjs->evt_fun = argv[0]; - gjs->obj = obj; + gjs->evt_filter_obj = obj; gjs->c = c; gjs->evt_filter.udta = gjs; gjs->evt_filter.on_event = gjs_event_filter; @@ -786,8 +831,6 @@ static JSBool SMJS_FUNCTION(gpac_get_scene) static void gjs_load(GF_JSUserExtension *jsext, GF_SceneGraph *scene, JSContext *c, JSObject *global, Bool unload) { GF_GPACJSExt *gjs; - JSObject *obj; - GF_JSAPIParam par; JSPropertySpec gpacEvtClassProps[] = { @@ -810,6 +853,8 @@ static void gjs_load(GF_JSUserExtension *jsext, GF_SceneGraph *scene, JSContext JSFunctionSpec gpacClassFuncs[] = { SMJS_FUNCTION_SPEC("getOption", gpac_getOption, 3), SMJS_FUNCTION_SPEC("setOption", gpac_setOption, 4), + SMJS_FUNCTION_SPEC("get_option", gpac_getOption, 3), + SMJS_FUNCTION_SPEC("set_option", gpac_setOption, 4), SMJS_FUNCTION_SPEC("enum_directory", gpac_enum_directory, 1), SMJS_FUNCTION_SPEC("set_size", gpac_set_size, 1), SMJS_FUNCTION_SPEC("get_horizontal_dpi", gpac_get_horizontal_dpi, 0), @@ -839,10 +884,7 @@ static void gjs_load(GF_JSUserExtension *jsext, GF_SceneGraph *scene, JSContext } return; } - if (gjs->nb_loaded) { - gjs->nb_loaded++; - return; - } + gjs->nb_loaded++; if (!scene) return; @@ -850,52 +892,58 @@ static void gjs_load(GF_JSUserExtension *jsext, GF_SceneGraph *scene, JSContext JS_SETUP_CLASS(gjs->gpacClass, "GPAC", JSCLASS_HAS_PRIVATE, gpac_getProperty, gpac_setProperty, JS_FinalizeStub); - JS_InitClass(c, global, 0, &gjs->gpacClass, 0, 0, gpacClassProps, gpacClassFuncs, 0, 0); - obj = JS_DefineObject(c, global, "gpac", &gjs->gpacClass, 0, 0); + if (!gjs->gpac_obj) { + JS_InitClass(c, global, 0, &gjs->gpacClass, 0, 0, gpacClassProps, gpacClassFuncs, 0, 0); + gjs->gpac_obj = JS_DefineObject(c, global, "gpac", &gjs->gpacClass, 0, 0); - if (scene->script_action) { - if (scene->script_action(scene->script_action_cbck, GF_JSAPI_OP_GET_TERM, scene->RootNode, &par)) { - gjs->term = par.term; + if (scene->script_action) { + if (scene->script_action(scene->script_action_cbck, GF_JSAPI_OP_GET_TERM, scene->RootNode, &par)) { + gjs->term = par.term; + } } + JS_SetPrivate(c, gjs->gpac_obj, gjs); + } else { + JS_DefineProperty(c, global, "gpac", OBJECT_TO_JSVAL(gjs->gpac_obj), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); } - JS_SetPrivate(c, obj, gjs); - - JS_SETUP_CLASS(gjs->gpacEvtClass, "GPACEVT", JSCLASS_HAS_PRIVATE, gpacevt_getProperty, JS_PropertyStub_forSetter, JS_FinalizeStub); - JS_InitClass(c, global, 0, &gjs->gpacEvtClass, 0, 0, gpacEvtClassProps, gpacEvtClassFuncs, 0, 0); - gjs->evt_obj = JS_DefineObject(c, global, "gpacevt", &gjs->gpacEvtClass, 0, 0); + if (!gjs->evt_obj) { + JS_SETUP_CLASS(gjs->gpacEvtClass, "GPACEVT", JSCLASS_HAS_PRIVATE, gpacevt_getProperty, JS_PropertyStub_forSetter, JS_FinalizeStub); + JS_InitClass(c, global, 0, &gjs->gpacEvtClass, 0, 0, gpacEvtClassProps, gpacEvtClassFuncs, 0, 0); + gjs->evt_obj = JS_DefineObject(c, global, "gpacevt", &gjs->gpacEvtClass, 0, 0); #define DECLARE_GPAC_CONST(name) \ - JS_DefineProperty(c, global, #name, INT_TO_JSVAL(name), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); - - DECLARE_GPAC_CONST(GF_EVENT_CLICK); - DECLARE_GPAC_CONST(GF_EVENT_MOUSEUP); - DECLARE_GPAC_CONST(GF_EVENT_MOUSEDOWN); - DECLARE_GPAC_CONST(GF_EVENT_MOUSEMOVE); - DECLARE_GPAC_CONST(GF_EVENT_MOUSEWHEEL); - DECLARE_GPAC_CONST(GF_EVENT_KEYUP); - DECLARE_GPAC_CONST(GF_EVENT_KEYDOWN); - DECLARE_GPAC_CONST(GF_EVENT_TEXTINPUT); - DECLARE_GPAC_CONST(GF_EVENT_CONNECT); - DECLARE_GPAC_CONST(GF_EVENT_NAVIGATE_INFO); - DECLARE_GPAC_CONST(GF_EVENT_NAVIGATE); - - DECLARE_GPAC_CONST(GF_NAVIGATE_NONE); - DECLARE_GPAC_CONST(GF_NAVIGATE_WALK); - DECLARE_GPAC_CONST(GF_NAVIGATE_FLY); - DECLARE_GPAC_CONST(GF_NAVIGATE_PAN); - DECLARE_GPAC_CONST(GF_NAVIGATE_GAME); - DECLARE_GPAC_CONST(GF_NAVIGATE_SLIDE); - DECLARE_GPAC_CONST(GF_NAVIGATE_EXAMINE); - DECLARE_GPAC_CONST(GF_NAVIGATE_ORBIT); - DECLARE_GPAC_CONST(GF_NAVIGATE_VR); - - DECLARE_GPAC_CONST(GF_NAVIGATE_TYPE_NONE); - DECLARE_GPAC_CONST(GF_NAVIGATE_TYPE_2D); - DECLARE_GPAC_CONST(GF_NAVIGATE_TYPE_3D); - - JS_SETUP_CLASS(gjs->anyClass, "GPACOBJECT", JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub_forSetter, JS_FinalizeStub); - JS_InitClass(c, global, 0, &gjs->anyClass, 0, 0, 0, 0, 0, 0); + JS_DefineProperty(c, global, #name, INT_TO_JSVAL(name), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + + DECLARE_GPAC_CONST(GF_EVENT_CLICK); + DECLARE_GPAC_CONST(GF_EVENT_MOUSEUP); + DECLARE_GPAC_CONST(GF_EVENT_MOUSEDOWN); + DECLARE_GPAC_CONST(GF_EVENT_MOUSEMOVE); + DECLARE_GPAC_CONST(GF_EVENT_MOUSEWHEEL); + DECLARE_GPAC_CONST(GF_EVENT_KEYUP); + DECLARE_GPAC_CONST(GF_EVENT_KEYDOWN); + DECLARE_GPAC_CONST(GF_EVENT_TEXTINPUT); + DECLARE_GPAC_CONST(GF_EVENT_CONNECT); + DECLARE_GPAC_CONST(GF_EVENT_NAVIGATE_INFO); + DECLARE_GPAC_CONST(GF_EVENT_NAVIGATE); + DECLARE_GPAC_CONST(GF_EVENT_OPENFILE); + + DECLARE_GPAC_CONST(GF_NAVIGATE_NONE); + DECLARE_GPAC_CONST(GF_NAVIGATE_WALK); + DECLARE_GPAC_CONST(GF_NAVIGATE_FLY); + DECLARE_GPAC_CONST(GF_NAVIGATE_PAN); + DECLARE_GPAC_CONST(GF_NAVIGATE_GAME); + DECLARE_GPAC_CONST(GF_NAVIGATE_SLIDE); + DECLARE_GPAC_CONST(GF_NAVIGATE_EXAMINE); + DECLARE_GPAC_CONST(GF_NAVIGATE_ORBIT); + DECLARE_GPAC_CONST(GF_NAVIGATE_VR); + + DECLARE_GPAC_CONST(GF_NAVIGATE_TYPE_NONE); + DECLARE_GPAC_CONST(GF_NAVIGATE_TYPE_2D); + DECLARE_GPAC_CONST(GF_NAVIGATE_TYPE_3D); + + JS_SETUP_CLASS(gjs->anyClass, "GPACOBJECT", JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub_forSetter, JS_FinalizeStub); + JS_InitClass(c, global, 0, &gjs->anyClass, 0, 0, 0, 0, 0, 0); + } } @@ -911,6 +959,7 @@ GF_JSUserExtension *gjs_new() GF_REGISTER_MODULE_INTERFACE(dr, GF_JS_USER_EXT_INTERFACE, "GPAC JavaScript Bindings", "gpac distribution"); GF_SAFEALLOC(gjs, GF_GPACJSExt); + gjs->rti_refresh_rate = GPAC_JS_RTI_REFRESH_RATE; dr->load = gjs_load; dr->udta = gjs; return dr; diff --git a/modules/hyb_in/fm_fake_pull.c b/modules/hyb_in/fm_fake_pull.c new file mode 100644 index 0000000..2680791 --- /dev/null +++ b/modules/hyb_in/fm_fake_pull.c @@ -0,0 +1,184 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Romain Bouqueau + * Copyright (c) Telecom ParisTech 2010-20xx + * All rights reserved + * + * This file is part of GPAC / Hybrid Media input module + * + * 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. + * + */ + +/*hybrid media interface implementation generating fake audio consisting in beeps every second in pull mode*/ + +#include +#include "hyb_in.h" + +/**********************************************************************************************************************/ + +#define FM_FAKE_PULL_AUDIO_FREQ 44100 +#define FM_FAKE_PULL_CHAN_NUM 2 +#define FM_FAKE_PULL_BITS 16 +#define FM_FAKE_PULL_TYPE s16 +#define FM_FAKE_PULL_FRAME_DUR 60 /*in ms*/ +#define FM_FAKE_PULL_FRAME_LEN ((FM_FAKE_PULL_FRAME_DUR*FM_FAKE_PULL_CHAN_NUM*FM_FAKE_PULL_BITS*FM_FAKE_PULL_AUDIO_FREQ)/(1000*8)) /*in bytes*/ + +/**********************************************************************************************************************/ + +typedef struct s_FM_FAKE_PULL { + u64 PTS; + unsigned char buffer10[FM_FAKE_PULL_FRAME_LEN]; /*played 10 percent of time*/ + unsigned char buffer90[FM_FAKE_PULL_FRAME_LEN]; /*played 90 percent of time*/ + +} FM_FAKE_PULL; +FM_FAKE_PULL FM_FAKE_PULL_private_data; + +/**********************************************************************************************************************/ + +static Bool FM_FAKE_PULL_CanHandleURL(const char *url); +static GF_ObjectDescriptor* FM_FAKE_PULL_GetOD(void); +static GF_Err FM_FAKE_PULL_Connect(GF_HYBMEDIA *self, GF_ClientService *service, const char *url); +static GF_Err FM_FAKE_PULL_Disconnect(GF_HYBMEDIA *self); +static GF_Err FM_FAKE_PULL_GetData(GF_HYBMEDIA *self, char **out_data_ptr, u32 *out_data_size, GF_SLHeader *out_sl_hdr); +static GF_Err FM_FAKE_PULL_ReleaseData(GF_HYBMEDIA *self); + +GF_HYBMEDIA master_fm_fake_pull = { + "Fake FM (pull mode)", /*name*/ + FM_FAKE_PULL_CanHandleURL, /*CanHandleURL()*/ + FM_FAKE_PULL_GetOD, /*GetOD()*/ + FM_FAKE_PULL_Connect, /*Connect()*/ + FM_FAKE_PULL_Disconnect, /*Disconnect()*/ + NULL, /*SetState()*/ + FM_FAKE_PULL_GetData, /*GetData()*/ + FM_FAKE_PULL_ReleaseData, /*ReleaseData()*/ + HYB_PULL, /*data_mode*/ + &FM_FAKE_PULL_private_data /*private_data*/ +}; + +/**********************************************************************************************************************/ + +static Bool FM_FAKE_PULL_CanHandleURL(const char *url) +{ + if (!strnicmp(url, "fm://fake_pull", 14)) + return 1; + + return 0; +} + +/**********************************************************************************************************************/ + +static GF_ESD* get_esd() +{ + GF_BitStream *dsi = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); + GF_ESD *esd = gf_odf_desc_esd_new(0); + + esd->ESID = 1; + esd->decoderConfig->streamType = GF_STREAM_AUDIO; + esd->decoderConfig->objectTypeIndication = GPAC_OTI_RAW_MEDIA_STREAM; + esd->decoderConfig->avgBitrate = esd->decoderConfig->maxBitrate = 0; + esd->slConfig->timestampResolution = FM_FAKE_PULL_AUDIO_FREQ; + + /*Decoder Specific Info for raw media*/ + gf_bs_write_u32(dsi, FM_FAKE_PULL_AUDIO_FREQ); /*u32 sample_rate*/ + gf_bs_write_u16(dsi, FM_FAKE_PULL_CHAN_NUM); /*u16 nb_channels*/ + gf_bs_write_u16(dsi, FM_FAKE_PULL_BITS); /*u16 nb_bits_per_sample*/ + gf_bs_write_u32(dsi, FM_FAKE_PULL_FRAME_LEN); /*u32 frame_size*/ + gf_bs_write_u32(dsi, 0); /*u32 channel_config*/ + gf_bs_get_content(dsi, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); + gf_bs_del(dsi); + + return esd; +} + +/**********************************************************************************************************************/ + +static GF_ObjectDescriptor* FM_FAKE_PULL_GetOD(void) +{ + /*declare object to terminal*/ + GF_ObjectDescriptor *od = (GF_ObjectDescriptor*)gf_odf_desc_new(GF_ODF_OD_TAG); + GF_ESD *esd = get_esd(); + od->objectDescriptorID = 1; + gf_list_add(od->ESDescriptors, esd); + return od; +} + +/**********************************************************************************************************************/ + +static GF_Err FM_FAKE_PULL_Connect(GF_HYBMEDIA *self, GF_ClientService *service, const char *url) +{ + u32 i; + + if (!self) + return GF_BAD_PARAM; + + if (!service) + return GF_BAD_PARAM; + + self->owner = service; + + /*set audio preloaded data*/ + assert(self->private_data); + memset(self->private_data, 0, sizeof(FM_FAKE_PULL)); + for (i=0; i<(FM_FAKE_PULL_FRAME_LEN*8)/FM_FAKE_PULL_BITS; i++) { + if (((2*i)/(FM_FAKE_PULL_CHAN_NUM*100))%2) /*100Hz*/ + *((FM_FAKE_PULL_TYPE*)((FM_FAKE_PULL*)self->private_data)->buffer10+i) = 1 << (FM_FAKE_PULL_BITS-1); + } + + return GF_OK; +} + +/**********************************************************************************************************************/ + +static GF_Err FM_FAKE_PULL_Disconnect(GF_HYBMEDIA *self) +{ + self->owner = NULL; + return GF_OK; +} + +/**********************************************************************************************************************/ + +static GF_Err FM_FAKE_PULL_GetData(GF_HYBMEDIA *self, char **out_data_ptr, u32 *out_data_size, GF_SLHeader *out_sl_hdr) +{ + u64 delta_pts = (FM_FAKE_PULL_FRAME_DUR*FM_FAKE_PULL_AUDIO_FREQ)/1000; + assert(!(FM_FAKE_PULL_FRAME_DUR*FM_FAKE_PULL_AUDIO_FREQ%1000)); + + /*write SL header*/ + memset(out_sl_hdr, 0, sizeof(GF_SLHeader)); + out_sl_hdr->compositionTimeStampFlag = 1; + out_sl_hdr->compositionTimeStamp = ((FM_FAKE_PULL*)self->private_data)->PTS; + out_sl_hdr->accessUnitStartFlag = 1; + + /*write audio data*/ + if ((((FM_FAKE_PULL*)self->private_data)->PTS%(10*delta_pts))) { + *out_data_ptr = ((FM_FAKE_PULL*)self->private_data)->buffer90; + } else { + *out_data_ptr = ((FM_FAKE_PULL*)self->private_data)->buffer10; + } + *out_data_size = FM_FAKE_PULL_FRAME_LEN; + ((FM_FAKE_PULL*)self->private_data)->PTS += delta_pts; + + return GF_OK; +} + +/**********************************************************************************************************************/ + +static GF_Err FM_FAKE_PULL_ReleaseData(GF_HYBMEDIA *self) +{ + return GF_OK; +} + +/**********************************************************************************************************************/ diff --git a/modules/hyb_in/fm_fake_push.c b/modules/hyb_in/fm_fake_push.c new file mode 100644 index 0000000..1ef2c35 --- /dev/null +++ b/modules/hyb_in/fm_fake_push.c @@ -0,0 +1,307 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Romain Bouqueau + * Copyright (c) Telecom ParisTech 2010-20xx + * All rights reserved + * + * This file is part of GPAC / Hybrid Media input module + * + * 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. + * + */ + +/*hybrid media interface implementation generating fake audio consisting in beeps every second in push mode*/ + +#include +#include +#include +#include "hyb_in.h" + +/**********************************************************************************************************************/ + +#define FM_FAKE_PUSH_AUDIO_FREQ 44100 +#define FM_FAKE_PUSH_CHAN_NUM 2 +#define FM_FAKE_PUSH_BITS 16 +#define FM_FAKE_PUSH_TYPE s16 +#define FM_FAKE_PUSH_FRAME_DUR 60 /*in ms*/ +#define FM_FAKE_PUSH_FRAME_LEN ((FM_FAKE_PUSH_FRAME_DUR*FM_FAKE_PUSH_CHAN_NUM*FM_FAKE_PUSH_BITS*FM_FAKE_PUSH_AUDIO_FREQ)/(1000*8)) /*in bytes*/ + +/**********************************************************************************************************************/ + +typedef struct s_FM_FAKE_PUSH { + u64 PTS; + unsigned char buffer10[FM_FAKE_PUSH_FRAME_LEN]; /*played 10 percent of time*/ + unsigned char buffer90[FM_FAKE_PUSH_FRAME_LEN]; /*played 90 percent of time*/ + + GF_Thread *th; + +} FM_FAKE_PUSH; +FM_FAKE_PUSH FM_FAKE_PUSH_private_data; + +/**********************************************************************************************************************/ + +static Bool FM_FAKE_PUSH_CanHandleURL(const char *url); +static GF_ObjectDescriptor* FM_FAKE_PUSH_GetOD(void); +static GF_Err FM_FAKE_PUSH_Connect(GF_HYBMEDIA *self, GF_ClientService *service, const char *url); +static GF_Err FM_FAKE_PUSH_Disconnect(GF_HYBMEDIA *self); +static GF_Err FM_FAKE_PUSH_SetState(GF_HYBMEDIA *self, const GF_NET_CHAN_CMD state); + +GF_HYBMEDIA master_fm_fake_push = { + "Fake FM (push mode)", /*name*/ + FM_FAKE_PUSH_CanHandleURL, /*CanHandleURL()*/ + FM_FAKE_PUSH_GetOD, /*GetOD()*/ + FM_FAKE_PUSH_Connect, /*Connect()*/ + FM_FAKE_PUSH_Disconnect, /*Disconnect()*/ + FM_FAKE_PUSH_SetState, /*SetState()*/ + NULL, /*GetData()*/ + NULL, /*ReleaseData()*/ + HYB_PUSH, /*data_mode*/ + &FM_FAKE_PUSH_private_data /*private_data*/ +}; + +/**********************************************************************************************************************/ + +static Bool FM_FAKE_PUSH_CanHandleURL(const char *url) +{ + if (!strnicmp(url, "fm://fake_push", 14)) + return 1; + + return 0; +} + +/**********************************************************************************************************************/ + +static GF_ESD* get_esd() +{ + GF_BitStream *dsi = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); + GF_ESD *esd = gf_odf_desc_esd_new(0); + + esd->ESID = 1; + esd->decoderConfig->streamType = GF_STREAM_AUDIO; + esd->decoderConfig->objectTypeIndication = GPAC_OTI_RAW_MEDIA_STREAM; + esd->decoderConfig->avgBitrate = esd->decoderConfig->maxBitrate = 0; + esd->slConfig->timestampResolution = FM_FAKE_PUSH_AUDIO_FREQ; + + /*Decoder Specific Info for raw media*/ + gf_bs_write_u32(dsi, FM_FAKE_PUSH_AUDIO_FREQ); /*u32 sample_rate*/ + gf_bs_write_u16(dsi, FM_FAKE_PUSH_CHAN_NUM); /*u16 nb_channels*/ + gf_bs_write_u16(dsi, FM_FAKE_PUSH_BITS); /*u16 nb_bits_per_sample*/ + gf_bs_write_u32(dsi, FM_FAKE_PUSH_FRAME_LEN); /*u32 frame_size*/ + gf_bs_write_u32(dsi, 0); /*u32 channel_config*/ + gf_bs_get_content(dsi, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); + gf_bs_del(dsi); + + return esd; +} + +/**********************************************************************************************************************/ + +static GF_ObjectDescriptor* FM_FAKE_PUSH_GetOD(void) +{ + /*declare object to terminal*/ + GF_ObjectDescriptor *od = (GF_ObjectDescriptor*)gf_odf_desc_new(GF_ODF_OD_TAG); + GF_ESD *esd = get_esd(); + od->objectDescriptorID = 1; + gf_list_add(od->ESDescriptors, esd); + return od; +} + +/**********************************************************************************************************************/ + +static GF_Err GetData(const GF_HYBMEDIA *self, char **out_data_ptr, u32 *out_data_size, GF_SLHeader *out_sl_hdr) +{ + u64 delta_pts = (FM_FAKE_PUSH_FRAME_DUR*FM_FAKE_PUSH_AUDIO_FREQ)/1000; + assert(!(FM_FAKE_PUSH_FRAME_DUR*FM_FAKE_PUSH_AUDIO_FREQ%1000)); + + /*write SL header*/ + memset(out_sl_hdr, 0, sizeof(GF_SLHeader)); + out_sl_hdr->compositionTimeStampFlag = 1; + out_sl_hdr->compositionTimeStamp = ((FM_FAKE_PUSH*)self->private_data)->PTS; + out_sl_hdr->accessUnitStartFlag = 1; + + /*write audio data*/ + if ((((FM_FAKE_PUSH*)self->private_data)->PTS%(10*delta_pts))) { + *out_data_ptr = ((FM_FAKE_PUSH*)self->private_data)->buffer90; + } else { + *out_data_ptr = ((FM_FAKE_PUSH*)self->private_data)->buffer10; + } + *out_data_size = FM_FAKE_PUSH_FRAME_LEN; + ((FM_FAKE_PUSH*)self->private_data)->PTS += delta_pts; + + return GF_OK; +} + +/**********************************************************************************************************************/ + +static u32 audio_gen_th(void *par) +{ + GF_Err e; + char *data; + u32 data_size, init_time; + s32 time_to_wait = 0; + GF_SLHeader slh; + GF_HYBMEDIA *self = (GF_HYBMEDIA*) par; + FM_FAKE_PUSH *fm_fake_push = (FM_FAKE_PUSH*)self->private_data; + memset(&slh, 0, sizeof(GF_SLHeader)); + + while (self->state >= 0) /*pause or play*/ + { + if (self->state == HYB_STATE_PAUSE) { + gf_sleep(10); + init_time = (u32)(gf_sys_clock() - ((u64)slh.compositionTimeStamp*1000)/FM_FAKE_PUSH_AUDIO_FREQ); /*pause: won't wait at resume*/ + continue; + } + + if (!time_to_wait) + { + /*TODO: remove the sleep*/ + gf_sleep(1000); + + /*for hybrid scenarios: add an external media*/ + { + /*declare object to terminal*/ + GF_ObjectDescriptor *od = (GF_ObjectDescriptor*)gf_odf_desc_new(GF_ODF_OD_TAG); + od->URLString = PUT_TOUR_URL_HERE; + od->objectDescriptorID = 0; + gf_term_add_media(self->owner, (GF_Descriptor*)od, 0); + } + + /*for hybrid scenarios: map clocks*/ + { + time_t now; + struct tm *now_tm; + time(&now); + now_tm = gmtime(&now); + { + GF_NetworkCommand com; + memset(&com, 0, sizeof(com)); + com.command_type = GF_NET_CHAN_MAP_TIME; + com.map_time.media_time = now_tm->tm_hour*3600+now_tm->tm_min*60+now_tm->tm_sec; + com.map_time.timestamp = slh.compositionTimeStamp; + com.map_time.reset_buffers = 0; + com.base.on_channel = self->channel; + gf_term_on_command(self->owner, &com, GF_OK); + GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[HYB In] Mapping WC Time %04d/%02d/%02d %02d:%02d:%02d and Hyb time "LLD"\n", + (now_tm->tm_year + 1900), (now_tm->tm_mon + 1), now_tm->tm_mday, now_tm->tm_hour, now_tm->tm_min, now_tm->tm_sec, + com.map_time.timestamp)); + } + } + + /*initialize clock*/ + init_time = gf_sys_clock(); + } + + time_to_wait = (u32)(init_time + ((u64)slh.compositionTimeStamp*1000)/FM_FAKE_PUSH_AUDIO_FREQ - gf_sys_clock()); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[HYB_IN] FM_FAKE_PUSH - %d ms before next AU\n", time_to_wait)); + if (time_to_wait > 0) { + if (time_to_wait > 1000) /*TODO: understand the big shifts when playing icecasts contents*/ + GF_LOG(GF_LOG_WARNING, GF_LOG_MODULE, ("[HYB_IN] FM_FAKE_PUSH - audio asked to sleep for %d ms\n", time_to_wait)); + gf_sleep(time_to_wait); + } + + e = GetData(self, &data, &data_size, &slh); + gf_term_on_sl_packet(self->owner, self->channel, data, data_size, &slh, e); + } + + self->state = HYB_STATE_STOPPED; + + return 0; +} + +/**********************************************************************************************************************/ + +static void audio_gen_stop(GF_HYBMEDIA *self) +{ + if (self->state >= 0) { /*only when playing*/ + self->state = HYB_STATE_STOP_REQ; + while (self->state != HYB_STATE_STOPPED) + gf_sleep(10); + } +} + +/**********************************************************************************************************************/ + +static GF_Err FM_FAKE_PUSH_Connect(GF_HYBMEDIA *self, GF_ClientService *service, const char *url) +{ + u32 i; + FM_FAKE_PUSH *priv; + + if (!self) + return GF_BAD_PARAM; + + if (!service) + return GF_BAD_PARAM; + + priv = (FM_FAKE_PUSH*)self->private_data; + if (!priv) + return GF_BAD_PARAM; + + self->owner = service; + + /*set audio preloaded data*/ + memset(self->private_data, 0, sizeof(FM_FAKE_PUSH)); + for (i=0; i<(FM_FAKE_PUSH_FRAME_LEN*8)/FM_FAKE_PUSH_BITS; i++) { + if (((2*i)/(FM_FAKE_PUSH_CHAN_NUM*100))%2) /*100Hz*/ + *((FM_FAKE_PUSH_TYPE*)((FM_FAKE_PUSH*)self->private_data)->buffer10+i) = 1 << (FM_FAKE_PUSH_BITS-1); + } + + assert(!priv->th); + priv->th = gf_th_new("HYB-FM fake audio generation thread"); + self->state = HYB_STATE_PAUSE; + gf_th_run(priv->th, audio_gen_th, self); + + return GF_OK; +} + +/**********************************************************************************************************************/ + +static GF_Err FM_FAKE_PUSH_Disconnect(GF_HYBMEDIA *self) +{ + FM_FAKE_PUSH *priv = (FM_FAKE_PUSH*)self->private_data; + + audio_gen_stop(self); + gf_th_del(priv->th); + priv->th = NULL; + + self->owner = NULL; + return GF_OK; +} + +/**********************************************************************************************************************/ + +static GF_Err FM_FAKE_PUSH_SetState(GF_HYBMEDIA *self, const GF_NET_CHAN_CMD state) +{ + switch(state) { + case GF_NET_CHAN_PLAY: + self->state = HYB_STATE_PLAYING; + break; + case GF_NET_CHAN_STOP: + audio_gen_stop(self); + break; + case GF_NET_CHAN_PAUSE: + self->state = HYB_STATE_PAUSE; + break; + case GF_NET_CHAN_RESUME: + self->state = HYB_STATE_PLAYING; + break; + default: + return GF_BAD_PARAM; + } + + return GF_OK; +} + +/**********************************************************************************************************************/ diff --git a/modules/hyb_in/fm_mmbtools.c b/modules/hyb_in/fm_mmbtools.c new file mode 100644 index 0000000..bf598fc --- /dev/null +++ b/modules/hyb_in/fm_mmbtools.c @@ -0,0 +1,104 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Romain Bouqueau + * Copyright (c) Telecom ParisTech 2010-20xx + * All rights reserved + * + * This file is part of GPAC / Hybrid Media input module + * + * 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. + * + */ + + +/*hybrid media interface implementation using MMB Tools from the Communication Research Center Canada (http://mmbtools.crc.ca/)*/ + +#include + +#if 0 + + +GF_HYBMEDIA master_fm_mmbtools = { +}; + + +typedef struct { + Bool clock_found_time; /*simulate the discovery of a RDS clock: arrives within the first minutes with a 100ms jitter*/ + + GF_Thread *fm_th; + volatile u32 fm_th_state; +} FM_MMBTOOLS; + + + +static Bool FM_MMBTOOLS_CanHandleURL(const char *url) +{ + if (!strnicmp(url, "fm://", 5)) + return 1; + + return 0; +} + +static GF_ObjectDescriptor* FM_MMBTOOLS_GetOD() +{ + + return od; +} + +static GF_Err HYB_FM_Close(GF_HYB_In *hyb_in) +{ + /*stop the audio_generation thread*/ + hyb_in->fm_th_state = HYB_STATE_STOPPING; + while (hyb_in->fm_th_state != HYB_STATE_STOPPED) + gf_sleep(10); + + return GF_OK; +} + +static GF_Err HYB_FM_Connect(GF_HYB_In *hyb_in, const char *url) +{ + FM_MMBTOOLS* audio_gen; + if (hyb_in->fm_thread) + return GF_ERR; + GF_SAFEALLOC(audio_gen, FM_MMBTOOLS); + hyb_in->fm_thread = gf_th_new("HYB-FM fake audio generation thread"); + gf_th_run(hyb_in->fm_thread, audio_gen_th, audio_gen); + + return GF_OK; +} + +static u32 audio_gen_th(void *par) +{ + FM_MMBTOOLS audio_gen = (FM_MMBTOOLS*) par; + + /*RDS clock discovery time*/ + clock_found_time = rand() % XXX; //radom in the 1st minute + + while (!audio_gen->state) /*FM_MMBTOOLS_STATE_RUNNING*/ + { + gf_sleep (remaining); + + if (clock > clock_found_time && ) { + gf_term_clock clock(); + } else { + gf_term_clock utc_clock(); + } + } + + audio_gen->state = FM_MMBTOOLS_STATE_STOPPED; +} + +#endif diff --git a/modules/hyb_in/hyb_in.c b/modules/hyb_in/hyb_in.c new file mode 100644 index 0000000..5500f55 --- /dev/null +++ b/modules/hyb_in/hyb_in.c @@ -0,0 +1,308 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Romain Bouqueau + * Copyright (c) Telecom ParisTech 2010-20xx + * All rights reserved + * + * This file is part of GPAC / Hybrid Media input module + * + * 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 "hyb_in.h" + +/*register by hand existing masters*/ +extern GF_HYBMEDIA master_fm_mmbtools; +extern GF_HYBMEDIA master_fm_fake_pull; +extern GF_HYBMEDIA master_fm_fake_push; + +GF_HYBMEDIA* hyb_masters[] = { + &master_fm_fake_pull, + &master_fm_fake_push, +#ifdef GPAC_ANDROID + &master_fm_mmbtools, +#endif +}; + +typedef struct { + /*GPAC Service object (i.e. how this module is seen by the terminal)*/ + GF_ClientService *service; + + /*This Hybrid media architecture assumes there is a master media*/ + GF_HYBMEDIA* master; + +} GF_HYB_In; + + +static u32 HYB_RegisterMimeTypes(const GF_InputService *plug) +{ + if (!plug) + return 0; + + return 1; +} + +static Bool HYB_CanHandleURL(GF_InputService *plug, const char *url) +{ + u32 i; + const size_t nb_masters = sizeof(hyb_masters) / sizeof(GF_HYBMEDIA*); + + for (i=0; iCanHandleURL(url)) + return 1; + } + + return 0; +} + +static GF_Err hybmedia_sanity_check(GF_HYBMEDIA *master) +{ + /*these checks need to be upgraded when the interface changes*/ + if (master->data_mode != HYB_PUSH && master->data_mode != HYB_PULL) + return GF_BAD_PARAM; + + if (!master->name) goto error_exit; + if (!master->CanHandleURL) goto error_exit; + if (!master->GetOD) goto error_exit; + if (!master->Connect) goto error_exit; + if (!master->Disconnect) goto error_exit; + + if (master->data_mode == HYB_PUSH) { + if (!master->SetState) goto error_exit; + } + + if (master->data_mode == HYB_PULL) { + if (!master->GetData) goto error_exit; + if (!master->ReleaseData) goto error_exit; + } + + return GF_OK; + +error_exit: + return GF_SERVICE_ERROR; +} + +static GF_Err HYB_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url) +{ + u32 i; + GF_Err e = GF_OK; + const size_t nb_masters = sizeof(hyb_masters) / sizeof(GF_HYBMEDIA*); + + GF_HYB_In *hyb_in = (GF_HYB_In*)plug->priv; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[HYB_IN] Received Connection request from service %p for %s\n", serv, url)); + + if (!hyb_in || !serv || !url) return GF_BAD_PARAM; + hyb_in->service = serv; + + /*choose the master service*/ + for (i=0; iCanHandleURL(url)) { + hyb_in->master = hyb_masters[i]; + break; + } + } + assert(hyb_in->master); + + /*sanity check about the master*/ + e = hybmedia_sanity_check(hyb_in->master); + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[HYB_IN] Error - object \"%s\" failed the sanity checks\n", hyb_in->master->name)); + gf_term_on_connect(hyb_in->service, NULL, e); + return e; + } + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[HYB_IN] Selected master object \"%s\" for URL: %s\n", hyb_in->master->name, url)); + + /*connect the master*/ + e = hyb_in->master->Connect(hyb_in->master, hyb_in->service, url); + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[HYB_IN] Error - cannot connect service, wrong URL %s\n", url)); + gf_term_on_connect(hyb_in->service, NULL, GF_BAD_PARAM); + return e; + } + gf_term_on_connect(hyb_in->service, NULL, GF_OK); + gf_term_add_media(hyb_in->service, (GF_Descriptor*)hyb_in->master->GetOD(), 0); + + return GF_OK; +} + +static GF_Err HYB_CloseService(GF_InputService *plug) +{ + GF_Err e; + GF_HYB_In *hyb_in = (GF_HYB_In*)plug->priv; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[HYB_IN] Received Close Service (%p) request from terminal\n", ((GF_HYB_In*)plug->priv)->service)); + + /*force to stop and disconnect the master*/ + hyb_in->master->SetState(hyb_in->master, GF_NET_CHAN_STOP); + e = hyb_in->master->Disconnect(hyb_in->master); + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[HYB_IN] Error - cannot disconnect service %p\n", hyb_in->service)); + gf_term_on_connect(hyb_in->service, NULL, GF_BAD_PARAM); + return e; + } + + return GF_OK; +} + +static GF_Descriptor *HYB_GetServiceDesc(GF_InputService *plug, u32 expect_type, const char *sub_url) +{ + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[HYB_IN] Received Service Description request from terminal for %s\n", sub_url)); + + return NULL; +} + +static GF_Err HYB_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, const char *url, Bool upstream) +{ + GF_HYB_In *hyb_in; + GF_HYBMEDIA *master; + + if (!plug || !plug->priv) + return GF_SERVICE_ERROR; + + hyb_in = (GF_HYB_In*)plug->priv; + master = (GF_HYBMEDIA*)hyb_in->master; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[HYB_IN] Received Channel Connection request from service %p for %s\n", channel, url)); + + master->channel = channel; + gf_term_on_connect(hyb_in->service, channel, GF_OK); + + return GF_OK; +} + +static GF_Err HYB_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) +{ + GF_HYB_In *hyb_in = (GF_HYB_In*)plug->priv; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[HYB_IN] Received Channel Disconnect Service (%p) request from terminal\n", hyb_in->service)); + + hyb_in->master->channel = NULL; + gf_term_on_disconnect(hyb_in->service, NULL, GF_OK); + + return GF_OK; +} + +static GF_Err HYB_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) +{ + GF_HYB_In *hyb_in = (GF_HYB_In*)plug->priv; + + switch (com->command_type) { + case GF_NET_CHAN_SET_SPEED: + /*not implemented for push mode*/ + assert(hyb_in->master->data_mode == HYB_PULL); + return GF_OK; + case GF_NET_CHAN_INTERACTIVE: + return GF_NOT_SUPPORTED; + case GF_NET_CHAN_BUFFER: + com->buffer.max = com->buffer.min = 0; + return GF_OK; + case GF_NET_CHAN_DURATION: + com->duration.duration = 0; + return GF_OK; + case GF_NET_CHAN_PLAY: + case GF_NET_CHAN_STOP: + case GF_NET_CHAN_PAUSE: + case GF_NET_CHAN_RESUME: + if (hyb_in->master->data_mode == HYB_PUSH) + return hyb_in->master->SetState(hyb_in->master, com->command_type); + return GF_OK; + case GF_NET_CHAN_SET_PULL: + if (hyb_in->master->data_mode == HYB_PULL) + return GF_OK; + else + return GF_NOT_SUPPORTED; /*we're in push mode*/ + } + + return GF_OK; +} + +static Bool HYB_CanHandleURLInService(GF_InputService *plug, const char *url) +{ + return 0; +} + +static GF_Err HYB_ChannelGetSLP(GF_InputService *plug, LPNETCHANNEL channel, char **out_data_ptr, u32 *out_data_size, GF_SLHeader *out_sl_hdr, Bool *sl_compressed, GF_Err *out_reception_status, Bool *is_new_data) +{ + GF_HYB_In *hyb_in = (GF_HYB_In*)plug->priv; + assert(hyb_in->master->data_mode == HYB_PULL && hyb_in->master->GetData && hyb_in->master->ReleaseData); + + assert(((GF_HYB_In*)plug->priv)->master->channel == channel); + hyb_in->master->GetData(hyb_in->master, out_data_ptr, out_data_size, out_sl_hdr); + *sl_compressed = 0; + *out_reception_status = GF_OK; + *is_new_data = 1; + return GF_OK; +} + +static GF_Err HYB_ChannelReleaseSLP(GF_InputService *plug, LPNETCHANNEL channel) +{ + GF_HYB_In *hyb_in = (GF_HYB_In*)plug->priv; + assert(((GF_HYB_In*)plug->priv)->master->channel == channel); + return GF_OK; +} + +GF_EXPORT +const u32 *QueryInterfaces() +{ + static u32 si [] = { + GF_NET_CLIENT_INTERFACE, + 0 + }; + return si; +} + +GF_EXPORT +GF_BaseInterface *LoadInterface(u32 InterfaceType) +{ + GF_HYB_In *hyb_in; + GF_InputService *plug; + if (InterfaceType != GF_NET_CLIENT_INTERFACE) return NULL; + + GF_SAFEALLOC(plug, GF_InputService); + GF_REGISTER_MODULE_INTERFACE(plug, GF_NET_CLIENT_INTERFACE, "GPAC HYBRID MEDIA Loader", "gpac distribution") + plug->RegisterMimeTypes= HYB_RegisterMimeTypes; + plug->CanHandleURL= HYB_CanHandleURL; + plug->ConnectService= HYB_ConnectService; + plug->CloseService= HYB_CloseService; + plug->GetServiceDescriptor= HYB_GetServiceDesc; + plug->ConnectChannel= HYB_ConnectChannel; + plug->DisconnectChannel= HYB_DisconnectChannel; + plug->ServiceCommand= HYB_ServiceCommand; + plug->CanHandleURLInService=HYB_CanHandleURLInService; + plug->ChannelGetSLP= HYB_ChannelGetSLP; + plug->ChannelReleaseSLP= HYB_ChannelReleaseSLP; + + GF_SAFEALLOC(hyb_in, GF_HYB_In); + plug->priv = hyb_in; + + return (GF_BaseInterface *)plug; +} + +GF_EXPORT +void ShutdownInterface(GF_BaseInterface *ifce) +{ + GF_LOG(GF_LOG_MEDIA, GF_LOG_ERROR, ("DeleteLoaderInterface %p: 1\n", ifce)); + if (ifce->InterfaceType == GF_NET_CLIENT_INTERFACE) { + GF_InputService *plug = (GF_InputService*)ifce; + GF_HYB_In *hyb_in = (GF_HYB_In*)plug->priv; + gf_free(hyb_in); + plug->priv = NULL; + gf_free(plug); + GF_LOG(GF_LOG_MEDIA, GF_LOG_ERROR, ("DeleteLoaderInterface %p: 2\n", ifce)); + } +} diff --git a/modules/hyb_in/hyb_in.h b/modules/hyb_in/hyb_in.h new file mode 100644 index 0000000..1c60ed6 --- /dev/null +++ b/modules/hyb_in/hyb_in.h @@ -0,0 +1,96 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Romain Bouqueau + * Copyright (c) Telecom ParisTech 2010-20xx + * All rights reserved + * + * This file is part of GPAC / Hybrid Media input module + * + * 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. + * + */ + +#ifndef _HYB_IN_H +#define _HYB_IN_H + +#include +#include +#include + + +typedef enum { + HYB_STATE_STOPPED = -2, /*thread received HYB_STATE_STOP_REQ and stopped*/ + HYB_STATE_STOP_REQ = -1, /*user asked to stop*/ + HYB_STATE_PAUSE = 0, /*default state*/ + //HYB_STATE_PLAY_REQ = 1, /*user asked to play*/ + HYB_STATE_PLAYING = 2, /*thread received HYB_STATE_PLAY_REQ and has started playing*/ +} HYB_STATE; + +typedef enum { + HYB_PUSH = 0, /*threaded*/ + HYB_PULL, /*not threaded*/ +} HYB_DATA_MODE; + +/*base structure for media hybridation*/ +typedef struct s_GF_HYBMEDIA { + + /*object description*/ + const char* name; + + /* *** static methods *** */ + + /*is url handled by this service?*/ + Bool (*CanHandleURL)(const char *url); + + /*retrieve object descriptor*/ + GF_ObjectDescriptor* (*GetOD)(void); + + + /* *** other methods *** */ + + /*create/destroy the object and all its data*/ + GF_Err (*Connect) (struct s_GF_HYBMEDIA *self, GF_ClientService *service, const char *url); + GF_Err (*Disconnect)(struct s_GF_HYBMEDIA *self); + + /*request state from */ + GF_Err (*SetState)(struct s_GF_HYBMEDIA *self, const GF_NET_CHAN_CMD state); + + /*in case data retrieval paradigm is pull these two functions shall not be NULL*/ + GF_Err (*GetData) (struct s_GF_HYBMEDIA *self, char **out_data_ptr, u32 *out_data_size, GF_SLHeader *out_sl_hdr); /*only available when data_mode is pull*/ + GF_Err (*ReleaseData)(struct s_GF_HYBMEDIA *self); /*only available when data_mode is pull*/ + + + /* *** statically initialized data *** */ + + /*data retrieval mode: HYB_PUSH or HYB_PULL*/ + HYB_DATA_MODE data_mode; + + /*pivate data which type depends on dynamic considerations*/ + void *private_data; + + + /* *** dynamically initialized data *** */ + + /*object state: play/stop/pause/...*/ + HYB_STATE state; + + /*object carrying us (needed to communicate with the player)*/ + GF_ClientService *owner; + LPNETCHANNEL channel; + +} GF_HYBMEDIA; + +#endif diff --git a/modules/img_in/Makefile b/modules/img_in/Makefile index 2cd7f68..f085be1 100644 --- a/modules/img_in/Makefile +++ b/modules/img_in/Makefile @@ -60,7 +60,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS) ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_img_in-static.so $(OBJS) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_img_in-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS) endif diff --git a/modules/img_in/img_dec.c b/modules/img_in/img_dec.c index 323a7c9..69c5ddc 100644 --- a/modules/img_in/img_dec.c +++ b/modules/img_in/img_dec.c @@ -26,39 +26,44 @@ #include "img_in.h" -static Bool DEC_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, u8 PL) +static u32 DEC_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, u8 PL) { - if (StreamType != GF_STREAM_VISUAL) return 0; + if (StreamType != GF_STREAM_VISUAL) return GF_CODEC_NOT_SUPPORTED; /*media type query*/ - if (!esd) return 1; + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; switch (esd->decoderConfig->objectTypeIndication) { #ifdef GPAC_HAS_PNG case GPAC_OTI_IMAGE_PNG: - return NewPNGDec(dec); + if (NewPNGDec(dec)) return GF_CODEC_SUPPORTED; + return GF_CODEC_NOT_SUPPORTED; #endif #ifdef GPAC_HAS_JPEG case GPAC_OTI_IMAGE_JPEG: - return NewJPEGDec(dec); + if (NewJPEGDec(dec)) return GF_CODEC_SUPPORTED; + return GF_CODEC_NOT_SUPPORTED; #endif #ifdef GPAC_HAS_JP2 case GPAC_OTI_IMAGE_JPEG_2000: - return NewJP2Dec(dec); + if (NewJP2Dec(dec)) return GF_CODEC_SUPPORTED; + return GF_CODEC_NOT_SUPPORTED; #endif case GPAC_BMP_OTI: - return NewBMPDec(dec); + if (NewBMPDec(dec)) return GF_CODEC_SUPPORTED; + return GF_CODEC_NOT_SUPPORTED; default: #ifdef GPAC_HAS_JP2 { char *dsi = esd->decoderConfig->decoderSpecificInfo ? esd->decoderConfig->decoderSpecificInfo->data : NULL; if (dsi && (dsi[0]=='m') && (dsi[1]=='j') && (dsi[2]=='p') && (dsi[3]=='2')) - return NewJP2Dec(dec); + if (NewJP2Dec(dec)) return GF_CODEC_SUPPORTED; + return GF_CODEC_NOT_SUPPORTED; } #endif - return 0; + return GF_CODEC_NOT_SUPPORTED; } - return 0; + return GF_CODEC_NOT_SUPPORTED; } diff --git a/modules/img_in/jp2_dec.c b/modules/img_in/jp2_dec.c index ca93728..40a0398 100644 --- a/modules/img_in/jp2_dec.c +++ b/modules/img_in/jp2_dec.c @@ -344,7 +344,11 @@ static GF_Err JP2_ProcessData(GF_MediaDecoder *ifcg, static const char *JP2_GetCodecName(GF_BaseDecoder *dec) { +#ifdef OPENJPEG_VERSION return "OpenJPEG "OPENJPEG_VERSION ; +#else + return "OpenJPEG" ; +#endif } diff --git a/modules/ismacryp/Makefile b/modules/ismacryp/Makefile index 1a4e72b..d83c52d 100644 --- a/modules/ismacryp/Makefile +++ b/modules/ismacryp/Makefile @@ -30,7 +30,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_ismacryp-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_ismacryp-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static endif diff --git a/modules/isom_in/Makefile b/modules/isom_in/Makefile index 6138688..df8f591 100644 --- a/modules/isom_in/Makefile +++ b/modules/isom_in/Makefile @@ -31,7 +31,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(EXTRALIBS) ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_isom_in-static.so $(OBJS) -L../../bin/gcc -lgpac_static $(EXTRALIBS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_isom_in-static.$(DYN_LIB_SUFFIX) $(OBJS) -L../../bin/gcc -lgpac_static $(EXTRALIBS) endif diff --git a/modules/isom_in/load.c b/modules/isom_in/load.c index eb9d3f1..26c05d9 100644 --- a/modules/isom_in/load.c +++ b/modules/isom_in/load.c @@ -108,7 +108,8 @@ void isor_declare_objects(ISOMReader *read) esd = gf_media_map_esd(read->mov, i+1); if (esd) { od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG); - od->objectDescriptorID = esd->ESID; + od->service_ifce = read->input; + od->objectDescriptorID = 0; if (!ocr_es_id) ocr_es_id = esd->ESID; esd->OCRESID = ocr_es_id; gf_list_add(od->ESDescriptors, esd); @@ -119,24 +120,46 @@ void isor_declare_objects(ISOMReader *read) if (gf_isom_apple_get_tag(read->mov, GF_ISOM_ITUNE_COVER_ART, &tag, &tlen)==GF_OK) { const char *cdir = gf_modules_get_option((GF_BaseInterface *)gf_term_get_service_interface(read->service), "General", "CacheDirectory"); if (cdir) { - char szName[GF_MAX_PATH], *sep; + char szName[GF_MAX_PATH]; + const char *sep; FILE *t; sep = strrchr(gf_isom_get_filename(read->mov), '\\'); if (!sep) sep = strrchr(gf_isom_get_filename(read->mov), '/'); + if (!sep) sep = gf_isom_get_filename(read->mov); if ((cdir[strlen(cdir)-1] != '\\') && (cdir[strlen(cdir)-1] != '/')) { sprintf(szName, "%s/%s_cover.%s", cdir, sep, (tlen & 0x80000000) ? "png" : "jpg"); } else { sprintf(szName, "%s%s_cover.%s", cdir, sep, (tlen & 0x80000000) ? "png" : "jpg"); } + t = gf_f64_open(szName, "wb"); + if (t) { + Bool isom_contains_video = 0; + + /*write cover data*/ + assert(!(tlen & 0x80000000)); fwrite(tag, tlen & 0x7FFFFFFF, 1, t); fclose(t); - od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG); - od->objectDescriptorID = 1050; - od->URLString = gf_strdup(szName); - gf_term_add_media(read->service, (GF_Descriptor*)od, 1); + + /*don't display cover art when video is present*/ + for (i=0; imov); i++) { + if (!gf_isom_is_track_enabled(read->mov, i+1)) + continue; + if (gf_isom_get_media_type(read->mov, i+1) == GF_ISOM_MEDIA_VISUAL) { + isom_contains_video = 1; + break; + } + } + + if (!isom_contains_video) { + od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG); + od->service_ifce = read->input; + od->objectDescriptorID = GF_MEDIA_EXTERNAL_ID; + od->URLString = gf_strdup(szName); + gf_term_add_media(read->service, (GF_Descriptor*)od, 1); + } } } } diff --git a/modules/isom_in/read.c b/modules/isom_in/read.c index 39a5434..05b39f2 100644 --- a/modules/isom_in/read.c +++ b/modules/isom_in/read.c @@ -643,7 +643,7 @@ GF_Err ISOR_ChannelGetSLP(GF_InputService *plug, LPNETCHANNEL channel, char **ou if (!ch->sample) { /*get sample*/ isor_reader_get_sample(ch); - *is_new_data = 1; + *is_new_data = ch->sample ? 1 : 0; } if (ch->sample) { diff --git a/modules/isom_in/read_ch.c b/modules/isom_in/read_ch.c index 516a7a5..801a02b 100644 --- a/modules/isom_in/read_ch.c +++ b/modules/isom_in/read_ch.c @@ -104,6 +104,7 @@ static void check_segment_switch(ISOMReader *read) { GF_NetworkCommand param; u32 i, count; + GF_Err e; if (!read->frag_type) return; if (!read->input->query_proxy) return; @@ -111,23 +112,30 @@ static void check_segment_switch(ISOMReader *read) for (i=0; ichannels, i); /*check all playing channels are waiting for next segment*/ - if (ch->is_playing && !ch->wait_for_segment_switch) return; + if (ch->is_playing && !ch->wait_for_segment_switch) { + return; + } } /*close current segment*/ gf_isom_release_segment(read->mov, 1); + GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[IsoMedia] Done playing segment - querying new one\n")); /*update current fragment if any*/ param.command_type = GF_NET_SERVICE_QUERY_NEXT; if ((read->input->query_proxy(read->input, ¶m)==GF_OK) && param.url_query.next_url){ - gf_isom_open_segment(read->mov, param.url_query.next_url); + + e = gf_isom_open_segment(read->mov, param.url_query.next_url); + GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[IsoMedia] playing new segment %s: %s\n", param.url_query.next_url, gf_error_to_string(e) )); for (i=0; ichannels, i); ch->wait_for_segment_switch = 0; + GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[IsoMedia] Track %d - cur sample %d - new sample count %d\n", ch->track, ch->sample_num, gf_isom_get_sample_count(ch->owner->mov, ch->track) )); } } else { /*consider we are done*/ read->frag_type = 2; + GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[IsoMedia] No more segments - done playing file\n")); } } @@ -190,10 +198,6 @@ fetch_next: ch->sample_num++; goto fetch_next; } - /*if sample cannot be found and file is fragmented, rewind sample*/ - if (!ch->sample && ch->owner->frag_type) { - ch->sample_num--; - } } if (!ch->sample) { /*incomplete file - check if we're still downloading or not*/ @@ -207,11 +211,19 @@ fetch_next: } } else if (!ch->sample_num || (ch->sample_num >= gf_isom_get_sample_count(ch->owner->mov, ch->track))) { if (ch->owner->frag_type==1) { + if (!ch->wait_for_segment_switch) { + ch->wait_for_segment_switch = 1; + GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[IsoMedia] Track #%d end of segment reached - waiting for sample %d - current count %d\n", ch->track, ch->sample_num, gf_isom_get_sample_count(ch->owner->mov, ch->track) )); + } + /*if sample cannot be found and file is fragmented, rewind sample*/ + if (ch->sample_num) ch->sample_num--; ch->last_state = GF_OK; - ch->wait_for_segment_switch = 1; } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[IsoMedia] Track #%d end of stream reached\n", ch->track)); ch->last_state = GF_EOS; } + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[IsoMedia] Track #%d fail to fetch sample %d / %d: %s\n", ch->track, ch->sample_num, gf_isom_get_sample_count(ch->owner->mov, ch->track), gf_error_to_string(gf_isom_last_error(ch->owner->mov)) )); } if (ch->wait_for_segment_switch) check_segment_switch(ch->owner); return; diff --git a/modules/laser_dec/Makefile b/modules/laser_dec/Makefile index ac6ba4d..f457f73 100644 --- a/modules/laser_dec/Makefile +++ b/modules/laser_dec/Makefile @@ -31,7 +31,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_laser_dec-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_laser_dec-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static endif diff --git a/modules/laser_dec/laser_dec.c b/modules/laser_dec/laser_dec.c index d87f5e0..5469af5 100644 --- a/modules/laser_dec/laser_dec.c +++ b/modules/laser_dec/laser_dec.c @@ -105,13 +105,13 @@ static GF_Err LSR_ProcessData(GF_SceneDecoder*plug, const char *inBuffer, u32 in return e; } -Bool LSR_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, GF_ESD *esd, u8 PL) +static u32 LSR_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, GF_ESD *esd, u8 PL) { - if (StreamType!=GF_STREAM_SCENE) return 0; + if (StreamType!=GF_STREAM_SCENE) return GF_CODEC_NOT_SUPPORTED; /*media type query*/ - if (!esd) return 1; - if (esd->decoderConfig->objectTypeIndication == GPAC_OTI_SCENE_LASER) return 1; - return 0; + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; + if (esd->decoderConfig->objectTypeIndication == GPAC_OTI_SCENE_LASER) return GF_CODEC_SUPPORTED; + return GF_CODEC_NOT_SUPPORTED; } diff --git a/modules/libplayer/Makefile b/modules/libplayer/Makefile index b4042f9..3266c90 100644 --- a/modules/libplayer/Makefile +++ b/modules/libplayer/Makefile @@ -1,53 +1,53 @@ -include ../../config.mak - -vpath %.c $(SRC_PATH)/modules/libplayer - -CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include" - -ifeq ($(DEBUGBUILD), yes) -CFLAGS+=-g -LDFLAGS+=-g -endif - -ifeq ($(GPROFBUILD), yes) -CFLAGS+=-pg -LDFLAGS+=-pg -endif - -#common obj -OBJS= libplayer.o - -SRCS := $(OBJS:.o=.c) - -LIB=gm_libplayer.$(DYN_LIB_SUFFIX) - - -all: $(LIB) - - -$(LIB): $(OBJS) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< - - -clean: - rm -f $(OBJS) ../../bin/gcc/$(LIB) - -dep: depend - -depend: - rm -f .depend - $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend - -distclean: clean - rm -f Makefile.bak .depend - - - -# include dependency files if they exist -# -ifneq ($(wildcard .depend),) -include .depend -endif +include ../../config.mak + +vpath %.c $(SRC_PATH)/modules/libplayer + +CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include" + +ifeq ($(DEBUGBUILD), yes) +CFLAGS+=-g +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD), yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + +#common obj +OBJS= libplayer.o + +SRCS := $(OBJS:.o=.c) + +LIB=gm_libplayer.$(DYN_LIB_SUFFIX) + + +all: $(LIB) + + +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac -lplayer + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + + +clean: + rm -f $(OBJS) ../../bin/gcc/$(LIB) + +dep: depend + +depend: + rm -f .depend + $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend + +distclean: clean + rm -f Makefile.bak .depend + + + +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/modules/libplayer/libplayer.c b/modules/libplayer/libplayer.c index d240a41..67276d4 100644 --- a/modules/libplayer/libplayer.c +++ b/modules/libplayer/libplayer.c @@ -10,15 +10,15 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -29,7 +29,7 @@ #include #include -#define TEST_LIBPLAYER +//#define TEST_LIBPLAYER #ifndef TEST_LIBPLAYER @@ -42,16 +42,20 @@ typedef s32 off_t; #include "player.h" - #endif +static int libplayer_id = 0; typedef struct { /*the service we're responsible for*/ GF_ClientService *service; + u32 init; u32 state; - + u32 player_id; + u32 width; + u32 height; + char *url; #ifndef TEST_LIBPLAYER player_t *player; #endif @@ -60,7 +64,7 @@ typedef struct static const char * LIBPLAYER_MIME_TYPES[] = { - "video/x-mpeg", "mpg mpeg mp2 mpa mpe mpv2", "MPEG 1/2 Movies", + "video/x-mpeg", "mpg mpeg mp2 mpa mpe mpv2 ts", "MPEG 1/2 Movies", "video/x-mpeg-systems", "mpg mpeg mp2 mpa mpe mpv2", "MPEG 1/2 Movies", "audio/basic", "snd au", "Basic Audio", "audio/x-wav", "wav", "WAV Audio", @@ -74,11 +78,8 @@ static const char * LIBPLAYER_MIME_TYPES[] = { "video/H263", "h263 263", "H263 Video", "video/H264", "h264 264", "H264 Video", "video/MPEG4", "cmp", "MPEG-4 Video", -/* We let ffmpeg handle mov because some QT files with uncompressed or adpcm audio use 1 audio sample - per MP4 sample which is a killer for our MP4 lib, whereas ffmpeg handles these as complete audio chunks - moreover ffmpeg handles cmov, we don't */ + "video/mp4", "mp4", "MPEG-4 Movie", "video/quicktime", "mov qt", "QuickTime Movies", -/* Supported by latest versions of FFMPEG */ "video/webm", "webm", "Google WebM Movies", "audio/webm", "webm", "Google WebM Music", NULL @@ -105,7 +106,7 @@ Bool LIBPLAYER_CanHandleURL(GF_InputService *plug, const char *url) if (!strnicmp(url, "rtsp://", 7)) return 0; sExt++; - cgi_par = strchr(sExt, '?'); + cgi_par = strchr(sExt, '?'); if (cgi_par) cgi_par[0] = 0; for (i = 0 ; LIBPLAYER_MIME_TYPES[i] ; i+=3) { @@ -124,13 +125,19 @@ Bool LIBPLAYER_CanHandleURL(GF_InputService *plug, const char *url) static int on_libplayer_event(player_event_t e, void *data) { - fprintf(stdout, "Received event %d\n", e); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerEvent] Received event %d\n", e)); - switch (e) { + switch (e) { + case PLAYER_EVENT_PLAYBACK_FINISHED: + player_playback_stop(data); + player_playback_start(data); + break; case PLAYER_EVENT_FE_HAS_LOCK: break; case PLAYER_EVENT_FE_TIMEDOUT: break; + case PLAYER_EVENT_VIDEO_PICTURE: + break; default: break; } @@ -138,6 +145,8 @@ static int on_libplayer_event(player_event_t e, void *data) return 0; } + + #endif GF_Err LIBPLAYER_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url) @@ -147,28 +156,42 @@ GF_Err LIBPLAYER_ConnectService(GF_InputService *plug, GF_ClientService *serv, c mrl_t *mrl = NULL; #endif + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[LibPlayerIN] Connecting\n")); + if (!read || !serv || !url) return GF_BAD_PARAM; + if (!strnicmp(url, "libplayer://", 12)) url+=12; + + if (!read->init) { + read->init=1; + /* libplayer init with default width/height */ + read->width = 80; + read->height = 20; + read->url = url; + read->player_id = libplayer_id; #ifndef TEST_LIBPLAYER - if (!read->player) { - /* libplayer init */ - read->player = player_init(PLAYER_TYPE_DUMMY, PLAYER_AO_AUTO, PLAYER_VO_AUTO, PLAYER_MSG_ERROR, 0, on_libplayer_event); + read->player = player_init(PLAYER_TYPE_DUMMY, PLAYER_AO_AUTO, PLAYER_VO_AUTO, PLAYER_MSG_INFO, read->player_id, on_libplayer_event); + if (!read->player) { - GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[LibPlayerIN] Failed to instanciate libplayer\n")); + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[LibPlayerIN] Failed to instanciate libplayer instance %d\n", read->player_id)); gf_term_on_connect(serv, NULL, GF_REMOTE_SERVICE_ERROR); return GF_OK; } +#endif + libplayer_id++; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerIN] Opening URL %s for Player instance %d\n", url, read->player_id)); } - + +#ifndef TEST_LIBPLAYER mrl = NULL; if (!strnicmp(url, "dvb://", 6)) { - } + } else if (!strnicmp(url, "file://", 7) || !strstr(url, "://")) { mrl_resource_local_args_t *mrl_args; mrl_args = calloc(1, sizeof(mrl_resource_local_args_t)); if (!strnicmp(url, "file://", 7)) { mrl_args->location = strdup(url + 7); - } else { + } else { mrl_args->location = strdup(url); } mrl = mrl_new (read->player, MRL_RESOURCE_FILE, mrl_args); @@ -183,8 +206,8 @@ GF_Err LIBPLAYER_ConnectService(GF_InputService *plug, GF_ClientService *serv, c } player_mrl_set(read->player, mrl); -#endif +#endif read->state = 0; read->service = serv; @@ -196,35 +219,42 @@ GF_Err LIBPLAYER_ConnectService(GF_InputService *plug, GF_ClientService *serv, c { GF_ESD *esd; GF_ObjectDescriptor *od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG); - od->objectDescriptorID = 1; - + od->objectDescriptorID = 1+read->player_id; + esd = gf_odf_desc_esd_new(0); - esd->ESID = 1; + esd->ESID = 1+read->player_id; esd->slConfig->timestampResolution = 1000; esd->decoderConfig->streamType = GF_STREAM_PRIVATE_MEDIA; esd->decoderConfig->objectTypeIndication = GPAC_OTI_PRIVATE_MEDIA_LIBPLAYER; #ifndef TEST_LIBPLAYER - esd->decoderConfig->decoderSpecificInfo->data = read->player; + esd->decoderConfig->decoderSpecificInfo->data = read; #endif gf_list_add(od->ESDescriptors, esd); gf_term_add_media(read->service, (GF_Descriptor*)od, 0); } - return GF_OK; } GF_Err LIBPLAYER_CloseService(GF_InputService *plug) { LibPlayerIn *read = (LibPlayerIn *) plug->priv; + #ifndef TEST_LIBPLAYER - player_playback_stop(read->player); - player_uninit(read->player); - read->player = NULL; + player_playback_stop(read->player); + printf("[LibPlayerIN]player_playback_stop for instance %d\n", read->player_id); + player_uninit(read->player); + printf("[LibPlayerIN]player_uninit for instance %d\n", read->player_id); + read->player = NULL; + libplayer_id--; + + #endif - read->state = 0; + read->state = 0; + gf_term_on_disconnect(read->service, NULL, GF_OK); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerIn] Closing libplayer instance %d\n", read->player_id)); return GF_OK; } @@ -238,20 +268,24 @@ static GF_Descriptor *LIBPLAYER_GetServiceDesc(GF_InputService *plug, u32 expect GF_Err LIBPLAYER_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) { LibPlayerIn *read = (LibPlayerIn *) plug->priv; - + unsigned long prop = 0; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerIN] ServiceCommand for instance %d, read->state=%d\n", read->player_id, read->state)); if (!com->base.on_channel) return GF_NOT_SUPPORTED; + if (com->command_type==GF_NET_SERVICE_HAS_AUDIO) return GF_NOT_SUPPORTED; + switch (com->command_type) { case GF_NET_CHAN_SET_PULL: return GF_NOT_SUPPORTED; case GF_NET_CHAN_INTERACTIVE: return GF_OK; /*since data is file-based, no padding is needed (decoder plugin will handle it itself)*/ - case GF_NET_CHAN_SET_PADDING: return GF_OK; + case GF_NET_CHAN_SET_PADDING: return GF_OK; case GF_NET_CHAN_BUFFER: + return GF_OK; com->buffer.max = com->buffer.min = 0; return GF_OK; case GF_NET_CHAN_DURATION: /*this module is not made for updates, use undefined duration*/ - com->duration.duration = 0; + com->duration.duration = -1; return GF_OK; case GF_NET_CHAN_PLAY: if (read->state==0) { @@ -259,6 +293,7 @@ GF_Err LIBPLAYER_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) player_playback_start(read->player); #endif read->state = 1; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerIN] Starting playback for instance %d\n", read->player_id)); } return GF_OK; case GF_NET_CHAN_STOP: @@ -267,9 +302,10 @@ GF_Err LIBPLAYER_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) player_playback_pause(read->player); #endif read->state = 0; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerIN] Stopping playback for instance %d\n", read->player_id)); } return GF_OK; - case GF_NET_CHAN_CONFIG: return GF_OK; + case GF_NET_CHAN_CONFIG: return GF_OK; case GF_NET_CHAN_GET_DSI: com->get_dsi.dsi = NULL; com->get_dsi.dsi_len = 0; @@ -282,9 +318,9 @@ GF_Err LIBPLAYER_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, con { u32 ESID; LibPlayerIn *read = (LibPlayerIn *) plug->priv; - sscanf(url, "ES_ID=%ud", &ESID); - if (ESID != 1) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerIN] instance %d connect channel %d\n", read->player_id, ESID)); + if (ESID != 1+read->player_id) { gf_term_on_connect(read->service, channel, GF_STREAM_NOT_FOUND); } else { gf_term_on_connect(read->service, channel, GF_OK); @@ -295,6 +331,7 @@ GF_Err LIBPLAYER_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, con GF_Err LIBPLAYER_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) { LibPlayerIn *read = (LibPlayerIn *) plug->priv; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerIN] instance %d disconnect channel\n", read->player_id)); gf_term_on_disconnect(read->service, channel, GF_OK); return GF_OK; } @@ -308,48 +345,57 @@ Bool LIBPLAYER_CanHandleURLInService(GF_InputService *plug, const char *url) static GF_Err LIBPLAYER_AttachStream(GF_BaseDecoder *dec, GF_ESD *esd) { - if (esd->ESID!=1) return GF_BAD_PARAM; + LibPlayerIn *read; + if (dec->privateStack) return GF_BAD_PARAM; if (!esd->decoderConfig->decoderSpecificInfo) return GF_BAD_PARAM; -#ifndef TEST_LIBPLAYER if (!esd->decoderConfig->decoderSpecificInfo->data) return GF_BAD_PARAM; - dec->privateStack = esd->decoderConfig->decoderSpecificInfo->data; -#endif + read = (LibPlayerIn *) esd->decoderConfig->decoderSpecificInfo->data; + if (esd->ESID!=1+read->player_id) return GF_BAD_PARAM; + dec->privateStack = read; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerDEC] AttachStream for instance %d\n", read->player_id)); esd->decoderConfig->decoderSpecificInfo->data = NULL; return GF_OK; } static GF_Err LIBPLAYER_DetachStream(GF_BaseDecoder *dec, u16 ES_ID) { + LibPlayerIn *player = dec->privateStack; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerDEC] DetachStream for instance %d\n", player ? player->player_id : -1)); dec->privateStack = NULL; return GF_OK; } static GF_Err LIBPLAYER_GetCapabilities(GF_BaseDecoder *dec, GF_CodecCapability *capability) { + LibPlayerIn *read = dec->privateStack; + //GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerDEC] GetCapabilities\n")); switch (capability->CapCode) { case GF_CODEC_WIDTH: - capability->cap.valueInt = 320; + capability->cap.valueInt = read->width; break; case GF_CODEC_HEIGHT: - capability->cap.valueInt = 240; + capability->cap.valueInt = read->height; break; } return GF_OK; } static GF_Err LIBPLAYER_SetCapabilities(GF_BaseDecoder *dec, GF_CodecCapability capability) { - return GF_OK; + return GF_NOT_SUPPORTED; } -static Bool LIBPLAYER_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, u8 PL) +static u32 LIBPLAYER_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, u8 PL) { - if (StreamType!=GF_STREAM_PRIVATE_MEDIA) return 0; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerDEC] CanHandleStream\n")); + if (StreamType!=GF_STREAM_PRIVATE_MEDIA) return GF_CODEC_NOT_SUPPORTED; /*don't reply to media type queries*/ - if (!esd) return 0; - if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_PRIVATE_MEDIA_LIBPLAYER) return 1; - return 0; + if (!esd) return GF_CODEC_NOT_SUPPORTED; + if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_PRIVATE_MEDIA_LIBPLAYER) return GF_CODEC_SUPPORTED; + return GF_CODEC_NOT_SUPPORTED; } static const char *LIBPLAYER_GetName(GF_BaseDecoder *dec) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerDEC] GetName\n")); return "LibPlayer decoder"; } @@ -357,28 +403,43 @@ static GF_Err LIBPLAYER_Control(GF_PrivateMediaDecoder *dec, Bool mute, GF_Windo { #ifndef TEST_LIBPLAYER video_rect_t in, out; - player_t *player = dec->privateStack; - - if (!player) return GF_OK; - - in.x = src->x; - in.y = src->y; - in.w = src->w; - in.h = src->h; - out.x = dst->x; - out.y = dst->y; - out.w = dst->w; - out.h = dst->h; - player_video_io_windows_set(player, &in, &out); -#endif + LibPlayerIn *read = dec->privateStack; + u32 width, height; + + if (!read) return GF_OK; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerDEC] Control instance %d\n",read->player_id)); -// fprintf(stdout, "Repositioning video src %d %d %d %d - dest %d %d %d %d\n", src->x, src->y, src->w, src->h, dst->x, dst->y, dst->w, dst->h); + width = mrl_get_property(read->player, NULL, MRL_PROPERTY_VIDEO_WIDTH); + height = mrl_get_property(read->player, NULL, MRL_PROPERTY_VIDEO_HEIGHT); + + if((width != read->width) || (height != read->height)) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerDEC] video size changed to width %d - height %d\n", width, height)); + if (width && height) { + read->width = width; + read->height = height; + } + return GF_BUFFER_TOO_SMALL; + } + + in.x = src->x; + in.y = src->y; + in.w = src->w; + in.h = src->h; + out.x = dst->x; + out.y = dst->y; + out.w = dst->w; + out.h = dst->h; + player_video_io_windows_set(read->player, &in, &out); + +#endif + + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[LibPlayerDEC] Repositioning video src %d %d %d %d - dest %d %d %d %d\n", src->x, src->y, src->w, src->h, dst->x, dst->y, dst->w, dst->h) ); return GF_OK; } GF_EXPORT -const u32 *QueryInterfaces() +const u32 *QueryInterfaces() { static u32 si [] = { GF_NET_CLIENT_INTERFACE, @@ -418,7 +479,7 @@ GF_BaseInterface *LoadInterface(u32 InterfaceType) GF_SAFEALLOC(ifce, GF_PrivateMediaDecoder); GF_REGISTER_MODULE_INTERFACE(ifce, GF_PRIVATE_MEDIA_DECODER_INTERFACE, "LibPlayer Decoder", "gpac distribution") - /*setup our own interface*/ + /*setup our own interface*/ ifce->AttachStream = LIBPLAYER_AttachStream; ifce->DetachStream = LIBPLAYER_DetachStream; ifce->GetCapabilities = LIBPLAYER_GetCapabilities; diff --git a/modules/mp3_in/Makefile b/modules/mp3_in/Makefile index be86d62..d77f42f 100644 --- a/modules/mp3_in/Makefile +++ b/modules/mp3_in/Makefile @@ -46,7 +46,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(EXTRALIBS) ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_mp3_in-static.so $(OBJS) -L../../bin/gcc -lgpac_static $(EXTRALIBS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_mp3_in-static.$(DYN_LIB_SUFFIX) $(OBJS) -L../../bin/gcc -lgpac_static $(EXTRALIBS) endif diff --git a/modules/mp3_in/mad_dec.c b/modules/mp3_in/mad_dec.c index 9485fde..2ccd017 100644 --- a/modules/mp3_in/mad_dec.c +++ b/modules/mp3_in/mad_dec.c @@ -62,6 +62,7 @@ typedef struct static GF_Err MAD_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) { MADCTX(); + assert( ctx ); if (ctx->ES_ID && ctx->ES_ID!=esd->ESID) return GF_NOT_SUPPORTED; if (ctx->configured) { @@ -89,7 +90,10 @@ static GF_Err MAD_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) static GF_Err MAD_DetachStream(GF_BaseDecoder *ifcg, u16 ES_ID) { MADCTX(); + assert( ctx ); if (ES_ID != ctx->ES_ID) return GF_BAD_PARAM; + assert( ifcg ); + assert( ctx ); ctx->ES_ID = 0; if (ctx->buffer) gf_free(ctx->buffer); ctx->buffer = NULL; @@ -106,6 +110,7 @@ static GF_Err MAD_DetachStream(GF_BaseDecoder *ifcg, u16 ES_ID) static GF_Err MAD_GetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability *capability) { MADCTX(); + assert( ctx ); switch (capability->CapCode) { /*not tested yet*/ case GF_CODEC_RESILIENT: @@ -153,6 +158,7 @@ static GF_Err MAD_GetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability *capa static GF_Err MAD_SetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability capability) { MADCTX(); + assert( ctx ); switch (capability.CapCode) { /*reset storage buffer*/ case GF_CODEC_WAIT_RAP: @@ -194,6 +200,7 @@ static GF_Err MAD_ProcessData(GF_MediaDecoder *ifcg, char *ptr; u32 num, outSize; MADCTX(); + assert( ctx ); /*check not using scalabilty*/ assert(ctx->ES_ID == ES_ID); @@ -290,21 +297,21 @@ static const char *MAD_GetCodecName(GF_BaseDecoder *dec) MAD_VERSION; } -static Bool MAD_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, u8 PL) +static u32 MAD_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, u8 PL) { /*audio decs*/ - if (StreamType != GF_STREAM_AUDIO) return 0; + if (StreamType != GF_STREAM_AUDIO) return GF_CODEC_NOT_SUPPORTED; /*media type query*/ - if (!esd) return 1; + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; switch (esd->decoderConfig->objectTypeIndication) { /*MPEG1 audio*/ case GPAC_OTI_AUDIO_MPEG2_PART3: /*MPEG2 audio*/ case GPAC_OTI_AUDIO_MPEG1: - return 1; + return GF_CODEC_SUPPORTED; } - return 0; + return GF_CODEC_NOT_SUPPORTED; } GF_BaseDecoder *NewMADDec() @@ -337,6 +344,7 @@ void DeleteMADDec(GF_MediaDecoder *ifcg) if (!ifcg) return; ctx = (MADDec *) ifcg->privateStack; + ifcg->privateStack = NULL; if (ctx){ if (ctx->configured) { mad_stream_finish(&ctx->stream); @@ -348,8 +356,8 @@ void DeleteMADDec(GF_MediaDecoder *ifcg) ctx->num_channels = 0; gf_free(ctx); } - ifcg->privateStack = NULL; gf_free(ifcg); } #endif + diff --git a/modules/mpd_in/Makefile b/modules/mpd_in/Makefile index b5d8969..22bb385 100644 --- a/modules/mpd_in/Makefile +++ b/modules/mpd_in/Makefile @@ -1,57 +1,57 @@ -include ../../config.mak - -vpath %.c $(SRC_PATH)/modules/mpd_in - -CFLAGS= $(OPTFLAGS) -w -I"$(SRC_PATH)/include" -Wall - - -ifeq ($(DEBUGBUILD), yes) -CFLAGS+=-g -DDEBUG -LDFLAGS+=-g -endif - -ifeq ($(GPROFBUILD), yes) -CFLAGS+=-pg -LDFLAGS+=-pg -endif - -#common obj -OBJS=mpd_in.o - -SRCS := $(OBJS:.o=.c) - -LIB=gm_mpd_in.$(DYN_LIB_SUFFIX) - -all: $(LIB) - - -$(LIB): $(OBJS) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac -ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_mpegts_in-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static -endif - - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< - - -clean: - rm -f $(OBJS) ../../bin/gcc/$(LIB) - -dep: depend - -depend: - rm -f .depend - $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend - -distclean: clean - rm -f Makefile.bak .depend - - - -# include dependency files if they exist -# -ifneq ($(wildcard .depend),) -include .depend -endif +include ../../config.mak + +vpath %.c $(SRC_PATH)/modules/mpd_in + +CFLAGS= $(OPTFLAGS) -w -I"$(SRC_PATH)/include" -Wall + + +ifeq ($(DEBUGBUILD), yes) +CFLAGS+=-g -DDEBUG +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD), yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + +#common obj +OBJS=mpd_in.o + +SRCS := $(OBJS:.o=.c) + +LIB=gm_mpd_in.$(DYN_LIB_SUFFIX) + +all: $(LIB) + + +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_mpegts_in-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static +endif + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + + +clean: + rm -f $(OBJS) ../../bin/gcc/$(LIB) + +dep: depend + +depend: + rm -f .depend + $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend + +distclean: clean + rm -f Makefile.bak .depend + + + +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/modules/mpd_in/mpd_in.c b/modules/mpd_in/mpd_in.c index 1d066db..6e03e95 100644 --- a/modules/mpd_in/mpd_in.c +++ b/modules/mpd_in/mpd_in.c @@ -1,7 +1,7 @@ /* * GPAC - Multimedia Framework C SDK * - * Authors: Cyril Concolato + * Authors: Cyril Concolato, Jean Le Feuvre * Copyright (c) Telecom ParisTech 2010- * All rights reserved * @@ -43,74 +43,100 @@ static const char * MPD_MIME_TYPES[] = { "video/vnd.3gpp.mpd", "audio/vnd.3gpp.m */ static const char * M3U8_MIME_TYPES[] = { "video/x-mpegurl", "audio/x-mpegurl", "application/x-mpegurl", "application/vnd.apple.mpegurl", NULL}; +typedef enum { + MPD_STATE_STOPPED = 0, + MPD_STATE_RUNNING, + MPD_STATE_CONNECTING, +} MPD_STATE; + +GF_Err MPD_downloadWithRetry( GF_ClientService * service, GF_DownloadSession ** sess, const char *url, gf_dm_user_io user_io, void *usr_cbk, u64 start_range, u64 end_range, Bool persistent); + typedef struct { char *cache; char *url; } segment_cache_entry; +typedef struct __mpd_group +{ + GF_List *representations; + u32 group_id; + Bool selected; + Bool done; + Bool force_switch_bandwidth; + u32 nb_bw_check; + /*pointer toactive period*/ + GF_MPD_Period *period; + /*active representation index in period->representations*/ + u32 active_rep_index; + u32 active_bitrate, max_bitrate, min_bitrate; + /*local file playback, do not delete them*/ + Bool local_files; + /*next segment to download for this group*/ + u32 download_segment_index; + + /*next file (cached) to delete at next GF_NET_SERVICE_QUERY_NEXT for this group*/ + char * urlToDeleteNext; + volatile u32 max_cached, nb_cached; + segment_cache_entry *cached; + + GF_DownloadSession *segment_dnload; + const char *segment_local_url; + + u32 nb_segments_done; + + Bool segment_must_be_streamed; + + /* Service really managing the segments */ + GF_InputService *service; + char *service_mime; + Bool service_connected; +} GF_MPD_Group; + typedef struct __mpd_module { /* GPAC Service object (i.e. how this module is seen by the terminal)*/ GF_ClientService *service; /* URL to which this service is connected Used to detect when audio service connection request is made on the same URL as video */ char *url; - Bool is_service_connected; - /* number of time the service has been connected */ - u32 nb_service_connections; - u32 nb_connected_channels; - u32 nb_playing_or_paused_channels; - - /* Download of the MPD */ - volatile Bool is_mpd_in_download; - GF_DownloadSession *mpd_dnload; - char * urlToDeleteNext; - volatile u32 max_cached, nb_cached; u32 option_max_cached; - segment_cache_entry *cached; + u32 auto_switch_count; + Bool keep_files; - /* MPD and active informations */ + /* MPD downloader*/ + GF_DownloadSession *mpd_dnload; + /* MPD */ GF_MPD *mpd; + /* number of time the MPD has been reloaded and last update time*/ + u32 reload_count, last_update_time; + /*signature of last MPD*/ + u8 lastMPDSignature[20]; + /*mime used by M3U8 server*/ + char *mimeTypeForM3U8Segments; + + /* active period in MPD (only one currently supported) */ u32 active_period_index; - u32 active_rep_index; - u32 download_segment_index; - /* playback status */ - Double playback_speed; - Double playback_start_range, playback_end_range; + /*list of groups in the active period*/ + GF_List *groups; + /*group 0 if present, NULL otherwise*/ + GF_MPD_Group *group_zero_selected; - /* For Segment downloads */ - GF_DownloadSession *seg_dnload; - const char *seg_local_url; - GF_Thread *dl_thread; + /*Main MPD Thread handling segment downloads and MPD/M3U8 update*/ + GF_Thread *mpd_thread; + /*mutex for group->cache file name access and MPD update*/ GF_Mutex *dl_mutex; /* 0 not started, 1 download in progress */ - Bool is_dl_segments; - Bool dl_stop_request; - - /* Service really managing the segments */ - GF_InputService *seg_ifce; + MPD_STATE mpd_is_running; + Bool mpd_stop_request; - u32 reload_count; - volatile u32 last_update_time; - u32 nb_segs_done; - Bool auto_switch; - u8 lastMPDSignature[20]; - Bool segment_must_be_streamed; - char * mimeTypeForM3U8Segments; + /* TODO - handle playback status for SPEED/SEEK through SIDX */ + Double playback_speed, playback_start_range, playback_end_range; } GF_MPD_In; -static void dumpStatus( GF_MPD_In *mpdin) { - u32 i; - for (i = 0 ; i < mpdin->nb_cached; i++) { - printf("\t[%u] - %s\t:\t%s\n", i, mpdin->cached[i].cache, mpdin->cached[i].url); - } - printf("\t***********\n\n"); -} - static Bool MPD_CheckRootType(const char *local_url) { @@ -134,21 +160,60 @@ static Bool MPD_CheckRootType(const char *local_url) void MPD_NetIO_Segment(void *cbk, GF_NETIO_Parameter *param) { GF_Err e; - GF_MPD_In *mpdin = (GF_MPD_In*) cbk; + u32 download_rate; + GF_MPD_Group *group= (GF_MPD_Group*) cbk; /*handle service message*/ - gf_term_download_update_stats(mpdin->seg_dnload); - e = param->error; + gf_term_download_update_stats(group->segment_dnload); + if (group->done) { + gf_dm_sess_abort(group->segment_dnload); + return; + } + + if ((param->msg_type == GF_NETIO_PARSE_HEADER) && !strcmp(param->name, "Content-Type")) { + if (!group->service_mime) group->service_mime = gf_strdup(param->value); + else if (strcmp(group->service_mime, param->value)) { + GF_MPD_Representation *rep = gf_list_get(group->period->representations, group->active_rep_index); + if (!rep->mime) rep->mime = gf_strdup(param->value); + rep->disabled = 1; + group->force_switch_bandwidth = 1; + gf_dm_sess_abort(group->segment_dnload); + return; + } + } + + e = param->error; if (param->msg_type == GF_NETIO_PARSE_REPLY) { - if (! gf_dm_sess_can_be_cached_on_disk(mpdin->seg_dnload)) { + if (! gf_dm_sess_can_be_cached_on_disk(group->segment_dnload)) { GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, - ("[MPD_IN] Segment %s cannot be cached on disk, will use direct streaming\n", gf_dm_sess_get_resource_name(mpdin->seg_dnload))); - mpdin->segment_must_be_streamed = 1; - gf_dm_sess_abort(mpdin->seg_dnload); + ("[MPD_IN] Segment %s cannot be cached on disk, will use direct streaming\n", gf_dm_sess_get_resource_name(group->segment_dnload))); + group->segment_must_be_streamed = 1; + gf_dm_sess_abort(group->segment_dnload); } else { - mpdin->segment_must_be_streamed = 0; + group->segment_must_be_streamed = 0; } } + else if ((param->msg_type == GF_NETIO_DATA_EXCHANGE) || (param->msg_type == GF_NETIO_DATA_TRANSFERED)) { + if (gf_dm_sess_get_stats(group->segment_dnload, NULL, NULL, NULL, NULL, &download_rate, NULL) == GF_OK) { + if (download_rate) { + download_rate *= 8; + if (download_ratemin_bitrate) group->min_bitrate = download_rate; + if (download_rate>group->max_bitrate) group->max_bitrate = download_rate; + + if (download_rate && (download_rate < group->active_bitrate)) { + fprintf(stdout, "Downloading from group %d at rate %d kbps but group bitrate is %d kbps\n", group->group_id, download_rate/1024, group->active_bitrate/1024); + group->nb_bw_check ++; + if (group->nb_bw_check>2) { + fprintf(stdout, "Downloading from group %d at rate %d kbps but group bitrate is %d kbps - switching\n", group->group_id, download_rate/1024, group->active_bitrate/1024); + group->force_switch_bandwidth = 1; + gf_dm_sess_abort(group->segment_dnload); + } + } else { + group->nb_bw_check = 0; + } + } + } + } } /*! @@ -202,11 +267,10 @@ void MPD_NetIO(void *cbk, GF_NETIO_Parameter *param) e = param->error; } -GF_Err MPD_downloadWithRetry( GF_ClientService * service, GF_DownloadSession ** sess, const char *url, gf_dm_user_io user_io, void *usr_cbk); static GF_Err MPD_UpdatePlaylist(GF_MPD_In *mpdin) { GF_Err e; - u32 i, j, rep_idx; + u32 i, j, rep_idx, group_idx; Bool seg_found = 0; GF_DOMParser *mpd_parser; GF_MPD_Period *period, *new_period; @@ -233,7 +297,8 @@ static GF_Err MPD_UpdatePlaylist(GF_MPD_In *mpdin) gf_delete_file(local_url); purl = gf_strdup(gf_dm_sess_get_resource_name(mpdin->mpd_dnload)); GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Updating Playlist %s...\n", purl)); - e = MPD_downloadWithRetry(mpdin->service, &(mpdin->mpd_dnload), purl, MPD_NetIO, mpdin); + /*use non-persistent connection for MPD*/ + e = MPD_downloadWithRetry(mpdin->service, &(mpdin->mpd_dnload), purl, MPD_NetIO, mpdin, 0, 0, 0); if (e!=GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot update playlist: download problem %s for MPD file\n", gf_error_to_string(e))); gf_free(purl); @@ -290,7 +355,7 @@ static GF_Err MPD_UpdatePlaylist(GF_MPD_In *mpdin) return GF_NON_COMPLIANT_BITSTREAM; } new_mpd = gf_mpd_new(); - e = gf_mpd_init_from_dom(gf_xml_dom_get_root(mpd_parser), new_mpd); + e = gf_mpd_init_from_dom(gf_xml_dom_get_root(mpd_parser), new_mpd, purl); gf_xml_dom_del(mpd_parser); if (e) { GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot update playlist: error in MPD creation %s\n", gf_error_to_string(e))); @@ -313,78 +378,96 @@ static GF_Err MPD_UpdatePlaylist(GF_MPD_In *mpdin) return GF_NON_COMPLIANT_BITSTREAM; } - rep = gf_list_get(period->representations, mpdin->active_rep_index); - info1 = gf_list_get(rep->segments, mpdin->download_segment_index - 1); - - for (rep_idx = 0; rep_idxrepresentations); rep_idx++) { - rep = gf_list_get(period->representations, rep_idx); - new_rep = gf_list_get(new_period->representations, rep_idx); - if (!new_rep) { - GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot update playlist: missing representation in period\n")); - gf_mpd_del(new_mpd); - return GF_NON_COMPLIANT_BITSTREAM; - } - /*merge init segment*/ - if (new_rep->init_url) { - seg_found = 0; - - if (!strcmp(new_rep->init_url, rep->init_url)) { - seg_found = 1; - } else { - for (j=0; jsegments); j++) { - GF_MPD_SegmentInfo *seg = gf_list_get(rep->segments, j); - if (!strcmp(new_rep->init_url, seg->url)) { - seg_found = 1; - break; - } - } - } - /*remove from new list and push to old one*/ - if (!seg_found) { - GF_MPD_SegmentInfo *new_seg; - GF_SAFEALLOC(new_seg, GF_MPD_SegmentInfo); - new_seg->url = gf_strdup(new_rep->init_url); - new_seg->use_byterange = new_rep->init_use_range; - new_seg->byterange_start = new_rep->init_byterange_start; - new_seg->byterange_end = new_rep->init_byterange_end; - gf_list_add(rep->segments, new_seg); - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Representation #%d: Adding new segment from initialization segment %s\n", rep_idx+1, new_seg->url)); - } - } - - /*merge segment list*/ - for (i=0; isegments); i++) { - GF_MPD_SegmentInfo *new_seg = gf_list_get(new_rep->segments, i); - assert( new_seg ); - assert( new_seg->url); - seg_found = 0; - for (j=0; jsegments); j++) { - GF_MPD_SegmentInfo *seg = gf_list_get(rep->segments, j); - assert( seg ); - assert( seg->url); - if (!strcmp(new_seg->url, seg->url)) { - seg_found = 1; - break; - } - } - /*remove from new list and push to old one*/ - if (!seg_found) { - gf_list_rem(new_rep->segments, i); - gf_list_add(rep->segments, new_seg); - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Representation #%d: Adding new segment %s\n", rep_idx+1, new_seg->url)); - i--; - } - } - /*swap lists*/ - { - GF_MPD_SegmentInfo *info2; - segs = new_rep->segments; - new_rep->segments = rep->segments; - rep->segments = segs; - info2 = gf_list_get(rep->segments, mpdin->download_segment_index); - } - } - + for (group_idx=0; group_idxgroups); group_idx++) { + GF_MPD_Group *group = gf_list_get(mpdin->groups, group_idx); + if (!group->selected) continue; + + rep = gf_list_get(period->representations, group->active_rep_index); + info1 = gf_list_get(rep->segments, group->download_segment_index - 1); + + for (rep_idx = 0; rep_idxrepresentations); rep_idx++) { + rep = gf_list_get(period->representations, rep_idx); + new_rep = gf_list_get(new_period->representations, rep_idx); + if (!new_rep) { + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot update playlist: missing representation in period\n")); + gf_mpd_del(new_mpd); + return GF_NON_COMPLIANT_BITSTREAM; + } + /*merge init segment*/ + if (new_rep->init_url) { + seg_found = 0; + + if (!strcmp(new_rep->init_url, rep->init_url)) { + seg_found = 1; + } else { + for (j=0; jsegments); j++) { + GF_MPD_SegmentInfo *seg = gf_list_get(rep->segments, j); + if (!strcmp(new_rep->init_url, seg->url)) { + seg_found = 1; + break; + } + } + } + /*remove from new list and push to old one*/ + if (!seg_found) { + GF_MPD_SegmentInfo *new_seg; + GF_SAFEALLOC(new_seg, GF_MPD_SegmentInfo); + new_seg->url = gf_strdup(new_rep->init_url); + new_seg->use_byterange = new_rep->init_use_range; + new_seg->byterange_start = new_rep->init_byterange_start; + new_seg->byterange_end = new_rep->init_byterange_end; + gf_list_add(rep->segments, new_seg); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Representation #%d: Adding new segment from initialization segment %s\n", rep_idx+1, new_seg->url)); + } + } + + /*merge segment list*/ + for (i=0; isegments); i++) { + GF_MPD_SegmentInfo *new_seg = gf_list_get(new_rep->segments, i); + assert( new_seg ); + assert( new_seg->url); + seg_found = 0; + for (j=0; jsegments); j++) { + GF_MPD_SegmentInfo *seg = gf_list_get(rep->segments, j); + assert( seg ); + assert( seg->url); + if (!strcmp(new_seg->url, seg->url)) { + seg_found = 1; + break; + } + } + /*remove from new list and push to old one*/ + if (!seg_found) { + gf_list_rem(new_rep->segments, i); + gf_list_add(rep->segments, new_seg); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Representation #%d: Adding new segment %s\n", rep_idx+1, new_seg->url)); + i--; + } + } + /*swap lists*/ + { + GF_MPD_SegmentInfo *info2; + segs = new_rep->segments; + new_rep->segments = rep->segments; + new_rep->disabled = rep->disabled; + if (!new_rep->mime) { + new_rep->mime = rep->mime; + rep->mime = NULL; + } + rep->segments = segs; + info2 = gf_list_get(rep->segments, group->download_segment_index); + } + } + /*update group/period to new period*/ + group->period = new_period; + + /*and rebuild representations for this group*/ + gf_list_reset(group->representations); + for (i=0; irepresentations); i++) { + GF_MPD_Representation *rep = gf_list_get(new_period->representations, i); + if (rep->groupID==group->group_id) gf_list_add(group->representations, rep); + } + } /*swap representations - we don't need to update download_segment_index as it still points to the right entry in the merged list*/ if (mpdin->mpd) gf_mpd_del(mpdin->mpd); @@ -399,50 +482,70 @@ static GF_Err MPD_UpdatePlaylist(GF_MPD_In *mpdin) static GF_Err MPD_ClientQuery(GF_InputService *ifce, GF_NetworkCommand *param) { + u32 i; + GF_MPD_Group *group = NULL; if (!param || !ifce || !ifce->proxy_udta) return GF_BAD_PARAM; - if (param->command_type==GF_NET_SERVICE_QUERY_NEXT) { + + if (param->command_type==GF_NET_SERVICE_QUERY_NEXT) { u32 timer = gf_sys_clock(); GF_MPD_In *mpdin = (GF_MPD_In *) ifce->proxy_udta; GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Service Query Next request from terminal\n")); gf_mx_p(mpdin->dl_mutex); + + for (i=0; igroups); i++) { + group = gf_list_get(mpdin->groups, i); + if (group->selected && (group->service == ifce)) break; + group = NULL; + } + + if (!group) { + gf_mx_v(mpdin->dl_mutex); + return GF_SERVICE_ERROR; + } + /* Wait until no file is scheduled to be downloaded */ - while (mpdin->is_dl_segments && mpdin->nb_cached<2) { + while (mpdin->mpd_is_running && group->nb_cached<2) { gf_mx_v(mpdin->dl_mutex); + if (group->done) { + return GF_EOS; + } gf_sleep(16); gf_mx_p(mpdin->dl_mutex); } - if (mpdin->nb_cached<2) { + if (group->nb_cached<2) { GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] No more file in cache, EOS\n")); gf_mx_v(mpdin->dl_mutex); return GF_EOS; } else { GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Had to wait for %u ms for the only cache file to be downloaded\n", (gf_sys_clock() - timer))); } - if (mpdin->cached[0].cache) { - if (mpdin->urlToDeleteNext) { - gf_dm_delete_cached_file_entry_session(mpdin->mpd_dnload, mpdin->urlToDeleteNext); - gf_free( mpdin->urlToDeleteNext); - mpdin->urlToDeleteNext = NULL; + if (group->cached[0].cache) { + if (group->urlToDeleteNext) { + if (!group->local_files && !mpdin->keep_files) + gf_dm_delete_cached_file_entry_session(mpdin->mpd_dnload, group->urlToDeleteNext); + + gf_free( group->urlToDeleteNext); + group->urlToDeleteNext = NULL; } - assert( mpdin->cached[0].url ); - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] deleting cache file %s : %s\n", mpdin->cached[0].url, mpdin->cached[0].cache)); - mpdin->urlToDeleteNext = gf_strdup( mpdin->cached[0].url ); - gf_free(mpdin->cached[0].cache); - gf_free(mpdin->cached[0].url); - mpdin->cached[0].url = NULL; - mpdin->cached[0].cache = NULL; + assert( group->cached[0].url ); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] deleting cache file %s : %s\n", group->cached[0].url, group->cached[0].cache)); + group->urlToDeleteNext = gf_strdup( group->cached[0].url ); + gf_free(group->cached[0].cache); + gf_free(group->cached[0].url); + group->cached[0].url = NULL; + group->cached[0].cache = NULL; } - memmove(&mpdin->cached[0], &mpdin->cached[1], sizeof(segment_cache_entry)*(mpdin->nb_cached-1)); - memset(&(mpdin->cached[mpdin->nb_cached-1]), 0, sizeof(segment_cache_entry)); - mpdin->nb_cached--; - param->url_query.next_url = mpdin->cached[0].cache; + memmove(&group->cached[0], &group->cached[1], sizeof(segment_cache_entry)*(group->nb_cached-1)); + memset(&(group->cached[group->nb_cached-1]), 0, sizeof(segment_cache_entry)); + group->nb_cached--; + param->url_query.next_url = group->cached[0].cache; gf_mx_v(mpdin->dl_mutex); { u32 timer2 = gf_sys_clock() - timer ; if (timer2 > 1000) { GF_LOG(GF_LOG_WARNING, GF_LOG_MODULE, ("[MPD_IN] We were stuck waiting for download to end during too much time : %u ms !\n", timer2)); } - GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] Switching segment playback to \n\tURL: %s in %u ms\n\tCache: %s\n\tElements in cache: %u/%u\n", mpdin->cached[0].url, timer2, mpdin->cached[0].cache, mpdin->nb_cached, mpdin->max_cached)); + GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] Switching segment playback to \n\tURL: %s in %u ms\n\tCache: %s\n\tElements in cache: %u/%u\n", group->cached[0].url, timer2, group->cached[0].cache, group->nb_cached, group->max_cached)); } } else { GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Client Query request (%d) from terminal\n", param->command_type)); @@ -450,27 +553,40 @@ static GF_Err MPD_ClientQuery(GF_InputService *ifce, GF_NetworkCommand *param) return GF_OK; } -static GF_Err MPD_LoadMediaService(GF_MPD_In *mpdin, const char *mime) +static GF_Err MPD_LoadMediaService(GF_MPD_In *mpdin, GF_MPD_Group *group, const char *mime, const char *init_segment_name) { + u32 i; const char *sPlug; - /* Check MIME type to start the right InputService (ISOM or MPEG-2) */ - sPlug = gf_cfg_get_key(mpdin->service->term->user->config, "MimeTypes", mime); - if (sPlug) sPlug = strrchr(sPlug, '"'); - if (sPlug) { - sPlug += 2; - mpdin->seg_ifce = (GF_InputService *) gf_modules_load_interface_by_name(mpdin->service->term->user->modules, sPlug, GF_NET_CLIENT_INTERFACE); - if (mpdin->seg_ifce) { - mpdin->seg_ifce->proxy_udta = mpdin; - mpdin->seg_ifce->query_proxy = MPD_ClientQuery; - } else { - goto exit; - } - } else { - goto exit; - } - return GF_OK; -exit: - GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error locating plugin for segment mime type: %s\n", mime)); + if (mime) { + /* Check MIME type to start the right InputService */ + sPlug = gf_cfg_get_key(mpdin->service->term->user->config, "MimeTypes", mime); + if (sPlug) sPlug = strrchr(sPlug, '"'); + if (sPlug) { + sPlug += 2; + group->service = (GF_InputService *) gf_modules_load_interface_by_name(mpdin->service->term->user->modules, sPlug, GF_NET_CLIENT_INTERFACE); + if (group->service) { + group->service->proxy_udta = mpdin; + group->service->query_proxy = MPD_ClientQuery; + return GF_OK; + } + } + } + if (init_segment_name) { + for (i=0; i< gf_modules_get_count(mpdin->service->term->user->modules); i++) { + GF_InputService *ifce = (GF_InputService *) gf_modules_load_interface(mpdin->service->term->user->modules, i, GF_NET_CLIENT_INTERFACE); + if (!ifce) continue; + + if (ifce->CanHandleURL && ifce->CanHandleURL(ifce, init_segment_name)) { + group->service = ifce; + group->service->proxy_udta = mpdin; + group->service->query_proxy = MPD_ClientQuery; + return GF_OK; + } + gf_modules_close_interface((GF_BaseInterface *) ifce); + } + } + + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error locating plugin for segment - mime type %s - name %s\n", mime, init_segment_name)); return GF_CODEC_NOT_FOUND; } @@ -481,20 +597,35 @@ exit: * Parameters are identical to the ones of gf_term_download_new. * \see gf_term_download_new() */ -GF_Err MPD_downloadWithRetry( GF_ClientService * service, GF_DownloadSession ** sess, const char *url, gf_dm_user_io user_io, void *usr_cbk) +GF_Err MPD_downloadWithRetry( GF_ClientService * service, GF_DownloadSession **sess, const char *url, gf_dm_user_io user_io, void *usr_cbk, u64 start_range, u64 end_range, Bool persistent) { GF_Err e; - if (*sess) { - gf_term_download_del(*sess); - *sess = NULL; - } - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Downloading %s...\n", url)); - *sess = gf_term_download_new(service, url, GF_NETIO_SESSION_NOT_THREADED, user_io, usr_cbk); - if (!(*sess)){ - assert(0); - GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Cannot try to download %s... OUT of memory ?\n", url)); - return GF_OUT_OF_MEM; - } + + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Downloading %s...\n", url)); + if (! *sess) { + u32 flags = GF_NETIO_SESSION_NOT_THREADED; + if (persistent) flags |= GF_NETIO_SESSION_PERSISTENT; + *sess = gf_term_download_new(service, url, flags, user_io, usr_cbk); + if (!(*sess)){ + assert(0); + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Cannot try to download %s... OUT of memory ?\n", url)); + return GF_OUT_OF_MEM; + } + } else { + e = gf_dm_sess_setup_from_url(*sess, url); + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Cannot resetup session for url %s: %s\n", url, gf_error_to_string(e) )); + return e; + } + + } + if (end_range) { + e = gf_dm_sess_set_range(*sess, start_range, end_range); + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Cannot setup byte-range download for %s: %s\n", url, gf_error_to_string(e) )); + return e; + } + } e = gf_dm_sess_process(*sess); switch (e) { case GF_IP_CONNECTION_FAILURE: @@ -524,44 +655,130 @@ GF_Err MPD_downloadWithRetry( GF_ClientService * service, GF_DownloadSession ** } } +static void MPD_SwitchGroupRepresentation(GF_MPD_In *mpd, GF_MPD_Group *group) +{ + u32 i, bandwidth, min_bandwidth; + GF_MPD_Representation *rep_sel = NULL; + GF_MPD_Representation *min_rep_sel = NULL; + Bool min_bandwidth_selected = 0; + bandwidth = 0; + min_bandwidth = (u32) -1; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPDIn] Checking representations between %d and %d kbps\n", group->min_bitrate/1024, group->max_bitrate/1024)); + + for (i=0; irepresentations); i++) { + GF_MPD_Representation *rep = gf_list_get(group->representations, i); + if (rep->disabled) continue; + if ((rep->bandwidth > bandwidth) && (rep->bandwidth < group->max_bitrate )) { + rep_sel = rep; + bandwidth = rep->bandwidth; + } + if (rep->bandwidth < min_bandwidth) { + min_rep_sel = rep; + min_bandwidth = rep->bandwidth; + } + } + if (!rep_sel) { + rep_sel = min_rep_sel; + min_bandwidth_selected = 1; + } + assert(rep_sel); + i = gf_list_find(group->period->representations, rep_sel); + + assert((s32) i >= 0); + + group->force_switch_bandwidth = 0; + group->max_bitrate = 0; + group->min_bitrate = (u32) -1; + + if (i != group->active_rep_index) { + if (min_bandwidth_selected) { + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPDIn] No representation found with bandwidth below %d kbps - using representation @ %d kbps\n", group->max_bitrate/1024, rep_sel->bandwidth/1024)); + } else { + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPDIn] Switching to representation bandwidth %d kbps for download bandwidth %d kbps\n", rep_sel->bandwidth/1024, group->max_bitrate/1024)); + } + group->active_rep_index = i; + group->active_bitrate = rep_sel->bandwidth; + } +} -static GF_Err MPD_DownloadInitSegment(GF_MPD_In *mpdin, GF_MPD_Period *period) +static GF_Err MPD_DownloadInitSegment(GF_MPD_In *mpdin, GF_MPD_Group *group) { GF_Err e; char *base_init_url; char * url_to_dl; GF_MPD_Representation *rep; + u64 start_range, end_range; /* This variable is 0 if there is a initURL, the index of first segment downloaded otherwise */ u32 firstSegment = 0; - if (!mpdin || !period) + if (!mpdin || !group) return GF_BAD_PARAM; gf_mx_p(mpdin->dl_mutex); - assert( period->representations ); - rep = gf_list_get(period->representations, mpdin->active_rep_index); + + assert( group->period && group->period->representations ); + rep = gf_list_get(group->period->representations, group->active_rep_index); if (!rep) { gf_mx_v(mpdin->dl_mutex); GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Unable to find any representation, aborting.\n")); return GF_IO_ERR; } + start_range = end_range = 0; if (!rep->init_url) { GF_MPD_SegmentInfo * seg = gf_list_get(rep->segments, 0); /* No init URL provided, we have to download the first segment then */ if (!seg->url) { - mpdin->dl_stop_request = 1; + mpdin->mpd_stop_request = 1; gf_mx_v(mpdin->dl_mutex); return GF_BAD_PARAM; } firstSegment = 1; url_to_dl = seg->url; + if (seg->use_byterange) { + start_range = seg->byterange_start; + end_range = seg->byterange_end; + } } else { url_to_dl = rep->init_url; + if (rep->init_use_range) { + start_range = rep->init_byterange_start; + end_range = rep->init_byterange_end; + } } if (rep->default_base_url) { base_init_url = gf_url_concatenate(rep->default_base_url, url_to_dl); } else { base_init_url = gf_strdup(url_to_dl); } - e = MPD_downloadWithRetry(mpdin->service, &(mpdin->seg_dnload), base_init_url, MPD_NetIO_Segment, mpdin); + + + if (!strstr(base_init_url, "://") || !strnicmp(base_init_url, "file://", 7)) { + assert(!group->nb_cached); + group->cached[0].cache = gf_strdup(base_init_url); + group->cached[0].url = gf_strdup(base_init_url); + group->nb_cached = 1; + /*do not erase local files*/ + group->local_files = 1; + group->download_segment_index = firstSegment; + group->segment_local_url = group->cached[0].cache; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Setup initialization segment %s \n", group->segment_local_url)); + if (!group->service) e = MPD_LoadMediaService(mpdin, group, rep->mime, group->segment_local_url); + gf_mx_v(mpdin->dl_mutex); + gf_free(base_init_url); + return GF_OK; + } + + group->max_bitrate = 0; + group->min_bitrate = (u32)-1; + /*use persistent connection for segment downloads*/ + e = MPD_downloadWithRetry(mpdin->service, &(group->segment_dnload), base_init_url, MPD_NetIO_Segment, group, start_range, end_range, 1); + + if ((e==GF_OK) && group->force_switch_bandwidth && !mpdin->auto_switch_count) { + MPD_SwitchGroupRepresentation(mpdin, group); + gf_mx_v(mpdin->dl_mutex); + return MPD_DownloadInitSegment(mpdin, group); + } + + if (e == GF_URL_ERROR && !base_init_url) { /* We have a 404 and started with segments */ /* It is possible that the first segment has been deleted while we made the first request... * so we try with the next segment on some M3U8 servers */ @@ -578,86 +795,95 @@ static GF_Err MPD_DownloadInitSegment(GF_MPD_In *mpdin, GF_MPD_Period *period) } GF_LOG(GF_LOG_WARNING, GF_LOG_MODULE, ("Download of first segment failed... retrying with second one : %s\n", base_init_url)); firstSegment = 2; - e = MPD_downloadWithRetry(mpdin->service, &(mpdin->seg_dnload), base_init_url, MPD_NetIO_Segment, mpdin); + /*use persistent connection for segment downloads*/ + e = MPD_downloadWithRetry(mpdin->service, &(group->segment_dnload), base_init_url, MPD_NetIO_Segment, group, 0, 0, 1); } /* end of 404 */ - if (e!= GF_OK && !mpdin->segment_must_be_streamed) { - mpdin->dl_stop_request = 1; + if (e!= GF_OK && !group->segment_must_be_streamed) { + mpdin->mpd_stop_request = 1; gf_mx_v(mpdin->dl_mutex); gf_free(base_init_url); return e; } else { char mime[128]; - GF_MPD_Representation *rep = gf_list_get(period->representations, mpdin->active_rep_index); u32 count = gf_list_count(rep->segments) + 1; - if (count < mpdin->max_cached) { + if (count < group->max_cached) { if (count < 1) { GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] 0 representations, aborting\n")); gf_free(base_init_url); + gf_mx_v(mpdin->dl_mutex); return GF_BAD_PARAM; } - GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] Resizing to %u max_cached elements instead of %u.\n", count, mpdin->max_cached)); + GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] Resizing to %u max_cached elements instead of %u.\n", count, group->max_cached)); /* OK, we have a problem, it may ends download */ - mpdin->max_cached = count; + group->max_cached = count; } - e = gf_dm_sess_process(mpdin->seg_dnload); + e = gf_dm_sess_process(group->segment_dnload); /* Mime-Type check */ - strncpy(mime, gf_dm_sess_mime_type(mpdin->seg_dnload), sizeof(mime)); + strncpy(mime, gf_dm_sess_mime_type(group->segment_dnload), sizeof(mime)); strlwr(mime); - if (mime && mpdin->seg_ifce == NULL) { + if (mime && group->service == NULL) { GF_Err e; - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Searching a decoder for mime type : %s...\n", mime)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Searching an input plugin for mime type : %s...\n", mime)); gf_free( mpdin->mimeTypeForM3U8Segments); mpdin->mimeTypeForM3U8Segments = gf_strdup( mime ); gf_free( rep->mime); rep->mime = gf_strdup( mime ); - e = MPD_LoadMediaService(mpdin, mime); - if (e != GF_OK) + e = MPD_LoadMediaService(mpdin, group, mime, base_init_url); + if (e != GF_OK) { + gf_mx_v(mpdin->dl_mutex); return e; + } } if (!mime || (stricmp(mime, rep->mime))) { GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Mime '%s' is not correct for '%s', it should be '%s'\n", mime, base_init_url, rep->mime)); - mpdin->dl_stop_request = 0; + mpdin->mpd_stop_request = 0; gf_mx_v(mpdin->dl_mutex); gf_free(base_init_url); base_init_url = NULL; return GF_BAD_PARAM; } - if (mpdin->segment_must_be_streamed ) { - mpdin->seg_local_url = gf_dm_sess_get_resource_name(mpdin->seg_dnload); + if (group->segment_must_be_streamed ) { + group->segment_local_url = gf_dm_sess_get_resource_name(group->segment_dnload); e = GF_OK; } else { - mpdin->seg_local_url = rep->init_use_range ? gf_cache_get_cache_filename_range(mpdin->seg_dnload, rep->init_byterange_start, rep->init_byterange_end ) : gf_dm_sess_get_cache_name(mpdin->seg_dnload); + group->segment_local_url = gf_dm_sess_get_cache_name(group->segment_dnload); } - if ((e!=GF_OK) || !mpdin->seg_local_url) { - GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error with initialization segment: download result:%s, cache file:%s\n", gf_error_to_string(e), mpdin->seg_local_url)); - mpdin->dl_stop_request = 1; + if ((e!=GF_OK) || !group->segment_local_url) { + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error with initialization segment: download result:%s, cache file:%s\n", gf_error_to_string(e), group->segment_local_url)); + mpdin->mpd_stop_request = 1; gf_mx_v(mpdin->dl_mutex); gf_free(base_init_url); return GF_BAD_PARAM; } else { -#ifndef DONT_USE_TERMINAL_MODULE_API - GF_NetworkCommand com; -#endif - assert(!mpdin->nb_cached); - mpdin->cached[0].cache = gf_strdup(mpdin->seg_local_url); - mpdin->cached[0].url = gf_strdup(gf_dm_sess_get_resource_name(mpdin->seg_dnload)); - mpdin->nb_cached = 1; - mpdin->download_segment_index = firstSegment; - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Adding initialization segment %s to cache: %s\n", mpdin->seg_local_url, mpdin->cached[0].url )); + assert(!group->nb_cached); + group->cached[0].cache = gf_strdup(group->segment_local_url); + group->cached[0].url = gf_strdup(gf_dm_sess_get_resource_name(group->segment_dnload)); + group->nb_cached = 1; + group->download_segment_index = firstSegment; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Adding initialization segment %s to cache: %s\n", group->segment_local_url, group->cached[0].url )); gf_mx_v(mpdin->dl_mutex); gf_free(base_init_url); -#ifndef DONT_USE_TERMINAL_MODULE_API - com.base.command_type = GF_NET_SERVICE_INFO; - gf_term_on_command(mpdin->service, &com, GF_OK); -#endif return GF_OK; } } } - +static void MPDIn_skip_disabled_rep(GF_MPD_Group *group, GF_MPD_Representation *rep) +{ + s32 rep_idx = gf_list_find(group->representations, rep); + while (1) { + rep_idx++; + if (rep_idx==gf_list_count(group->representations)) rep_idx = 0; + rep = gf_list_get(group->representations, rep_idx); + if (!rep->disabled) break; + } + assert(rep && !rep->disabled); + group->active_rep_index = gf_list_find(group->period->representations, rep); + group->active_bitrate = rep->bandwidth; + GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] Switching to representation %d - BW %d\n", group->active_rep_index, group->active_bitrate )); +} static u32 download_segments(void *par) { @@ -666,144 +892,267 @@ static u32 download_segments(void *par) GF_MPD_Period *period; GF_MPD_Representation *rep; GF_MPD_SegmentInfo *seg; + u32 i, group_count, ret = 0; + Bool go_on = 1; char *new_base_seg_url; assert(mpdin); if (!mpdin->mpd){ - GF_LOG(GF_LOG_WARNING, GF_LOG_MODULE, ("[MPD_IN] Incorrect state, no mpdin->mpd for URL=%s, already stopped ?\n", mpdin->seg_local_url)); + GF_LOG(GF_LOG_WARNING, GF_LOG_MODULE, ("[MPD_IN] Incorrect state, no mpdin->mpd for URL=%s, already stopped ?\n", mpdin->url)); return 1; } + /* Setting the download status in exclusive code */ gf_mx_p(mpdin->dl_mutex); - mpdin->is_dl_segments = 1; + mpdin->mpd_is_running = MPD_STATE_CONNECTING; gf_mx_v(mpdin->dl_mutex); + e = GF_OK; period = gf_list_get(mpdin->mpd->periods, mpdin->active_period_index); - e = MPD_DownloadInitSegment(mpdin, period); - mpdin->dl_stop_request=0; - if (e != GF_OK) { + group_count = gf_list_count(mpdin->groups); + for (i=0; igroups, i); + if (!group->selected) continue; + e = MPD_DownloadInitSegment(mpdin, group); + if (e) break; + } + mpdin->mpd_stop_request=0; + + if (e != GF_OK) { gf_term_on_connect(mpdin->service, NULL, e); - return 1; + ret = 1; + goto exit; } - if (!mpdin->is_service_connected) mpdin->is_service_connected = 1; mpdin->last_update_time = gf_sys_clock(); - /* Forward the ConnectService message to the appropriate service for this type of segment */ - GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] Connecting initial service... %s\n", mpdin->seg_local_url)); - mpdin->seg_ifce->ConnectService(mpdin->seg_ifce, mpdin->service, mpdin->seg_local_url); - GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] Connecting initial service DONE\n", mpdin->seg_local_url)); - while (1) { + + gf_mx_p(mpdin->dl_mutex); + mpdin->mpd_is_running = MPD_STATE_CONNECTING; + gf_mx_v(mpdin->dl_mutex); + + for (i=0; igroups, i); + GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] Connecting initial service... %s\n", group->segment_local_url)); + if (! group->service) { + e = GF_SERVICE_ERROR; + gf_term_on_connect(mpdin->service, NULL, e); + ret = 1; + goto exit; + } + e = group->service->ConnectService(group->service, mpdin->service, group->segment_local_url); + if (e) { + ret = 1; + goto exit; + } + GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] Connecting initial service DONE\n", group->segment_local_url)); + } + + gf_mx_p(mpdin->dl_mutex); + mpdin->mpd_is_running = MPD_STATE_RUNNING; + gf_mx_v(mpdin->dl_mutex); + + while (go_on) { + const char *local_file_name = NULL; + const char *resource_name = NULL; /*wait until next segment is needed*/ - gf_mx_p(mpdin->dl_mutex); - while (!mpdin->dl_stop_request && (mpdin->nb_cached==mpdin->max_cached)) { + while (!mpdin->mpd_stop_request) { u32 timer = gf_sys_clock() - mpdin->last_update_time; Bool shouldParsePlaylist = mpdin->mpd->min_update_time && (timer > mpdin->mpd->min_update_time); - gf_mx_v(mpdin->dl_mutex); - if (shouldParsePlaylist) { + + if (shouldParsePlaylist) { GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Next segment in cache, but it is time to update the playlist (%u ms/%u)\n", timer, mpdin->mpd->min_update_time)); e = MPD_UpdatePlaylist(mpdin); + group_count = gf_list_count(mpdin->groups); if (e) { GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error updating MDP %s\n", gf_error_to_string(e))); } } else { - gf_sleep(16); + Bool cache_full = 1; + gf_mx_p(mpdin->dl_mutex); + for (i=0; igroups, i); + if (!group->selected || group->done) continue; + if (group->nb_cachedmax_cached) { + cache_full = 0; + break; + } + } + gf_mx_v(mpdin->dl_mutex); + if (!cache_full) break; + + gf_sleep(16); } - gf_mx_p(mpdin->dl_mutex); } /* stop the thread if requested */ - if (mpdin->dl_stop_request) { - mpdin->is_dl_segments = 0; - gf_mx_v(mpdin->dl_mutex); + if (mpdin->mpd_stop_request) { + go_on = 0; break; } - gf_mx_v(mpdin->dl_mutex); /* Continue the processing (no stop request) */ period = gf_list_get(mpdin->mpd->periods, mpdin->active_period_index); - rep = gf_list_get(period->representations, mpdin->active_rep_index); - /* if the index of the segment to be downloaded is greater or equal to the last segment (as seen in the playlist), - we need to check if a new playlist is ready */ - if (mpdin->download_segment_index>=gf_list_count(rep->segments)) { - u32 timer = gf_sys_clock() - mpdin->last_update_time; - /* update of the playlist, only if indicated */ - if (mpdin->mpd->min_update_time && timer > mpdin->mpd->min_update_time) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Last segment in current playlist downloaded, checking updates after %u ms\n", timer)); - e = MPD_UpdatePlaylist(mpdin); - if (e) { - GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error updating MDP %s\n", gf_error_to_string(e))); - } - period = gf_list_get(mpdin->mpd->periods, mpdin->active_period_index); - rep = gf_list_get(period->representations, mpdin->active_rep_index); - } else { - gf_sleep(16); - } - /* Now that the playlist is up to date, we can check again */ - if (mpdin->download_segment_index>=gf_list_count(rep->segments)) { - if (mpdin->mpd->min_update_time) { - /* if there is a specified update period, we redo the whole process */ - continue; - } else { - /* if not, we are really at the end of the playlist, we can quit */ - GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] End of playlist reached... downloading remaining elements...")); - break; - } - } - } - gf_mx_p(mpdin->dl_mutex); - /* At this stage, there are some segments left to be downloaded */ - seg = gf_list_get(rep->segments, mpdin->download_segment_index); - gf_mx_v(mpdin->dl_mutex); + /*for each selected groups*/ + for (i=0; igroups, i); + if (! group->selected) continue; + if (group->done) continue; + + + if (group->nb_cached>=group->max_cached) { + continue; + } + + rep = gf_list_get(period->representations, group->active_rep_index); + + /* if the index of the segment to be downloaded is greater or equal to the last segment (as seen in the playlist), + we need to check if a new playlist is ready */ + if (group->download_segment_index>=gf_list_count(rep->segments)) { + u32 timer = gf_sys_clock() - mpdin->last_update_time; + /* update of the playlist, only if indicated */ + if (mpdin->mpd->min_update_time && timer > mpdin->mpd->min_update_time) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Last segment in current playlist downloaded, checking updates after %u ms\n", timer)); + e = MPD_UpdatePlaylist(mpdin); + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error updating MDP %s\n", gf_error_to_string(e))); + } + group_count = gf_list_count(mpdin->groups); + period = gf_list_get(mpdin->mpd->periods, mpdin->active_period_index); + rep = gf_list_get(period->representations, group->active_rep_index); + } else { + gf_sleep(16); + } + /* Now that the playlist is up to date, we can check again */ + if (group->download_segment_index >= gf_list_count(rep->segments)) { + if (mpdin->mpd->min_update_time) { + /* if there is a specified update period, we redo the whole process */ + continue; + } else { + /* if not, we are really at the end of the playlist, we can quit */ + GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] End of playlist reached... downloading remaining elements...")); + group->done = 1; + break; + } + } + } + gf_mx_p(mpdin->dl_mutex); + /* At this stage, there are some segments left to be downloaded */ + seg = gf_list_get(rep->segments, group->download_segment_index); + gf_mx_v(mpdin->dl_mutex); + + if (!seg->url) { + if (rep->init_url) + new_base_seg_url = gf_url_concatenate(rep->default_base_url, rep->init_url); + else + new_base_seg_url = gf_strdup(rep->default_base_url); + } else if (rep->default_base_url) { + new_base_seg_url = gf_url_concatenate(rep->default_base_url, seg->url); + } else { + new_base_seg_url = gf_strdup(seg->url); + } + if (seg->use_byterange) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Downloading new segment: %s (range: %d-%d)\n", new_base_seg_url, seg->byterange_start, seg->byterange_end)); + } + + /*local file*/ + if (!strstr(new_base_seg_url, "://") || !strnicmp(new_base_seg_url, "file://", 7)) { + /*byte-range request from file are ignored*/ + if (seg->use_byterange) { + group->done = 1; + break; + } + resource_name = local_file_name = (char *) new_base_seg_url; + e = GF_OK; + /*do not erase local files*/ + group->local_files = 1; + } else { + group->max_bitrate = 0; + group->min_bitrate = (u32)-1; + /*use persistent connection for segment downloads*/ + if (seg->use_byterange) { + e = MPD_downloadWithRetry(mpdin->service, &(group->segment_dnload), new_base_seg_url, MPD_NetIO_Segment, group, seg->byterange_start, seg->byterange_end, 1); + } else { + e = MPD_downloadWithRetry(mpdin->service, &(group->segment_dnload), new_base_seg_url, MPD_NetIO_Segment, group, 0, 0, 1); + } + + if ((e==GF_OK) && group->force_switch_bandwidth) { + if (!mpdin->auto_switch_count) { + MPD_SwitchGroupRepresentation(mpdin, group); + /*restart*/ + i--; + continue; + } + if (rep->disabled) { + MPDIn_skip_disabled_rep(group, rep); + /*restart*/ + i--; + continue; + } + } + + if (group->segment_must_be_streamed) local_file_name = gf_dm_sess_get_resource_name(group->segment_dnload); + else local_file_name = gf_dm_sess_get_cache_name(group->segment_dnload); + + resource_name = gf_dm_sess_get_resource_name(group->segment_dnload); + + { + u32 total_size, bytes_per_sec; + Double bitrate; + gf_dm_sess_get_stats(group->segment_dnload, NULL, NULL, &total_size, NULL, &bytes_per_sec, NULL); + bitrate = 8*total_size; + bitrate *= 1000; + bitrate /= rep->default_segment_duration; + bitrate /= 1024; + fprintf(stdout, "Downloaded segment bitrate %d kbps with bandwith %d kbps\n", (u32) bitrate, 8*bytes_per_sec/1024); + /*TODO switch quality*/ + + if (!mpdin->auto_switch_count) { + MPD_SwitchGroupRepresentation(mpdin, group); + } + } + } + + if (e == GF_OK || group->segment_must_be_streamed) { + gf_mx_p(mpdin->dl_mutex); + assert(group->nb_cachedmax_cached); + group->cached[group->nb_cached].cache = gf_strdup(local_file_name); + group->cached[group->nb_cached].url = gf_strdup( resource_name ); + GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] Added file to cache\n\tURL: %s\n\tCache: %s\n\tElements in cache: %u/%u\n", group->cached[group->nb_cached].url, group->cached[group->nb_cached].cache, group->nb_cached+1, group->max_cached)); + group->nb_cached++; + group->download_segment_index++; + if (mpdin->auto_switch_count) { + group->nb_segments_done++; + if (group->nb_segments_done==mpdin->auto_switch_count) { + group->nb_segments_done=0; + MPDIn_skip_disabled_rep(group, rep); + } + } + gf_mx_v(mpdin->dl_mutex); + } + gf_free(new_base_seg_url); + new_base_seg_url = NULL; + if (e != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error in downloading new segment: %s %s\n", new_base_seg_url, gf_error_to_string(e))); + go_on=0; + break; + } + } + + if (!go_on) break; - if (rep->default_base_url) { - new_base_seg_url = gf_url_concatenate(rep->default_base_url, seg->url); - } else { - new_base_seg_url = gf_strdup(seg->url); - } - if (seg->use_byterange) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Downloading new segment: %s (range: %d-%d)\n", new_base_seg_url, seg->byterange_start, seg->byterange_end)); - } - e = MPD_downloadWithRetry(mpdin->service, &(mpdin->seg_dnload), new_base_seg_url, MPD_NetIO_Segment, mpdin); - if (e == GF_OK || mpdin->segment_must_be_streamed) { - gf_mx_p(mpdin->dl_mutex); - mpdin->cached[mpdin->nb_cached].cache = gf_strdup(mpdin->segment_must_be_streamed? - gf_dm_sess_get_resource_name(mpdin->seg_dnload) : - (rep->init_use_range ? gf_cache_get_cache_filename_range(mpdin->seg_dnload, rep->init_byterange_start, rep->init_byterange_end ) : gf_dm_sess_get_cache_name(mpdin->seg_dnload))); - mpdin->cached[mpdin->nb_cached].url = gf_strdup( gf_dm_sess_get_resource_name(mpdin->seg_dnload)); - GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[MPD_IN] Added file to cache\n\tURL: %s\n\tCache: %s\n\tElements in cache: %u/%u\n", mpdin->cached[mpdin->nb_cached].url, mpdin->cached[mpdin->nb_cached].cache, mpdin->nb_cached+1, mpdin->max_cached)); - mpdin->nb_cached++; - gf_mx_v(mpdin->dl_mutex); - mpdin->download_segment_index++; - if (mpdin->auto_switch) { - mpdin->nb_segs_done++; - if (mpdin->nb_segs_done==1) { - mpdin->nb_segs_done=0; - mpdin->active_rep_index++; - if (mpdin->active_rep_index>=gf_list_count(period->representations)) mpdin->active_rep_index=0; - } - } - } - if (e != GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error in downloading new segment: %s %s\n", new_base_seg_url, gf_error_to_string(e))); - gf_free(new_base_seg_url); - new_base_seg_url = NULL; - break; - } else { - gf_free(new_base_seg_url); - new_base_seg_url = NULL; - } } +exit: /* Signal that the download thread has ended */ gf_mx_p(mpdin->dl_mutex); - mpdin->is_dl_segments = 0; + mpdin->mpd_is_running = MPD_STATE_STOPPED; gf_mx_v(mpdin->dl_mutex); - return 0; + return ret; } const char * MPD_MPD_DESC = "HTTP MPD Streaming"; -const char * MPD_MPD_EXT = "3gm mdp"; +const char * MPD_MPD_EXT = "3gm mpd"; const char * MPD_M3U8_DESC = "HTTP M3U8 Playlist Streaming"; @@ -839,30 +1188,44 @@ Bool MPD_CanHandleURL(GF_InputService *plug, const char *url) return MPD_CheckRootType(url); } + +GF_InputService *MPD_GetInputServiceForChannel(GF_MPD_In *mpdin, LPNETCHANNEL channel) +{ + GF_Channel *ch; + if (mpdin->group_zero_selected) return mpdin->group_zero_selected->service; + ch = (GF_Channel *) channel; + assert(ch && ch->odm && ch->odm->OD); + + return (GF_InputService *) ch->odm->OD->service_ifce; +} + +GF_MPD_Group *MPD_GetGroupForInputService(GF_MPD_In *mpdin, GF_InputService *ifce) +{ + u32 i; + for (i=0; igroups); i++) { + GF_MPD_Group *group = gf_list_get(mpdin->groups, i); + if (group->service==ifce) return group; + } + return NULL; +} + GF_Err MPD_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, const char *url, Bool upstream) { GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv; - GF_Err e; - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Channel Connection (0x%x) request from terminal for %s\n", channel, url)); - if (!plug || !plug->priv || !mpdin->seg_ifce) return GF_SERVICE_ERROR; - e = mpdin->seg_ifce->ConnectChannel(mpdin->seg_ifce, channel, url, upstream); - if (e == GF_OK) { - mpdin->nb_connected_channels++; - } - return e; + GF_InputService *segment_ifce = MPD_GetInputServiceForChannel(mpdin, channel); + if (!plug || !plug->priv || !segment_ifce) return GF_SERVICE_ERROR; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Channel Connection (%p) request from terminal for %s\n", channel, url)); + return segment_ifce->ConnectChannel(segment_ifce, channel, url, upstream); } GF_Err MPD_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) { GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv; - GF_Err e; - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Disconnect channel (0x%x) request from terminal \n", channel)); - if (!plug || !plug->priv || !mpdin->seg_ifce) return GF_SERVICE_ERROR; - e = mpdin->seg_ifce->DisconnectChannel(mpdin->seg_ifce, channel); - if (e == GF_OK) { - mpdin->nb_connected_channels--; - } - return e; + GF_InputService *segment_ifce = MPD_GetInputServiceForChannel(mpdin, channel); + if (!plug || !plug->priv || !segment_ifce) return GF_SERVICE_ERROR; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Disconnect channel (%p) request from terminal \n", channel)); + + return segment_ifce->DisconnectChannel(segment_ifce, channel); } static u32 MPD_GetPeriodIndexFromTime(GF_MPD_In *mpdin, u32 time) @@ -881,16 +1244,24 @@ static u32 MPD_GetPeriodIndexFromTime(GF_MPD_In *mpdin, u32 time) static void MPD_DownloadStop(GF_MPD_In *mpdin) { + u32 i; + for (i=0; igroups); i++) { + GF_MPD_Group *group = gf_list_get(mpdin->groups, i); + if (group->selected && group->segment_dnload) { + gf_dm_sess_abort(group->segment_dnload); + group->done = 1; + } + } /* stop the download thread */ gf_mx_p(mpdin->dl_mutex); - if (mpdin->is_dl_segments == 1) { - mpdin->dl_stop_request = 1; + if (mpdin->mpd_is_running != MPD_STATE_STOPPED) { + mpdin->mpd_stop_request = 1; gf_mx_v(mpdin->dl_mutex); while (1) { /* waiting for the download thread to stop */ gf_sleep(16); gf_mx_p(mpdin->dl_mutex); - if (mpdin->is_dl_segments == 0) { + if (mpdin->mpd_is_running != MPD_STATE_RUNNING) { /* it's stopped we can continue */ gf_mx_v(mpdin->dl_mutex); break; @@ -902,20 +1273,114 @@ static void MPD_DownloadStop(GF_MPD_In *mpdin) } } +void MPD_ResetGroups(GF_MPD_In *mpdin) +{ + while (gf_list_count(mpdin->groups)) { + GF_MPD_Group *group = gf_list_last(mpdin->groups); + gf_list_rem_last(mpdin->groups); + gf_list_del(group->representations); + + if (group->urlToDeleteNext) { + if (!mpdin->keep_files && !group->local_files) + gf_dm_delete_cached_file_entry_session(mpdin->mpd_dnload, group->urlToDeleteNext); + + gf_free(group->urlToDeleteNext); + group->urlToDeleteNext = NULL; + } + if (group->segment_dnload) { + gf_term_download_del(group->segment_dnload); + group->segment_dnload = NULL; + } + while (group->nb_cached) { + group->nb_cached --; + if (!mpdin->keep_files && !group->local_files) + gf_delete_file(group->cached[group->nb_cached].cache); + + gf_free(group->cached[group->nb_cached].cache); + gf_free(group->cached[group->nb_cached].url); + } + gf_free(group->cached); + gf_free(group); + } + gf_list_del(mpdin->groups); + mpdin->groups = NULL; +} + +GF_Err MPD_SetupGroups(GF_MPD_In *mpdin) +{ + GF_Err e; + u32 i, j, count; + GF_MPD_Period *period; + if (!mpdin->groups) { + mpdin->groups = gf_list_new(); + if (!mpdin->groups) return GF_OUT_OF_MEM; + } + + period = gf_list_get(mpdin->mpd->periods, mpdin->active_period_index); + if (!period) return GF_BAD_PARAM; + + count = gf_list_count(period->representations); + for (i=0; irepresentations, i); + for (j=0; jgroups); j++) { + GF_MPD_Group *group = gf_list_get(mpdin->groups, j); + if (group->group_id==rep->groupID) { + found = 1; + e = gf_list_add(group->representations, rep); + if (e) return e; + break; + } + } + if (!found) { + GF_MPD_Group *group; + GF_SAFEALLOC(group, GF_MPD_Group); + if (!group) return GF_OUT_OF_MEM; + group->representations = gf_list_new(); + if (!group->representations) { + gf_free(group); + return GF_OUT_OF_MEM; + } + group->group_id = rep->groupID; + group->period = period; + group->max_cached = mpdin->option_max_cached; + group->cached = gf_malloc(sizeof(segment_cache_entry)*group->max_cached); + memset(group->cached, 0, sizeof(segment_cache_entry)*group->max_cached); + if (!group->cached) { + gf_list_del(group->representations); + gf_free(group); + return GF_OUT_OF_MEM; + } + e = gf_list_add(mpdin->groups, group); + if (e) { + gf_free(group->cached); + gf_list_del(group->representations); + gf_free(group); + return e; + } + + e = gf_list_add(group->representations, rep); + if (e) return e; + + } + } + return GF_OK; +} + static GF_Err MPD_SegmentsProcessStart(GF_MPD_In *mpdin, u32 time) { GF_Err e; - u32 rep_i; + u32 rep_i, group_i; GF_MPD_Period *period; - GF_MPD_Representation *rep; - e = GF_BAD_PARAM; -#if 1 +#if 0 MPD_DownloadStop(mpdin); #endif - /* Get the right period from the given time */ + MPD_ResetGroups(mpdin); + + /* Get the right period from the given time */ mpdin->active_period_index = MPD_GetPeriodIndexFromTime(mpdin, time); period = gf_list_get(mpdin->mpd->periods, mpdin->active_period_index); if (!period || !gf_list_count(period->representations) ) { @@ -923,38 +1388,62 @@ static GF_Err MPD_SegmentsProcessStart(GF_MPD_In *mpdin, u32 time) goto exit; } - /* Select the appropriate representation in the given period */ - mpdin->active_rep_index = 0; - for (rep_i = 0; rep_i < gf_list_count(period->representations); rep_i++) { - GF_MPD_Representation *rep = gf_list_get(period->representations, rep_i); - GF_MPD_Representation *rep_sel = gf_list_get(period->representations, mpdin->active_rep_index); - if (rep->qualityRanking > rep_sel->qualityRanking) { - mpdin->active_rep_index = rep_i; - } else if (rep->bandwidth < rep_sel->bandwidth) { - mpdin->active_rep_index = rep_i; - } - } + /*setup all groups*/ + MPD_SetupGroups(mpdin); + mpdin->group_zero_selected = NULL; - /* TODO: Generate segment names if urltemplates are used */ - rep = gf_list_get(period->representations, mpdin->active_rep_index); - if (!gf_list_count(rep->segments) || !rep->mime) { - if (!rep->mime) { - GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot start: missing mime\n")); - } else { - GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot start: missing segments\n")); - } - goto exit; - } + for (group_i=0; group_igroups); group_i++) { + GF_MPD_Representation *rep_sel; + u32 active_rep; + GF_MPD_Group *group = gf_list_get(mpdin->groups, group_i); - mpdin->seg_ifce = NULL; - if (strcmp(M3U8_UNKOWN_MIME_TYPE, rep->mime)) { - e = MPD_LoadMediaService(mpdin, rep->mime); - if (e != GF_OK) - goto exit; - } else { - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Ignoring mime type %s, wait for first file...\n", rep->mime)); - } - gf_th_run(mpdin->dl_thread, download_segments, mpdin); + if (group->group_id==0) { + mpdin->group_zero_selected = group; + } else if (mpdin->group_zero_selected) { + break; + } + + /* Select the appropriate representation in the given period */ + active_rep = 0; + for (rep_i = 0; rep_i < gf_list_count(group->representations); rep_i++) { + GF_MPD_Representation *rep = gf_list_get(group->representations, rep_i); + rep_sel = gf_list_get(group->representations, active_rep); + /*by default tune to best quality and/or full bandwith*/ + if (rep->qualityRanking > rep_sel->qualityRanking) { + active_rep = rep_i; + } else if (rep->bandwidth > rep_sel->bandwidth) { + active_rep = rep_i; + } + } + + rep_sel = gf_list_get(group->representations, active_rep); + group->active_rep_index = gf_list_find(group->period->representations, rep_sel); + group->active_bitrate = rep_sel->bandwidth; + + + /* TODO: Generate segment names if urltemplates are used */ + if (!gf_list_count(rep_sel->segments) || !rep_sel->mime) { + if (!rep_sel->mime) { + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot start: missing mime\n")); + } else { + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot start: missing segments\n")); + } + goto exit; + } + + group->service = NULL; + if (strcmp(M3U8_UNKOWN_MIME_TYPE, rep_sel->mime)) { + e = MPD_LoadMediaService(mpdin, group, rep_sel->mime, NULL); + if (e != GF_OK) + goto exit; + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Ignoring mime type %s, wait for first file...\n", rep_sel->mime)); + } + group->selected = 1; + } + + + gf_th_run(mpdin->mpd_thread, download_segments, mpdin); return GF_OK; exit: @@ -965,30 +1454,17 @@ exit: GF_Err MPD_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url) { GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv; + char local_path[GF_MAX_PATH]; const char *local_url, *opt; GF_Err e; GF_DOMParser *mpd_parser; Bool is_m3u8 = 0; + Bool is_local = 0; - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Service Connection request (0x%x) from terminal for %s\n", serv, url)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Service Connection request (%p) from terminal for %s\n", serv, url)); if (!mpdin|| !serv || !url) return GF_BAD_PARAM; - /* If the service is reused on a different URL while already connected this is a problem - The service should only be reused for audio/video in the same stream - WARNING: should check fragment identifiers */ - if (mpdin->is_service_connected) { - if (strcmp(mpdin->url, url)) { - GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot connect service with different url when already connected: %s / %s \n", mpdin->url, url)); - return GF_BAD_PARAM; - } else { - mpdin->nb_service_connections++; - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Reusing Service\n")); - return GF_OK; - } - } - - mpdin->nb_service_connections = 1; mpdin->service = serv; memset( mpdin->lastMPDSignature, 0, sizeof(mpdin->last_update_time)); mpdin->reload_count = 0; @@ -996,32 +1472,35 @@ GF_Err MPD_ConnectService(GF_InputService *plug, GF_ClientService *serv, const c gf_free(mpdin->url); mpdin->url = gf_strdup(url); mpdin->option_max_cached = 0; - mpdin->max_cached = 0; - mpdin->urlToDeleteNext = NULL; - opt = gf_modules_get_option((GF_BaseInterface *)plug, "DASH", "MaxCachedSegments"); - if (!opt) gf_modules_set_option((GF_BaseInterface *)plug, "DASH", "MaxCachedSegments", "5"); + + opt = gf_modules_get_option((GF_BaseInterface *)plug, "DASH", "MaxCachedSegments"); + if (!opt) gf_modules_set_option((GF_BaseInterface *)plug, "DASH", "MaxCachedSegments", "3"); if (opt) mpdin->option_max_cached = atoi(opt); - if (mpdin->option_max_cached < 3) - mpdin->option_max_cached = 3; - mpdin->max_cached = mpdin->option_max_cached; - mpdin->cached = gf_malloc(sizeof(segment_cache_entry)*mpdin->max_cached); - memset(mpdin->cached, 0, sizeof(segment_cache_entry)*mpdin->max_cached); - - mpdin->auto_switch = 0; - opt = gf_modules_get_option((GF_BaseInterface *)plug, "DASH", "AutoSwitch"); - if (!opt) gf_modules_set_option((GF_BaseInterface *)plug, "DASH", "AutoSwitch", "no"); - if (opt && !strcmp(opt, "yes")) mpdin->auto_switch = 1; - - if (mpdin->mpd_dnload) gf_term_download_del(mpdin->mpd_dnload); + if (!mpdin->option_max_cached) mpdin->option_max_cached = 1; + /*we need one more entry for the current segment being played*/ + mpdin->option_max_cached++; + + mpdin->auto_switch_count = 0; + opt = gf_modules_get_option((GF_BaseInterface *)plug, "DASH", "AutoSwitchCount"); + if (!opt) gf_modules_set_option((GF_BaseInterface *)plug, "DASH", "AutoSwitchCount", "0"); + if (opt) mpdin->auto_switch_count = atoi(opt); + + opt = gf_modules_get_option((GF_BaseInterface *)plug, "DASH", "KeepFiles"); + if (!opt) gf_modules_set_option((GF_BaseInterface *)plug, "DASH", "KeepFiles", "no"); + if (opt && !strcmp(opt, "yes")) mpdin->keep_files = 1; + + if (mpdin->mpd_dnload) gf_term_download_del(mpdin->mpd_dnload); mpdin->mpd_dnload = NULL; if (!strnicmp(url, "file://", 7)) { local_url = url + 7; + is_local = 1; if (strstr(url, ".m3u8")) { is_m3u8 = 1; } } else if (strstr(url, "://")) { - e = MPD_downloadWithRetry(mpdin->service, &(mpdin->mpd_dnload), url, MPD_NetIO, mpdin); + /*use non-persistent connection for MPD downloads*/ + e = MPD_downloadWithRetry(mpdin->service, &(mpdin->mpd_dnload), url, MPD_NetIO, mpdin, 0, 0, 1); if (e!=GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot connect service: MPD downloading problem %s for %s\n", gf_error_to_string(e), url)); gf_term_on_connect(mpdin->service, NULL, GF_IO_ERR); @@ -1038,7 +1517,7 @@ GF_Err MPD_ConnectService(GF_InputService *plug, GF_ClientService *serv, const c /* Some servers, for instance http://tv.freebox.fr, serve m3u8 as text/plain */ if (MPD_isM3U8_mime(mime) || strstr(url, ".m3u8")) { is_m3u8 = 1; - } else if (!MPD_is_MPD_mime(mime)) { + } else if (!MPD_is_MPD_mime(mime) && !strstr(url, ".mpd")) { GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] mime '%s' for '%s' should be m3u8 or mpd\n", mime, url)); gf_term_on_connect(mpdin->service, NULL, GF_BAD_PARAM); gf_term_download_del(mpdin->mpd_dnload); @@ -1056,10 +1535,33 @@ GF_Err MPD_ConnectService(GF_InputService *plug, GF_ClientService *serv, const c } } else { local_url = url; + is_local = 1; + if (strstr(url, ".m3u8")) + is_m3u8 = 1; } + + if (is_local) { + FILE *f = fopen(local_url, "rt"); + if (!f) { + gf_term_on_connect(mpdin->service, NULL, GF_URL_ERROR); + return GF_OK; + } + fclose(f); + } if (is_m3u8) { - gf_m3u8_to_mpd(mpdin->service, local_url, url, NULL, mpdin->reload_count, mpdin->mimeTypeForM3U8Segments); + if (is_local) { + char *sep; + strcpy(local_path, local_url); + sep = strrchr(local_path, '.'); + if (sep) sep[0]=0; + strcat(local_path, ".mpd"); + + gf_m3u8_to_mpd(mpdin->service, local_url, url, local_path, mpdin->reload_count, mpdin->mimeTypeForM3U8Segments); + local_url = local_path; + } else { + gf_m3u8_to_mpd(mpdin->service, local_url, url, NULL, mpdin->reload_count, mpdin->mimeTypeForM3U8Segments); + } } if (!MPD_CheckRootType(local_url)) { @@ -1087,7 +1589,7 @@ GF_Err MPD_ConnectService(GF_InputService *plug, GF_ClientService *serv, const c if (!mpdin->mpd) { e = GF_OUT_OF_MEM; } else { - e = gf_mpd_init_from_dom(gf_xml_dom_get_root(mpd_parser), mpdin->mpd); + e = gf_mpd_init_from_dom(gf_xml_dom_get_root(mpd_parser), mpdin->mpd, url); } gf_xml_dom_del(mpd_parser); if (e != GF_OK) { @@ -1109,37 +1611,36 @@ static GF_Descriptor *MPD_GetServiceDesc(GF_InputService *plug, u32 expect_type, { GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv; GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Service Description request from terminal for %s\n", sub_url)); - if (mpdin->seg_ifce) { - return mpdin->seg_ifce->GetServiceDescriptor(mpdin->seg_ifce, expect_type, sub_url); - } else { - GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot provide service description: no segment service hanlder created\n")); - return NULL; - } + if (mpdin->group_zero_selected) { + if (mpdin->group_zero_selected->service) { + return mpdin->group_zero_selected->service->GetServiceDescriptor(mpdin->group_zero_selected->service, expect_type, sub_url); + } else { + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD_IN] Error - cannot provide service description: no segment service hanlder created\n")); + return NULL; + } + } else { + u32 i; + for (i=0; igroups); i++) { + GF_MPD_Group *group = gf_list_get(mpdin->groups, i); + if (!group->selected) continue; + if (group->service_connected) continue; + group->service_connected = 1; + return group->service->GetServiceDescriptor(group->service, expect_type, sub_url); + } + return NULL; + } } void MPD_Stop(GF_MPD_In *mpdin) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Stopping service 0x%x\n", mpdin->service)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Stopping service %p\n", mpdin->service)); MPD_DownloadStop(mpdin); - if (mpdin->urlToDeleteNext) { - gf_dm_delete_cached_file_entry_session(mpdin->mpd_dnload, mpdin->urlToDeleteNext); - gf_free( mpdin->urlToDeleteNext); - mpdin->urlToDeleteNext = NULL; - } + MPD_ResetGroups(mpdin); + if (mpdin->mpd_dnload) { gf_term_download_del(mpdin->mpd_dnload); mpdin->mpd_dnload = NULL; } - if (mpdin->seg_dnload) { - gf_term_download_del(mpdin->seg_dnload); - mpdin->seg_dnload = NULL; - } - while (mpdin->nb_cached) { - mpdin->nb_cached --; - gf_delete_file(mpdin->cached[mpdin->nb_cached].cache); - gf_free(mpdin->cached[mpdin->nb_cached].cache); - gf_free(mpdin->cached[mpdin->nb_cached].url); - } if (mpdin->mpd) gf_mpd_del(mpdin->mpd); mpdin->mpd = NULL; @@ -1147,73 +1648,99 @@ void MPD_Stop(GF_MPD_In *mpdin) GF_Err MPD_CloseService(GF_InputService *plug) { + u32 i; GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv; - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Close Service (0x%x) request from terminal (#%d connections)\n", mpdin->service, mpdin->nb_service_connections)); - mpdin->nb_service_connections--; - if (mpdin->nb_service_connections == 0) { - if (mpdin->seg_ifce && mpdin->is_service_connected) { - mpdin->seg_ifce->CloseService(mpdin->seg_ifce); - mpdin->is_service_connected = 0; - mpdin->seg_ifce = NULL; - } - MPD_Stop(mpdin); - gf_term_on_disconnect(mpdin->service, NULL, GF_OK); - } - return GF_OK; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Close Service (%p) request from terminal\n", mpdin->service)); + + for (i=0; igroups); i++) { + GF_MPD_Group *group = gf_list_get(mpdin->groups, i); + + if (group->service && group->service_connected) { + group->service->CloseService(group->service); + group->service_connected = 0; + group->service = NULL; + } + } + MPD_Stop(mpdin); + MPD_ResetGroups(mpdin); + gf_term_on_disconnect(mpdin->service, NULL, GF_OK); + + return GF_OK; } GF_Err MPD_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) { GF_Err e; GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv; - if (!plug || !plug->priv || !com || !mpdin->seg_ifce) return GF_SERVICE_ERROR; + GF_InputService *segment_ifce = NULL; + GF_MPD_Group *group = NULL; + if (!plug || !plug->priv || !com ) return GF_SERVICE_ERROR; - switch (com->command_type) { + if (mpdin->group_zero_selected) segment_ifce = mpdin->group_zero_selected->service; + + switch (com->command_type) { case GF_NET_SERVICE_INFO: { - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Info command from terminal on Service (0x%x)\n", mpdin->service)); - /* defer to the real input service */ - e = mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); - if (e!= GF_OK || !com->info.name || 2 > strlen(com->info.name)) { - char * title = mpdin->mpd->title; - if (!title) - title = mpdin->cached[0].url; - com->info.name = title; - if (mpdin->mpd->source) + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Info command from terminal on Service (%p)\n", mpdin->service)); + + e = GF_OK; + if (segment_ifce) { + /* defer to the real input service */ + e = segment_ifce->ServiceCommand(segment_ifce, com); + } + + if (e!= GF_OK || !com->info.name || 2 > strlen(com->info.name)) { + com->info.name = mpdin->mpd->title; + if (!com->info.name && mpdin->group_zero_selected) + com->info.name = mpdin->group_zero_selected->cached[0].url; + + if (mpdin->mpd->source) com->info.comment = mpdin->mpd->source; } return GF_OK; } case GF_NET_SERVICE_HAS_AUDIO: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Has Audio command from terminal on Service (0x%x)\n", mpdin->service)); - /* defer to the real input service */ - return mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); - break; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Has Audio command from terminal on Service (%p)\n", mpdin->service)); + if (segment_ifce) { + /* defer to the real input service */ + return segment_ifce->ServiceCommand(segment_ifce, com); + } + return GF_NOT_SUPPORTED; + } + /*not supported*/ + if (!com->base.on_channel) return GF_NOT_SUPPORTED; + + segment_ifce = MPD_GetInputServiceForChannel(mpdin, com->base.on_channel); + if (!segment_ifce) return GF_NOT_SUPPORTED; + group = MPD_GetGroupForInputService(mpdin, segment_ifce); + + + switch (com->command_type) { case GF_NET_CHAN_SET_PADDING: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Set Padding command from terminal on channel 0x%x on Service (0x%x)\n", com->base.on_channel, mpdin->service)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Set Padding command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service)); /* for padding settings, the MPD level should not change anything */ - return mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); + return segment_ifce->ServiceCommand(segment_ifce, com); break; case GF_NET_CHAN_SET_PULL: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Set Pull command from terminal on channel 0x%x on Service (0x%x)\n", com->base.on_channel, mpdin->service)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Set Pull command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service)); /* defer to the real input service */ - return mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); + return segment_ifce->ServiceCommand(segment_ifce, com); break; case GF_NET_CHAN_INTERACTIVE: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Interactive command from terminal on channel 0x%x on Service (0x%x)\n", com->base.on_channel, mpdin->service)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Interactive command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service)); /* we are interactive (that's the whole point of MPD) */ return GF_OK; case GF_NET_CHAN_BUFFER: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Buffer query command from terminal on channel 0x%x on Service (0x%x)\n", com->base.on_channel, mpdin->service)); - return mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Buffer query command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service)); + return segment_ifce->ServiceCommand(segment_ifce, com); break; case GF_NET_CHAN_BUFFER_QUERY: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received buffer query from terminal on channel 0x%x on Service (0x%x)\n", com->base.on_channel, mpdin->service)); - return mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received buffer query from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service)); + return segment_ifce->ServiceCommand(segment_ifce, com); break; case GF_NET_CHAN_DURATION: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Duration query from terminal on channel 0x%x on Service (0x%x)\n", com->base.on_channel, mpdin->service)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Duration query from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service)); /* Ignore the duration given by the input service and use the one given in the MPD Note: the duration of the initial segment will be 0 anyway (in MP4).*/ { @@ -1225,92 +1752,77 @@ GF_Err MPD_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) } break; case GF_NET_CHAN_PLAY: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Play command (#%d playing) from terminal on channel 0x%x on Service (0x%x)\n", mpdin->nb_playing_or_paused_channels, com->base.on_channel, mpdin->service)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Play command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service)); mpdin->playback_speed = com->play.speed; mpdin->playback_start_range = com->play.start_range; mpdin->playback_end_range = com->play.end_range; - e = mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); - if (e == GF_OK) { - mpdin->nb_playing_or_paused_channels++; - } - return e; - break; - case GF_NET_CHAN_STOP: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Stop command (#%d playing) from terminal on channel 0x%x on Service (0x%x)\n", mpdin->nb_playing_or_paused_channels, com->base.on_channel, mpdin->service)); - e = mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); - if (e == GF_OK) { - mpdin->nb_playing_or_paused_channels--; - if (mpdin->nb_playing_or_paused_channels == 0) { -// MPD_Stop(mpdin); - } - } - return e; - break; + group->done = 0; + return segment_ifce->ServiceCommand(segment_ifce, com); + + case GF_NET_CHAN_STOP: + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Stop command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service)); + group->done = 1; + return segment_ifce->ServiceCommand(segment_ifce, com); case GF_NET_CHAN_PAUSE: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Pause command from terminal on channel 0x%x on Service (0x%x)\n", com->base.on_channel, mpdin->service)); - e = mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); - return e; - break; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Pause command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service)); + return segment_ifce->ServiceCommand(segment_ifce, com); case GF_NET_CHAN_RESUME: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Resume command from terminal on channel 0x%x on Service (0x%x)\n", com->base.on_channel, mpdin->service)); - e = mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); - return e; - break; - case GF_NET_CHAN_SET_SPEED: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Set Speed command from terminal on channel 0x%x on Service (0x%x)\n", com->base.on_channel, mpdin->service)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Resume command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service)); + return segment_ifce->ServiceCommand(segment_ifce, com); + case GF_NET_CHAN_SET_SPEED: + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Set Speed command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service)); /* recording the speed, to change the segment download speed */ mpdin->playback_speed = com->play.speed; - /* not supported in MP4 ?? */ - return mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); - break; - case GF_NET_CHAN_CONFIG: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Set Config command from terminal on channel 0x%x on Service (0x%x)\n", com->base.on_channel, mpdin->service)); + return segment_ifce->ServiceCommand(segment_ifce, com); + + case GF_NET_CHAN_CONFIG: + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Set Config command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service)); /* defer to the real input service */ - return mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); + return segment_ifce->ServiceCommand(segment_ifce, com); break; case GF_NET_CHAN_GET_PIXEL_AR: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Pixel Aspect Ratio query from terminal on channel 0x%x on Service (0x%x)\n", com->base.on_channel, mpdin->service)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Pixel Aspect Ratio query from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service)); /* defer to the real input service */ - return mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); + return segment_ifce->ServiceCommand(segment_ifce, com); break; case GF_NET_CHAN_GET_DSI: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Decoder Specific Info query from terminal on channel 0x%x on Service (0x%x)\n", com->base.on_channel, mpdin->service)); - return mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Decoder Specific Info query from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service)); + return segment_ifce->ServiceCommand(segment_ifce, com); break; case GF_NET_CHAN_MAP_TIME: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Map Time query from terminal on channel 0x%x on Service (0x%x)\n", com->base.on_channel, mpdin->service)); - return mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Map Time query from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service)); + return segment_ifce->ServiceCommand(segment_ifce, com); break; case GF_NET_CHAN_RECONFIG: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Reconfig command from terminal on channel 0x%x on Service (0x%x)\n", com->base.on_channel, mpdin->service)); - return mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Reconfig command from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service)); + return segment_ifce->ServiceCommand(segment_ifce, com); break; case GF_NET_CHAN_DRM_CFG: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received DRM query from terminal on channel 0x%x on Service (0x%x)\n", com->base.on_channel, mpdin->service)); - return mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received DRM query from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service)); + return segment_ifce->ServiceCommand(segment_ifce, com); break; case GF_NET_CHAN_GET_ESD: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Elementary Stream Descriptor query from terminal on channel 0x%x on Service (0x%x)\n", com->base.on_channel, mpdin->service)); - return mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Elementary Stream Descriptor query from terminal on channel %p on Service (%p)\n", com->base.on_channel, mpdin->service)); + return segment_ifce->ServiceCommand(segment_ifce, com); break; case GF_NET_BUFFER_QUERY: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Global Buffer query from terminal on Service (0x%x)\n", mpdin->service)); - return mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Global Buffer query from terminal on Service (%p)\n", mpdin->service)); + return segment_ifce->ServiceCommand(segment_ifce, com); break; case GF_NET_GET_STATS: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Statistics query from terminal on Service (0x%x)\n", mpdin->service)); - return mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Statistics query from terminal on Service (%p)\n", mpdin->service)); + return segment_ifce->ServiceCommand(segment_ifce, com); break; case GF_NET_IS_CACHABLE: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Cachable query from terminal on Service (0x%x)\n", mpdin->service)); - return mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Cachable query from terminal on Service (%p)\n", mpdin->service)); + return segment_ifce->ServiceCommand(segment_ifce, com); break; case GF_NET_SERVICE_MIGRATION_INFO: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Migration info query from terminal on Service (0x%x)\n", mpdin->service)); - return mpdin->seg_ifce->ServiceCommand(mpdin->seg_ifce, com); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Migration info query from terminal on Service (%p)\n", mpdin->service)); + return segment_ifce->ServiceCommand(segment_ifce, com); break; default: - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received unknown command (%d) on Service (0x%x)\n",com->command_type, mpdin->service)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received unknown command (%d) on Service (%p)\n",com->command_type, mpdin->service)); return GF_SERVICE_ERROR; } } @@ -1319,11 +1831,12 @@ GF_Err MPD_ChannelGetSLP(GF_InputService *plug, LPNETCHANNEL channel, char **out { GF_Err e; GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv; - if (!plug || !plug->priv || !mpdin->seg_ifce) return GF_SERVICE_ERROR; + GF_InputService *segment_ifce = MPD_GetInputServiceForChannel(mpdin, channel); + if (!plug || !plug->priv || !segment_ifce) return GF_SERVICE_ERROR; - gf_mx_p(mpdin->dl_mutex); - e = mpdin->seg_ifce->ChannelGetSLP(mpdin->seg_ifce, channel, out_data_ptr, out_data_size, out_sl_hdr, sl_compressed, out_reception_status, is_new_data); - gf_mx_v(mpdin->dl_mutex); +// gf_mx_p(mpdin->dl_mutex); + e = segment_ifce->ChannelGetSLP(segment_ifce, channel, out_data_ptr, out_data_size, out_sl_hdr, sl_compressed, out_reception_status, is_new_data); +// gf_mx_v(mpdin->dl_mutex); return e; } @@ -1331,24 +1844,30 @@ GF_Err MPD_ChannelReleaseSLP(GF_InputService *plug, LPNETCHANNEL channel) { GF_Err e; GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv; - if (!plug || !plug->priv || !mpdin->seg_ifce) return GF_SERVICE_ERROR; + GF_InputService *segment_ifce = MPD_GetInputServiceForChannel(mpdin, channel); + if (!plug || !plug->priv || !segment_ifce) return GF_SERVICE_ERROR; - gf_mx_p(mpdin->dl_mutex); - e = mpdin->seg_ifce->ChannelReleaseSLP(mpdin->seg_ifce, channel); - gf_mx_v(mpdin->dl_mutex); +// gf_mx_p(mpdin->dl_mutex); + e = segment_ifce->ChannelReleaseSLP(segment_ifce, channel); +// gf_mx_v(mpdin->dl_mutex); return e; } Bool MPD_CanHandleURLInService(GF_InputService *plug, const char *url) { - GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv; - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Can Handle URL In Service (0x%x) request from terminal for %s\n", mpdin->service, url)); - if (!plug || !plug->priv || !mpdin->seg_ifce) return GF_SERVICE_ERROR; - if (!strcmp(mpdin->url, url)) { + /*JLF: commented out, this shall not happen*/ +#if 0 + GF_MPD_In *mpdin = (GF_MPD_In*) plug->priv; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD_IN] Received Can Handle URL In Service (%p) request from terminal for %s\n", mpdin->service, url)); + if (!plug || !plug->priv) return GF_SERVICE_ERROR; + if (mpdin->url && !strcmp(mpdin->url, url)) { return 1; } else { return 0; } +#endif + + return 0; } GF_EXPORT @@ -1382,9 +1901,8 @@ GF_BaseInterface *LoadInterface(u32 InterfaceType) plug->ChannelGetSLP = MPD_ChannelGetSLP; plug->ChannelReleaseSLP = MPD_ChannelReleaseSLP; GF_SAFEALLOC(mpdin, GF_MPD_In); - memset(mpdin, 0, sizeof(GF_MPD_In)); plug->priv = mpdin; - mpdin->dl_thread = gf_th_new("MPD Segment Downloader Thread"); + mpdin->mpd_thread = gf_th_new("MPD Segment Downloader Thread"); mpdin->dl_mutex = gf_mx_new("MPD Segment Downloader Mutex"); mpdin->mimeTypeForM3U8Segments = gf_strdup( M3U8_UNKOWN_MIME_TYPE ); return (GF_BaseInterface *)plug; @@ -1402,10 +1920,9 @@ void ShutdownInterface(GF_BaseInterface *bi) if (mpdin->url) gf_free(mpdin->url); mpdin->url = NULL; - gf_th_del(mpdin->dl_thread); + gf_th_del(mpdin->mpd_thread); gf_mx_del(mpdin->dl_mutex); gf_free(mpdin->mimeTypeForM3U8Segments); - gf_free(mpdin->cached); gf_free(mpdin); gf_free(bi); } diff --git a/modules/mpegts_in/Makefile b/modules/mpegts_in/Makefile index 951d8ab..f9245ac 100644 --- a/modules/mpegts_in/Makefile +++ b/modules/mpegts_in/Makefile @@ -15,10 +15,6 @@ CFLAGS+=-pg LDFLAGS+=-pg endif -ifeq ($(LINUX_DVB), yes) -CFLAGS+=-DGPAC_HAS_LINUX_DVB -endif - #common obj OBJS=mpegts_in.o @@ -35,7 +31,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_mpegts_in-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_mpegts_in-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static endif diff --git a/modules/mpegts_in/mpegts_in.c b/modules/mpegts_in/mpegts_in.c index 1b48308..6d84d6b 100644 --- a/modules/mpegts_in/mpegts_in.c +++ b/modules/mpegts_in/mpegts_in.c @@ -32,36 +32,7 @@ #ifndef GPAC_DISABLE_MPEG2TS - -#ifdef GPAC_HAS_LINUX_DVB -#include -#include -#include -#include -#include - -typedef struct { - u32 freq; - u16 vpid; - u16 apid; - fe_spectral_inversion_t specInv; - fe_modulation_t modulation; - fe_bandwidth_t bandwidth; - fe_transmit_mode_t TransmissionMode; - fe_guard_interval_t guardInterval; - fe_code_rate_t HP_CodeRate; - fe_code_rate_t LP_CodeRate; - fe_hierarchy_t hierarchy; - - int ts_fd; -} GF_Tuner; - -#define DVB_BUFFER_SIZE 3760 // DVB buffer size 188x20 - -#endif - static const char * MIMES[] = { "video/mpeg-2", "video/mp2t", "video/mpeg", NULL}; -#define UDP_BUFFER_SIZE 0x40000 typedef struct { char *fragment; @@ -70,204 +41,36 @@ typedef struct { u32 pid; } M2TSIn_Prog; -typedef struct +typedef struct { - GF_InputService *owner; - - GF_ClientService *service; GF_M2TS_Demuxer *ts; - Bool request_all_pids; - GF_List *requested_progs; - GF_List *requested_pids; + GF_InputService *owner; - /*demuxer thread*/ - GF_Thread *th; - u32 run_state; - GF_Mutex *mx; - /*net playing*/ - GF_Socket *sock; + GF_ClientService *service; -#ifdef GPAC_HAS_LINUX_DVB - /*dvb playing*/ - GF_Tuner *tuner; -#endif - /*local file playing*/ - FILE *file; - char filename[GF_MAX_PATH]; - u32 start_range, end_range; - u64 file_size; - Double duration; - u32 nb_playing; - Bool file_regulate; - u64 pcr_last; - u32 stb_at_last_pcr; - u32 nb_pck; - - /*remote file handling*/ - GF_DownloadSession *dnload; Bool ts_setup; + Bool request_all_pids; + Bool is_connected; Bool epg_requested; Bool has_eit; LPNETCHANNEL eit_channel; + GF_Mutex *mx; + Bool mpeg4on2_scene_only; char * network_buffer; u32 network_buffer_size; -} M2TSIn; -#define M2TS_BUFFER_MAX 400 + /*pick first pcr pid for regulation*/ + u32 regulation_pcr_pid; + Bool hybrid_on; +}M2TSIn; -#ifdef GPAC_HAS_LINUX_DVB - -static GF_Err gf_dvb_tune(GF_Tuner *tuner, char *url, const char *chan_path) { - struct dmx_pes_filter_params pesFilterParams; - struct dvb_frontend_parameters frp; - int demux1, front1; - FILE *chanfile; - char line[255], chan_name_t[255]; - char freq_str[255], inv[255], bw[255], lcr[255], hier[255], cr[255], - mod[255], transm[255], gi[255], apid_str[255], vpid_str[255]; - const char *chan_conf = ":%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:"; - char *chan_name; - char *tmp; - char frontend_name[100], demux_name[100], dvr_name[100]; - u32 adapter_num; - - chanfile = gf_f64_open(chan_path, "r"); - if (!chanfile) return GF_BAD_PARAM; - - chan_name = url+6; // 6 = strlen("dvb://") - - // support for multiple frontends - tmp = strchr(chan_name, '@'); - if (tmp) { - adapter_num = atoi(tmp+1); - tmp[0] = 0; - } else { - adapter_num = 0; - } - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("Channel name %s\n", chan_name)); - - while(!feof(chanfile)) { - if ( fgets(line, 255, chanfile) != NULL) { - if (line[0]=='#') continue; - if (line[0]=='\r') continue; - if (line[0]=='\n') continue; - - strncpy(chan_name_t, line, index(line, ':')-line); - if (strncmp(chan_name,chan_name_t,strlen(chan_name))==0) { - sscanf(strstr(line,":"), chan_conf, freq_str, inv, bw, lcr, cr, mod, transm, gi, hier, apid_str, vpid_str); - tuner->freq = (uint32_t) atoi(freq_str); - tuner->apid = (uint16_t) atoi(apid_str); - tuner->vpid = (uint16_t) atoi(vpid_str); - //Inversion - if(! strcmp(inv, "INVERSION_ON")) tuner->specInv = INVERSION_ON; - else if(! strcmp(inv, "INVERSION_OFF")) tuner->specInv = INVERSION_OFF; - else tuner->specInv = INVERSION_AUTO; - //LP Code Rate - if(! strcmp(lcr, "FEC_1_2")) tuner->LP_CodeRate =FEC_1_2; - else if(! strcmp(lcr, "FEC_2_3")) tuner->LP_CodeRate =FEC_2_3; - else if(! strcmp(lcr, "FEC_3_4")) tuner->LP_CodeRate =FEC_3_4; - else if(! strcmp(lcr, "FEC_4_5")) tuner->LP_CodeRate =FEC_4_5; - else if(! strcmp(lcr, "FEC_6_7")) tuner->LP_CodeRate =FEC_6_7; - else if(! strcmp(lcr, "FEC_8_9")) tuner->LP_CodeRate =FEC_8_9; - else if(! strcmp(lcr, "FEC_5_6")) tuner->LP_CodeRate =FEC_5_6; - else if(! strcmp(lcr, "FEC_7_8")) tuner->LP_CodeRate =FEC_7_8; - else if(! strcmp(lcr, "FEC_NONE")) tuner->LP_CodeRate =FEC_NONE; - else tuner->LP_CodeRate =FEC_AUTO; - //HP Code Rate - if(! strcmp(cr, "FEC_1_2")) tuner->HP_CodeRate =FEC_1_2; - else if(! strcmp(cr, "FEC_2_3")) tuner->HP_CodeRate =FEC_2_3; - else if(! strcmp(cr, "FEC_3_4")) tuner->HP_CodeRate =FEC_3_4; - else if(! strcmp(cr, "FEC_4_5")) tuner->HP_CodeRate =FEC_4_5; - else if(! strcmp(cr, "FEC_6_7")) tuner->HP_CodeRate =FEC_6_7; - else if(! strcmp(cr, "FEC_8_9")) tuner->HP_CodeRate =FEC_8_9; - else if(! strcmp(cr, "FEC_5_6")) tuner->HP_CodeRate =FEC_5_6; - else if(! strcmp(cr, "FEC_7_8")) tuner->HP_CodeRate =FEC_7_8; - else if(! strcmp(cr, "FEC_NONE")) tuner->HP_CodeRate =FEC_NONE; - else tuner->HP_CodeRate =FEC_AUTO; - //Modulation - if(! strcmp(mod, "QAM_128")) tuner->modulation = QAM_128; - else if(! strcmp(mod, "QAM_256")) tuner->modulation = QAM_256; - else if(! strcmp(mod, "QAM_64")) tuner->modulation = QAM_64; - else if(! strcmp(mod, "QAM_32")) tuner->modulation = QAM_32; - else if(! strcmp(mod, "QAM_16")) tuner->modulation = QAM_16; - //Bandwidth - if(! strcmp(bw, "BANDWIDTH_6_MHZ")) tuner->bandwidth = BANDWIDTH_6_MHZ; - else if(! strcmp(bw, "BANDWIDTH_7_MHZ")) tuner->bandwidth = BANDWIDTH_7_MHZ; - else if(! strcmp(bw, "BANDWIDTH_8_MHZ")) tuner->bandwidth = BANDWIDTH_8_MHZ; - //Transmission Mode - if(! strcmp(transm, "TRANSMISSION_MODE_2K")) tuner->TransmissionMode = TRANSMISSION_MODE_2K; - else if(! strcmp(transm, "TRANSMISSION_MODE_8K")) tuner->TransmissionMode = TRANSMISSION_MODE_8K; - //Guard Interval - if(! strcmp(gi, "GUARD_INTERVAL_1_32")) tuner->guardInterval = GUARD_INTERVAL_1_32; - else if(! strcmp(gi, "GUARD_INTERVAL_1_16")) tuner->guardInterval = GUARD_INTERVAL_1_16; - else if(! strcmp(gi, "GUARD_INTERVAL_1_8")) tuner->guardInterval = GUARD_INTERVAL_1_8; - else tuner->guardInterval = GUARD_INTERVAL_1_4; - //Hierarchy - if(! strcmp(hier, "HIERARCHY_1")) tuner->hierarchy = HIERARCHY_1; - else if(! strcmp(hier, "HIERARCHY_2")) tuner->hierarchy = HIERARCHY_2; - else if(! strcmp(hier, "HIERARCHY_4")) tuner->hierarchy = HIERARCHY_4; - else if(! strcmp(hier, "HIERARCHY_AUTO")) tuner->hierarchy = HIERARCHY_AUTO; - else tuner->hierarchy = HIERARCHY_NONE; - - break; - } - } - } - fclose(chanfile); - sprintf(frontend_name, "/dev/dvb/adapter%d/frontend0", adapter_num); - sprintf(demux_name, "/dev/dvb/adapter%d/demux0", adapter_num); - sprintf(dvr_name, "/dev/dvb/adapter%d/dvr0", adapter_num); - - // Open frontend - if((front1 = open(frontend_name,O_RDWR|O_NONBLOCK)) < 0){ - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Cannot open frontend %s.\n", frontend_name)); - return GF_IO_ERR; - } else { - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("Frontend %s opened.\n", frontend_name)); - } - // Open demuxes - if ((demux1=open(demux_name, O_RDWR|O_NONBLOCK)) < 0){ - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Cannot open demux %s\n", demux_name)); - return GF_IO_ERR; - } else { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Demux %s opened.\n", demux_name)); - } - // Set FrontendParameters - DVB-T - frp.frequency = tuner->freq; - frp.inversion = tuner->specInv; - frp.u.ofdm.bandwidth = tuner->bandwidth; - frp.u.ofdm.code_rate_HP = tuner->HP_CodeRate; - frp.u.ofdm.code_rate_LP = tuner->LP_CodeRate; - frp.u.ofdm.constellation = tuner->modulation; - frp.u.ofdm.transmission_mode = tuner->TransmissionMode; - frp.u.ofdm.guard_interval = tuner->guardInterval; - frp.u.ofdm.hierarchy_information = tuner->hierarchy; - // Set frontend - if (ioctl(front1, FE_SET_FRONTEND, &frp) < 0){ - return GF_IO_ERR; - } - // Set dumex - pesFilterParams.pid = 0x2000; // Linux-DVB API take PID=2000 for FULL/RAW TS flag - pesFilterParams.input = DMX_IN_FRONTEND; - pesFilterParams.output = DMX_OUT_TS_TAP; - pesFilterParams.pes_type = DMX_PES_OTHER; - pesFilterParams.flags = DMX_IMMEDIATE_START; - if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ - return GF_IO_ERR; - } - /* The following code differs from mplayer and alike because the device is opened in blocking mode */ - if ((tuner->ts_fd = open(dvr_name, O_RDONLY/*|O_NONBLOCK*/)) < 0){ - return GF_IO_ERR; - } - return GF_OK; -} -#endif +static void M2TS_GetNetworkType(GF_InputService *plug,M2TSIn *reader); static Bool M2TS_CanHandleURL(GF_InputService *plug, const char *url) { @@ -281,7 +84,7 @@ static Bool M2TS_CanHandleURL(GF_InputService *plug, const char *url) || !strnicmp(url, "dvb://", 6) #endif ) { - return 1; + return 1; } sExt = strrchr(url, '.'); @@ -294,55 +97,23 @@ static Bool M2TS_CanHandleURL(GF_InputService *plug, const char *url) return 0; } -#ifdef GPAC_HAS_LINUX_DVB -static u32 gf_dvb_get_freq_from_url(const char *channels_config_path, const char *url) -{ - FILE *channels_config_file; - char line[255], name[255], *tmp, *channel_name; - - u32 freq; - - /* get rid of trailing @ */ - tmp = strchr(url, '@'); - if (tmp) tmp[0] = 0; - - channel_name = url+6; - - channels_config_file = gf_f64_open(channels_config_path, "r"); - if (!channels_config_file) return GF_BAD_PARAM; - - freq = 0; - while(!feof(channels_config_file)) { - if ( fgets(line, 255, channels_config_file) != NULL) { - if (line[0]=='#') continue; - if (line[0]=='\r') continue; - if (line[0]=='\n') continue; - - tmp = strchr(line, ':'); - tmp[0] = 0; - if (!strcmp(line, channel_name)) { - char *tmp2; - tmp++; - tmp2 = strchr(tmp, ':'); - if (tmp2) tmp2[0] = 0; - freq = (u32)atoi(tmp); - break; - } - } - } - return freq; -} -#endif - static Bool M2TS_CanHandleURLInService(GF_InputService *plug, const char *url) { Bool ret = 0; M2TSIn *m2ts; - if (!plug || !url) - return 0; - m2ts = (M2TSIn *)plug->priv; - if (!m2ts) - return 0; + + if (!plug || !url) + return 0; + m2ts = (M2TSIn *)plug->priv; + if (!m2ts) + return 0; + + if (!strnicmp(url, "pid://", 6)) { + u32 pid = atoi(url+6); + if (pid>=GF_M2TS_MAX_STREAMS) return 0; + if (m2ts->ts->ess[pid]) return 1; + return 0; + } #ifdef GPAC_HAS_LINUX_DVB if (!stricmp(url, "dvb://EPG")) return 1; @@ -355,10 +126,10 @@ static Bool M2TS_CanHandleURLInService(GF_InputService *plug, const char *url) } /* if the tuner is already tuned to the same frequence, nothing needs to be done */ - else if (m2ts->tuner->freq != 0) { + else if (m2ts->ts->tuner->freq != 0) { char *frag = strchr(url, '#'); if (frag) frag[0] = 0; - if (m2ts->tuner->freq == gf_dvb_get_freq_from_url(chan_conf, url)) { + if (m2ts->ts->tuner->freq == gf_dvb_get_freq_from_url(chan_conf, url)) { GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[DVBIn] Reusing the same tuner for %s\n", url)); ret = 1; } @@ -375,7 +146,7 @@ static Bool M2TS_CanHandleURLInService(GF_InputService *plug, const char *url) } else { char *frag = strchr(url, '#'); if (frag) frag[0] = 0; - if (!strlen(url) || !strcmp(url, m2ts->filename)) { + if (!strlen(url) || !strcmp(url, m2ts->ts->filename)) { GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[DVBIn] Reusing the same input file for %s\n", url)); ret = 1; } @@ -422,7 +193,7 @@ static GF_ObjectDescriptor *MP2TS_GetOD(M2TSIn *m2ts, GF_M2TS_PES *stream, char case GF_M2TS_AUDIO_AAC: if (!dsi) { /*discard regulate until we fetch the AAC config*/ - m2ts->file_regulate = 0; + m2ts->ts->file_regulate = 0; /*turn on parsing*/ gf_m2ts_set_pes_framing(stream, GF_M2TS_PES_FRAMING_DEFAULT); gf_odf_desc_del((GF_Descriptor *)esd); @@ -461,8 +232,11 @@ static GF_ObjectDescriptor *MP2TS_GetOD(M2TSIn *m2ts, GF_M2TS_PES *stream, char /*declare object to terminal*/ od = (GF_ObjectDescriptor*)gf_odf_desc_new(GF_ODF_OD_TAG); gf_list_add(od->ESDescriptors, esd); - od->objectDescriptorID = esd->ESID; + od->objectDescriptorID = 0; if (streamType) *streamType = esd->decoderConfig->streamType; + /*remember program number for service/program selection*/ + od->ServiceID = stream->program->number; + od->service_ifce = m2ts->owner; return od; } @@ -477,25 +251,21 @@ static void MP2TS_DeclareStream(M2TSIn *m2ts, GF_M2TS_PES *stream, char *dsi, u3 static void MP2TS_SetupProgram(M2TSIn *m2ts, GF_M2TS_Program *prog, Bool regenerate_scene, Bool no_declare) { u32 i, count; - Bool force_declare_ods = 0; count = gf_list_count(prog->streams); #ifdef GPAC_HAS_LINUX_DVB - if (m2ts->tuner) { + if (m2ts->ts->tuner) { Bool found = 0; for (i=0; istreams, i); - if (pes->pid==m2ts->tuner->vpid) found = 1; - else if (pes->pid==m2ts->tuner->apid) found = 1; + if (pes->pid==m2ts->ts->tuner->vpid) found = 1; + else if (pes->pid==m2ts->ts->tuner->apid) found = 1; } if (!found) return; } #endif - if (m2ts->file || m2ts->dnload) m2ts->file_regulate = no_declare ? 0 : 1; + if (m2ts->ts->file || m2ts->ts->dnload) m2ts->ts->file_regulate = no_declare ? 0 : 1; - if (prog->pmt_iod && (prog->pmt_iod->tag==GF_ODF_IOD_TAG) && (((GF_InitialObjectDescriptor*)prog->pmt_iod)->OD_profileAndLevel==GPAC_MAGIC_OD_PROFILE_FOR_MPEG4_SIGNALING)) { - force_declare_ods = 1; - } for (i=0; istreams, i); if (es->pid==prog->pmt_pid) continue; @@ -505,11 +275,9 @@ static void MP2TS_SetupProgram(M2TSIn *m2ts, GF_M2TS_Program *prog, Bool regener if (!prog->pmt_iod && !no_declare) { MP2TS_DeclareStream(m2ts, (GF_M2TS_PES *)es, NULL, 0); - } else if (force_declare_ods) { - if ((es->stream_type!=GF_M2TS_SYSTEMS_MPEG4_PES) && (es->stream_type!=GF_M2TS_SYSTEMS_MPEG4_SECTIONS)) { - MP2TS_DeclareStream(m2ts, (GF_M2TS_PES *)es, NULL, 0); - } - } + } + /*if IOD, streams not declared through OD framework are refered to by pid:// scheme, and will be declared upon + request by the terminal through GetServiceDesc*/ } /*force scene regeneration*/ @@ -528,8 +296,13 @@ static void MP2TS_SendPacket(M2TSIn *m2ts, GF_M2TS_PES_PCK *pck) memset(&slh, 0, sizeof(GF_SLHeader)); slh.accessUnitStartFlag = (pck->flags & GF_M2TS_PES_PCK_AU_START) ? 1 : 0; if (slh.accessUnitStartFlag) { +#if 0 slh.OCRflag = 1; - slh.objectClockReference = pck->stream->program->last_pcr_value/300; + slh.m2ts_pcr = 1; + slh.objectClockReference = pck->stream->program->last_pcr_value; +#else + slh.OCRflag = 0; +#endif slh.compositionTimeStampFlag = 1; slh.compositionTimeStamp = pck->PTS; if (pck->DTS) { @@ -579,7 +352,8 @@ static GF_ObjectDescriptor *M2TS_GenerateEPG_OD(M2TSIn *m2ts) /*declare object to terminal*/ od = (GF_ObjectDescriptor*)gf_odf_desc_new(GF_ODF_OD_TAG); gf_list_add(od->ESDescriptors, esd); - od->objectDescriptorID = GF_M2TS_PID_EIT_ST_CIT; + od->objectDescriptorID = 0; + od->service_ifce = m2ts->owner; return od; } @@ -590,9 +364,9 @@ static void M2TS_FlushRequested(M2TSIn *m2ts) gf_mx_p(m2ts->mx); found = 0; - count = gf_list_count(m2ts->requested_pids); + count = gf_list_count(m2ts->ts->requested_pids); for (i=0; irequested_pids, i); + M2TSIn_Prog *req_pid = gf_list_get(m2ts->ts->requested_pids, i); GF_M2TS_ES *es = m2ts->ts->ess[req_pid->pid]; if (es==NULL) continue; @@ -600,15 +374,15 @@ static void M2TS_FlushRequested(M2TSIn *m2ts) if (!(es->flags & GF_M2TS_ES_IS_SECTION) && !es->user) gf_m2ts_set_pes_framing((GF_M2TS_PES *)es, GF_M2TS_PES_FRAMING_SKIP); MP2TS_DeclareStream(m2ts, (GF_M2TS_PES *)es, NULL, 0); - gf_list_rem(m2ts->requested_pids, i); + gf_list_rem(m2ts->ts->requested_pids, i); gf_free(req_pid); i--; count--; found++; } - req_prog_count = gf_list_count(m2ts->requested_progs); + req_prog_count = gf_list_count(m2ts->ts->requested_progs); for (i = 0; i < req_prog_count; i++) { - M2TSIn_Prog *req_prog = gf_list_get(m2ts->requested_progs, i); + M2TSIn_Prog *req_prog = gf_list_get(m2ts->ts->requested_progs, i); prog_id = atoi(req_prog->fragment); count = gf_list_count(m2ts->ts->SDTs); for (j=0; jfragment); gf_free(req_prog); - gf_list_rem(m2ts->requested_progs, i); + gf_list_rem(m2ts->ts->requested_progs, i); req_prog_count--; i--; break; @@ -653,22 +427,52 @@ static void M2TS_FlushRequested(M2TSIn *m2ts) static void M2TS_OnEvent(GF_M2TS_Demuxer *ts, u32 evt_type, void *param) { + GF_Event evt; M2TSIn *m2ts = (M2TSIn *) ts->user; + switch (evt_type) { case GF_M2TS_EVT_PAT_UPDATE: +/* example code showing how to forward an event from MPEG-2 TS input service to GPAC user*/ +#if 0 + { + GF_Event evt; + evt.type = GF_EVENT_FORWARDED; + evt.forwarded_event.forward_type = GF_EVT_FORWARDED_MPEG2; + evt.forwarded_event.forward_type = GF_EVT_FORWARDED_MPEG2; + evt.forwarded_event.service_event_type = evt_type; + evt.forwarded_event.param = param; + gf_term_on_service_event(m2ts->service, &evt); + } +#endif + break; + case GF_M2TS_EVT_AIT_FOUND: + evt.type = GF_EVENT_FORWARDED; + evt.forwarded_event.forward_type = GF_EVT_FORWARDED_MPEG2; + evt.forwarded_event.service_event_type = evt_type; + evt.forwarded_event.param = param; + gf_term_on_service_event(m2ts->service, &evt); break; case GF_M2TS_EVT_PAT_FOUND: - /* In case the TS has one program, wait for the PMT to send connect, in case of IOD in PMT */ - if (gf_list_count(m2ts->ts->programs) != 1) + /* In case the TS has one program, wait for the PMT to send connect, in case of IOD in PMT */ + if (gf_list_count(m2ts->ts->programs) != 1) { gf_term_on_connect(m2ts->service, NULL, GF_OK); + m2ts->is_connected = 1; + } + /* Send the TS to the a user if needed. Useful to check the number of received programs*/ + evt.type = GF_EVENT_FORWARDED; + evt.forwarded_event.forward_type = GF_M2TS_EVT_PAT_FOUND; + evt.forwarded_event.service_event_type = evt_type; + evt.forwarded_event.param = ts; + gf_term_on_service_event(m2ts->service, &evt); break; case GF_M2TS_EVT_PMT_FOUND: - if (gf_list_count(m2ts->ts->programs) == 1) + if (gf_list_count(m2ts->ts->programs) == 1) { gf_term_on_connect(m2ts->service, NULL, GF_OK); + m2ts->is_connected = 1; + } /*do not declare if single program was requested for playback*/ MP2TS_SetupProgram(m2ts, param, m2ts->request_all_pids, m2ts->request_all_pids ? 0 : 1); - M2TS_FlushRequested(m2ts); break; case GF_M2TS_EVT_PMT_REPEAT: @@ -698,7 +502,7 @@ static void M2TS_OnEvent(GF_M2TS_Demuxer *ts, u32 evt_type, void *param) if (!pck->stream->first_dts) { gf_m2ts_set_pes_framing(pck->stream, GF_M2TS_PES_FRAMING_SKIP_NO_RESET); MP2TS_DeclareStream(m2ts, pck->stream, pck->data, pck->data_len); - if (m2ts->file || m2ts->dnload) m2ts->file_regulate = 1; + if (ts->file || ts->dnload) ts->file_regulate = 1; pck->stream->first_dts=1; /*force scene regeneration*/ gf_term_add_media(m2ts->service, NULL, 0); @@ -717,33 +521,70 @@ static void M2TS_OnEvent(GF_M2TS_Demuxer *ts, u32 evt_type, void *param) } ((GF_M2TS_PES_PCK *) param)->stream->program->first_dts = 1; - if (m2ts->file_regulate) { + if ( ((GF_M2TS_PES_PCK *) param)->flags & GF_M2TS_PES_PCK_DISCONTINUITY) { +#if 0 + if (ts->pcr_last) { + ts->pcr_last = ((GF_M2TS_PES_PCK *) param)->PTS; + ts->stb_at_last_pcr = gf_sys_clock(); + } +#endif + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M2TS In] PCR discontinuity - switching from old STB "LLD" to new one "LLD"\n", ts->pcr_last, ((GF_M2TS_PES_PCK *) param)->PTS)); + /*FIXME - we need to find a way to treat PCR discontinuities correctly while ignoring broken PCR discontinuities + seen in many HLS solutions*/ + return; + } + + if (ts->file_regulate) { u64 pcr = ((GF_M2TS_PES_PCK *) param)->PTS; u32 stb = gf_sys_clock(); - if (m2ts->pcr_last) { + + if (m2ts->regulation_pcr_pid==0) { + /*we pick the first PCR PID for file regulation - we don't need to make sure this is the PCR of a program being plyaed as we + only check buffer levels, not DTS/PTS of the streams in the regulation step*/ + m2ts->regulation_pcr_pid = ((GF_M2TS_PES_PCK *) param)->stream->pid; + } else if (m2ts->regulation_pcr_pid != ((GF_M2TS_PES_PCK *) param)->stream->pid) { + return; + } + + + if (ts->pcr_last) { s32 diff; - u64 pcr_diff = (pcr - m2ts->pcr_last); - pcr_diff /= 27000; - diff = (u32) pcr_diff - (stb - m2ts->stb_at_last_pcr); + if (pcr < ts->pcr_last) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M2TS In] PCR "LLU" less than previous PCR "LLU"\n", ((GF_M2TS_PES_PCK *) param)->PTS, ts->pcr_last)); + ts->pcr_last = pcr; + ts->stb_at_last_pcr = gf_sys_clock(); + diff = 0; + } else { + u64 pcr_diff = (pcr - ts->pcr_last); + pcr_diff /= 27000; + if (pcr_diff>1000) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M2TS In] PCR diff too big: "LLU" ms - PCR "LLU" - previous PCR "LLU" - error in TS ?\n", pcr_diff, ((GF_M2TS_PES_PCK *) param)->PTS, ts->pcr_last)); + diff = 100; + } else { + diff = (u32) pcr_diff - (stb - ts->stb_at_last_pcr); + } + } if (diff<0) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[M2TS In] Demux not going fast enough according to PCR (drift %d, pcr: "LLD", last pcr: "LLD")\n", diff, pcr, m2ts->pcr_last)); + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[M2TS In] Demux not going fast enough according to PCR (drift %d, pcr: "LLU", last pcr: "LLU")\n", diff, pcr, ts->pcr_last)); } else if (diff>0) { - u32 sleep_for=50; + u32 sleep_for=1; #ifndef GPAC_DISABLE_LOG u32 nb_sleep=0; #endif /*query buffer level, don't sleep if too low*/ GF_NetworkCommand com; com.command_type = GF_NET_BUFFER_QUERY; - while (m2ts->run_state) { + while (ts->run_state) { gf_term_on_command(m2ts->service, &com, GF_OK); - if (com.buffer.occupancy < M2TS_BUFFER_MAX) + if (com.buffer.occupancy < M2TS_BUFFER_MAX) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[M2TS In] Demux not going to sleep: buffer occupancy %d ms\n", com.buffer.occupancy)); break; + } /*We don't sleep for the entire buffer occupancy, because we would take the risk of starving the audio chains. We try to keep buffers half full*/ #ifndef GPAC_DISABLE_LOG if (!nb_sleep) { - GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[M2TS In] Demux going to sleep (buffer occupancy %d ms)\n", com.buffer.occupancy)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[M2TS In] Demux going to sleep (buffer occupancy %d ms)\n", com.buffer.occupancy)); } nb_sleep++; #endif @@ -751,154 +592,54 @@ static void M2TS_OnEvent(GF_M2TS_Demuxer *ts, u32 evt_type, void *param) } #ifndef GPAC_DISABLE_LOG if (nb_sleep) { - GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[M2TS In] Demux resume after %d ms - current buffer occupancy %d ms\n", sleep_for*nb_sleep, com.buffer.occupancy)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[M2TS In] Demux resume after %d ms - current buffer occupancy %d ms\n", sleep_for*nb_sleep, com.buffer.occupancy)); } #endif - m2ts->nb_pck = 0; - m2ts->pcr_last = pcr; - m2ts->stb_at_last_pcr = gf_sys_clock(); + ts->nb_pck = 0; + ts->pcr_last = pcr; + ts->stb_at_last_pcr = gf_sys_clock(); } else { - GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[M2TS In] Demux drift according to PCR (drift %d, pcr: "LLD", last pcr: "LLD")\n", diff, pcr, m2ts->pcr_last)); + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[M2TS In] Demux drift according to PCR (drift %d, pcr: "LLD", last pcr: "LLD")\n", diff, pcr, ts->pcr_last)); } } else { - m2ts->pcr_last = pcr; - m2ts->stb_at_last_pcr = gf_sys_clock(); + ts->pcr_last = pcr; + ts->stb_at_last_pcr = gf_sys_clock(); } } break; - } -} - - -u32 M2TS_Run(void *_p) -{ - GF_Err e; - char data[UDP_BUFFER_SIZE]; -#ifdef GPAC_HAS_LINUX_DVB - char dvbts[DVB_BUFFER_SIZE]; -#endif - u32 size, i; - M2TSIn *m2ts = _p; - - m2ts->run_state = 1; - m2ts->ts->on_event = M2TS_OnEvent; - gf_m2ts_reset_parsers(m2ts->ts); - - -#ifdef GPAC_HAS_LINUX_DVB - if (m2ts->tuner) { - // in case of DVB - while (m2ts->run_state) { - s32 ts_size = read(m2ts->tuner->ts_fd, dvbts, DVB_BUFFER_SIZE); - if (ts_size>0) gf_m2ts_process_data(m2ts->ts, dvbts, (u32) ts_size); - } - } else -#endif - if (m2ts->sock) { - Bool first_run, is_rtp; - first_run = 1; - is_rtp = 0; - while (m2ts->run_state) { - size = 0; - /*m2ts chunks by chunks*/ - e = gf_sk_receive(m2ts->sock, data, UDP_BUFFER_SIZE, 0, &size); - if (!size || e) { - gf_sleep(0); - continue; - } - if (first_run) { - first_run = 0; - /*FIXME: we assume only simple RTP packaging (no CSRC nor extensions)*/ - if ((data[0] != 0x47) && ((data[1] & 0x7F) == 33) ) { - is_rtp = 1; - } - } - /*process chunk*/ - if (is_rtp) { - gf_m2ts_process_data(m2ts->ts, data+12, size-12); - } else { - gf_m2ts_process_data(m2ts->ts, data, size); - } - } - } else if (m2ts->dnload) { - while (m2ts->run_state) { - gf_dm_sess_process(m2ts->dnload); - gf_sleep(1); - } - } else if (m2ts->file) { - u64 pos = 0; - if (m2ts->start_range && m2ts->duration) { - Double perc = m2ts->start_range / (1000 * m2ts->duration); - pos = (u64) (perc * m2ts->file_size); - /*align to TS packet size*/ - while (pos%188) pos++; - if (pos>=m2ts->file_size) { - m2ts->start_range = 0; - pos = 0; - } - } - gf_f64_seek(m2ts->file, pos, SEEK_SET); -restart_file: - while (m2ts->run_state && !feof(m2ts->file) ) { - /*m2ts chunks by chunks*/ - size = fread(data, 1, 188, m2ts->file); - if (!size) break; - if (size != 188){ - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[M2TS In] %u bytes read from file instead of 188.\n", size)); - } - /*process chunk*/ - gf_m2ts_process_data(m2ts->ts, data, size); - - m2ts->nb_pck++; - /*if asked to regulate, wait until we get a play request*/ - if (m2ts->run_state && !m2ts->nb_playing && m2ts->file_regulate) { - while (m2ts->run_state && !m2ts->nb_playing && m2ts->file_regulate) { - gf_sleep(50); + case GF_M2TS_EVT_TDT: + if (m2ts->hybrid_on) { + u32 i, count; + GF_M2TS_TDT_TOT *tdt = (GF_M2TS_TDT_TOT *)param; + GF_NetworkCommand com; + memset(&com, 0, sizeof(com)); + com.command_type = GF_NET_CHAN_MAP_TIME; + com.map_time.media_time = tdt->hour*3600+tdt->minute*60+tdt->second; + com.map_time.reset_buffers = 0; + count = gf_list_count(ts->programs); + for (i=0; iprograms, i); + u32 j, count2; + if (prog->tdt_found || !prog->last_pcr_value) /*map TDT one time, after we received a PCR*/ continue; + prog->tdt_found = 1; + count2 = gf_list_count(prog->streams); + com.map_time.timestamp = prog->last_pcr_value/300; + for (j=0; jstreams, j); + if (stream->user) { + com.base.on_channel = stream->user; + gf_term_on_command(m2ts->service, &com, GF_OK); + } } - } else if (m2ts->file) { - gf_sleep(0); - } - } - - if (feof(m2ts->file) && m2ts->owner && m2ts->owner->query_proxy) { - GF_NetworkCommand param; - GF_Err query_ret; - fclose(m2ts->file); - m2ts->file = NULL; - param.command_type = GF_NET_SERVICE_QUERY_NEXT; - param.url_query.next_url = NULL; - assert(m2ts->owner); - assert( m2ts->owner->query_proxy); - query_ret = m2ts->owner->query_proxy(m2ts->owner, ¶m); - if ((query_ret==GF_OK) && param.url_query.next_url){ - m2ts->file = gf_f64_open(param.url_query.next_url, "rb"); - if (m2ts->file) { - goto restart_file; - } else { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M2TS In] Cannot open next file %s\n", param.url_query.next_url)); - } - } else { - if (query_ret==GF_OK){ - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M2TS In] Cannot query next file since no file was provided but no error was raised\n")); - } else - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M2TS In] Cannot query next file: error: %s\n", gf_error_to_string(query_ret))); - } - } - - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("\n[M2TS In]EOS reached, remaining segments=%u\n", m2ts->nb_playing)); - if (m2ts->nb_playing) { - for (i=0; its->ess[i]; - if (!pes || (pes->pid==pes->program->pmt_pid)) continue; - if (!pes->user || !pes->reframe) continue; - gf_term_on_sl_packet(m2ts->service, pes->user, NULL, 0, NULL, GF_EOS); - gf_m2ts_set_pes_framing(pes, GF_M2TS_PES_FRAMING_SKIP); + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[M2TS In] Mapping TDT Time %04d/%02d/%02d %02d:%02d:%02d and PCR time "LLD" on program %d\n", + tdt->year, tdt->month, tdt->day, tdt->hour, tdt->minute, tdt->second, com.map_time.timestamp, prog->number)); } } + break; + case GF_M2TS_EVT_TOT: + break; } - m2ts->run_state = 2; - return 0; } static void M2TS_OnEventPCR(GF_M2TS_Demuxer *ts, u32 evt_type, void *param) @@ -906,60 +647,22 @@ static void M2TS_OnEventPCR(GF_M2TS_Demuxer *ts, u32 evt_type, void *param) if (evt_type==GF_M2TS_EVT_PES_PCR) { M2TSIn *m2ts = ts->user; GF_M2TS_PES_PCK *pck = param; - if (!m2ts->nb_playing) { - m2ts->nb_playing = pck->stream->pid; - m2ts->end_range = (u32) (pck->PTS / 90); - } else if (m2ts->nb_playing == pck->stream->pid) { - m2ts->start_range = (u32) (pck->PTS / 90); + if (!ts->nb_playing) { + ts->nb_playing = pck->stream->pid; + ts->end_range = (u32) (pck->PTS / 90); + } else if (ts->nb_playing == pck->stream->pid) { + ts->start_range = (u32) (pck->PTS / 90); } } } -#ifdef GPAC_HAS_LINUX_DVB -void M2TS_SetupDVB(GF_InputService *plug, M2TSIn *m2ts, char *url) -{ - GF_Err e = GF_OK; - char *str; - const char *chan_conf; - - if (strnicmp(url, "dvb://", 6)) { - e = GF_NOT_SUPPORTED; - goto exit; - } - - chan_conf = gf_modules_get_option((GF_BaseInterface *)plug, "DVB", "ChannelsFile"); - if (!chan_conf) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[DVBIn] Cannot locate channel configuration file\n")); - e = GF_SERVICE_ERROR; - goto exit; - } - - if (!m2ts->tuner) GF_SAFEALLOC(m2ts->tuner, GF_Tuner); - - if (m2ts->tuner->freq != 0 && m2ts->tuner->freq == gf_dvb_get_freq_from_url(chan_conf, url)) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[DVBIn] Tuner already tuned to that frequency\n")); - goto exit; - } - - e = gf_dvb_tune(m2ts->tuner, url, chan_conf); - if (e) goto exit; - - m2ts->th = gf_th_new("MPEG-2 TS Demux"); - /*start playing for tune-in*/ - gf_th_run(m2ts->th, M2TS_Run, m2ts); - -exit: - if (e) gf_term_on_connect(m2ts->service, NULL, e); -} -#endif - void m2ts_net_io(void *cbk, GF_NETIO_Parameter *param) { GF_Err e; M2TSIn *m2ts = (M2TSIn *) cbk; assert( m2ts ); /*handle service message*/ - gf_term_download_update_stats(m2ts->dnload); + gf_term_download_update_stats(m2ts->ts->dnload); if (param->msg_type==GF_NETIO_DATA_TRANSFERED) { e = GF_EOS; @@ -979,18 +682,18 @@ void m2ts_net_io(void *cbk, GF_NETIO_Parameter *param) } /*if asked to regulate, wait until we get a play request*/ - if (m2ts->run_state && !m2ts->nb_playing && m2ts->file_regulate) { - while (m2ts->run_state && !m2ts->nb_playing && m2ts->file_regulate) { + if (m2ts->ts->run_state && !m2ts->ts->nb_playing && m2ts->ts->file_regulate) { + while (m2ts->ts->run_state && !m2ts->ts->nb_playing && m2ts->ts->file_regulate) { gf_sleep(50); continue; } } else { gf_sleep(1); } - if (!m2ts->run_state){ - if (m2ts->dnload) - gf_term_download_del( m2ts->dnload ); - m2ts->dnload = NULL; + if (!m2ts->ts->run_state) { + if (m2ts->ts->dnload) + gf_term_download_del( m2ts->ts->dnload ); + m2ts->ts->dnload = NULL; } } else { @@ -999,224 +702,93 @@ void m2ts_net_io(void *cbk, GF_NETIO_Parameter *param) switch (e){ case GF_EOS: - gf_term_on_connect(m2ts->service, NULL, GF_OK); - return; + if (!m2ts->is_connected) { + gf_term_on_connect(m2ts->service, NULL, GF_OK); + } + return; case GF_OK: - return; + return; default: - if (!m2ts->ts_setup) { - m2ts->ts_setup = 1; - } - GF_LOG( GF_LOG_ERROR, GF_LOG_CONTAINER, - ("[MPEGTSIn] : Error while getting data : %s\n", gf_error_to_string(e))); - gf_term_on_connect(m2ts->service, NULL, e); + if (!m2ts->ts_setup) { + m2ts->ts_setup = 1; + } + GF_LOG( GF_LOG_ERROR, GF_LOG_CONTAINER,("[MPEGTSIn] : Error while getting data : %s\n", gf_error_to_string(e))); + gf_term_on_connect(m2ts->service, NULL, e); } } -void M2TS_SetupLive(GF_InputService *plug, M2TSIn *m2ts, char *url) +static const char *M2TS_QueryNextFile(void *udta) { - GF_Err e = GF_OK; - char *str; - u16 port; - u32 sock_type = 0; - - if (!strnicmp(url, "udp://", 6) || !strnicmp(url, "mpegts-udp://", 13)) { - sock_type = GF_SOCK_TYPE_UDP; - } else if (!strnicmp(url, "mpegts-tcp://", 13) ) { - sock_type = GF_SOCK_TYPE_TCP; + GF_NetworkCommand param; + GF_Err query_ret; + M2TSIn *m2ts = (M2TSIn *) udta; + assert(m2ts->owner); + assert( m2ts->owner->query_proxy); + + param.command_type = GF_NET_SERVICE_QUERY_NEXT; + param.url_query.next_url = NULL; + query_ret = m2ts->owner->query_proxy(m2ts->owner, ¶m); + if ((query_ret==GF_OK) && param.url_query.next_url){ + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[M2TS In] Switching to next segment %s\n", param.url_query.next_url)); + return param.url_query.next_url; + } else if (query_ret==GF_OK){ + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M2TS In] Cannot query next file: no file provided but no error raised\n")); } else { - e = GF_NOT_SUPPORTED; - goto exit; - } - - url = strchr(url, ':'); - url += 3; - - m2ts->sock = gf_sk_new(sock_type); - if (!m2ts->sock) { e = GF_IO_ERR; goto exit; } - - /*setup port and src*/ - port = 1234; - str = strrchr(url, ':'); - /*take care of IPv6 address*/ - if (str && strchr(str, ']')) str = strchr(url, ':'); - if (str) { - port = atoi(str+1); - str[0] = 0; - } - - /*do we have a source ?*/ - if (strlen(url) && strcmp(url, "localhost") ) { - const char *mob_ip = NULL; - const char *mob_on = gf_modules_get_option((GF_BaseInterface*)plug, "Network", "MobileIPEnabled"); - if (mob_on && !strcmp(mob_on, "yes")) - mob_ip = gf_modules_get_option((GF_BaseInterface*)plug, "Network", "MobileIP"); - - if (gf_sk_is_multicast_address(url)) { - const char *mcast_ifce = gf_modules_get_option((GF_BaseInterface *) plug, "Network", "DefaultMCastInterface"); - if (mcast_ifce) mob_ip = mcast_ifce; - - gf_sk_setup_multicast(m2ts->sock, url, port, 0, 0, (char*)mob_ip); - } else { - gf_sk_bind(m2ts->sock, (char*)mob_ip, port, url, 0, GF_SOCK_REUSE_PORT); - } - } else { - gf_sk_bind(m2ts->sock, NULL, port, NULL, 0, GF_SOCK_REUSE_PORT); - } - if (str) str[0] = ':'; - - gf_sk_set_buffer_size(m2ts->sock, 0, UDP_BUFFER_SIZE); - gf_sk_set_block_mode(m2ts->sock, 0); - - m2ts->th = gf_th_new("MPEG-2 TS Demux"); - /*start playing for tune-in*/ - gf_th_run(m2ts->th, M2TS_Run, m2ts); - -exit: - if (e) { - gf_term_on_connect(m2ts->service, NULL, e); - } + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M2TS In] Cannot query next file: error: %s\n", gf_error_to_string(query_ret))); + } + return NULL; } -void M2TS_SetupFile(M2TSIn *m2ts, char *url) -{ -#if 0 - char data[188]; - u64 size, fsize; - s32 nb_rwd; -#endif - if (m2ts->file && !strcmp(m2ts->filename, url)) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEGTSIn] TS already being processed\n")); - return; - } - - m2ts->file = gf_f64_open(url, "rb"); - if (!m2ts->file) { - gf_term_on_connect(m2ts->service, NULL, GF_URL_ERROR); - return; - } - strcpy(m2ts->filename, url); - - gf_f64_seek(m2ts->file, 0, SEEK_END); - m2ts->file_size = gf_f64_tell(m2ts->file); - -#if 0 - /* - estimate duration by reading the end of the file - m2ts->end_range is initialized to the PTS of the last TS packet - m2ts->nb_playing is initialized to the PID of the last TS packet - */ - m2ts->nb_playing = 0; - m2ts->ts->on_event = M2TS_OnEventPCR; - m2ts->end_range = 0; - nb_rwd = 1; - fsize = m2ts->file_size; - while (fsize % 188) fsize--; - while (1) { - gf_f64_seek(m2ts->file, fsize - 188 * nb_rwd, SEEK_SET); - /*m2ts chunks by chunks*/ - size = fread(data, 1, 188, m2ts->file); - if (!size) break; - /*process chunk*/ - gf_m2ts_process_data(m2ts->ts, data, size); - if (m2ts->nb_playing) break; - nb_rwd ++; - } - - /* - reset of the file - initialization of m2ts->start_range to the PTS of the first TS packet with PID = m2ts->nb_playing - */ - gf_f64_seek(m2ts->file, 0, SEEK_SET); - gf_m2ts_reset_parsers(m2ts->ts); - m2ts->start_range = 0; - while (1) { - /*m2ts chunks by chunks*/ - size = fread(data, 1, 188, m2ts->file); - if (!size) break; - /*process chunk*/ - gf_m2ts_process_data(m2ts->ts, data, size); - if (m2ts->start_range) break; - } - m2ts->duration = (m2ts->end_range - m2ts->start_range) / 300000.0; - gf_m2ts_demux_del(m2ts->ts); - - /* Creation of the real demuxer for playback */ - m2ts->ts = gf_m2ts_demux_new(); - m2ts->ts->user = m2ts; -#endif - - /* reinitialization for seek */ - m2ts->end_range = m2ts->start_range = 0; - m2ts->nb_playing = 0; - - m2ts->th = gf_th_new("MPEG-2 TS Demux"); - /*start playing for tune-in*/ - gf_th_run(m2ts->th, M2TS_Run, m2ts); -} static GF_Err M2TS_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url) { - char szURL[2048]; - char *frag; + GF_Err e; + const char *opt; M2TSIn *m2ts = plug->priv; - m2ts->owner = plug; - m2ts->service = serv; - strcpy(szURL, url); - frag = strrchr(szURL, '#'); - if (frag) frag[0] = 0; + M2TS_GetNetworkType(plug,m2ts); - m2ts->file_regulate = 0; - m2ts->duration = 0; + m2ts->owner = plug; - if (!strnicmp(url, "udp://", 6) - || !strnicmp(url, "mpegts-udp://", 13) - || !strnicmp(url, "mpegts-tcp://", 13) - ) { - M2TS_SetupLive(plug, m2ts, (char *) szURL); + opt = gf_modules_get_option((GF_BaseInterface *)m2ts->owner, "HybRadio", "Activated"); + if (opt && !strcmp(opt, "true")) { + m2ts->hybrid_on = 1; } -#ifdef GPAC_HAS_LINUX_DVB - else if (!strnicmp(url, "dvb://", 6)) { - // DVB Setup - M2TS_SetupDVB(plug, m2ts, (char *) szURL); + + m2ts->service = serv; + if (m2ts->owner->query_proxy) { + m2ts->ts->query_next = M2TS_QueryNextFile; + m2ts->ts->udta_query = m2ts; } -#endif - else if (!strnicmp(url, "http://", 7)) { - - m2ts->dnload = gf_term_download_new(m2ts->service, url, GF_NETIO_SESSION_NOT_THREADED | GF_NETIO_SESSION_NOT_CACHED, m2ts_net_io, m2ts); - if (!m2ts->dnload) gf_term_on_connect(m2ts->service, NULL, GF_NOT_SUPPORTED); - else { - m2ts->th = gf_th_new("MPEG-2 TS Demux"); - /*start playing for tune-in*/ - gf_th_run(m2ts->th, M2TS_Run, m2ts); + + if (!strnicmp(url, "http://", 7)) { + m2ts->ts->dnload = gf_term_download_new(m2ts->service, url, GF_NETIO_SESSION_NOT_THREADED | GF_NETIO_SESSION_NOT_CACHED, m2ts_net_io, m2ts); + if (!m2ts->ts->dnload){ + gf_term_on_connect(m2ts->service, NULL, GF_NOT_SUPPORTED); + return GF_OK; + } else { + e = TSDemux_DemuxPlay(m2ts->ts); } + } else { + e = TSDemux_Demux_Setup(m2ts->ts,url,0); } - else { - M2TS_SetupFile(m2ts, (char *) szURL); + + if (e) { + gf_term_on_connect(m2ts->service, NULL, e); } - return GF_OK; + return e; } static GF_Err M2TS_CloseService(GF_InputService *plug) { M2TSIn *m2ts = plug->priv; + GF_M2TS_Demuxer* ts = m2ts->ts; - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("destroying TSin\n")); - if (m2ts->th) { - if (m2ts->run_state == 1) { - m2ts->run_state = 0; - while (m2ts->run_state!=2) gf_sleep(0); - } - gf_th_del(m2ts->th); - m2ts->th = NULL; - } - - if (m2ts->file) fclose(m2ts->file); - m2ts->file = NULL; - - if (m2ts->dnload) gf_term_download_del(m2ts->dnload); - m2ts->dnload = NULL; + TSDemux_CloseDemux(ts); + + + if (ts->dnload) gf_term_download_del(ts->dnload); + ts->dnload = NULL; gf_term_on_disconnect(m2ts->service, NULL, GF_OK); return GF_OK; @@ -1227,6 +799,15 @@ static GF_Descriptor *M2TS_GetServiceDesc(GF_InputService *plug, u32 expect_type M2TSIn *m2ts = plug->priv; GF_Descriptor *desc = NULL; char *frag; + M2TSIn_Prog *prog; + + if (sub_url && !strnicmp(sub_url, "pid://", 6)) { + GF_ObjectDescriptor *od; + u32 pid = atoi(sub_url+6); + if (pid>=GF_M2TS_MAX_STREAMS) return NULL; + od = MP2TS_GetOD(m2ts, (GF_M2TS_PES*) m2ts->ts->ess[pid], NULL, 0, NULL); + return (GF_Descriptor *) od; + } frag = sub_url ? strrchr(sub_url, '#') : NULL; if (frag) frag++; @@ -1239,39 +820,39 @@ static GF_Descriptor *M2TS_GetServiceDesc(GF_InputService *plug, u32 expect_type if (!frag) { m2ts->request_all_pids = 1; } else { - M2TSIn_Prog *prog; - /*we need exclusive access*/ gf_mx_p(m2ts->mx); if (!strnicmp(frag, "pid=", 4)) { GF_SAFEALLOC(prog, M2TSIn_Prog); prog->pid = atoi(frag+4); - gf_list_add(m2ts->requested_pids, prog); + gf_list_add(m2ts->ts->requested_pids, prog); } else if (!strnicmp(frag, "EPG", 3)) { m2ts->epg_requested = 1; } else { u32 i, count; - count = gf_list_count(m2ts->requested_progs); + count = gf_list_count(m2ts->ts->requested_progs); prog = NULL; for (i=0; irequested_progs, i); + prog = gf_list_get(m2ts->ts->requested_progs, i); if (!strcmp(prog->fragment, frag)) break; prog = NULL; } if (!prog) { GF_SAFEALLOC(prog, M2TSIn_Prog); - gf_list_add(m2ts->requested_progs, prog); + gf_list_add(m2ts->ts->requested_progs, prog); prog->fragment = gf_strdup(frag); } } gf_mx_v(m2ts->mx); } - if (expect_type==GF_MEDIA_OBJECT_SCENE) { + /*if type is undefined, check the PMT for an IOD*/ + if (expect_type<=GF_MEDIA_OBJECT_SCENE) { if (gf_list_count(m2ts->ts->programs) == 1) { GF_M2TS_Program *prog = gf_list_get(m2ts->ts->programs, 0); if (prog->pmt_iod) { + m2ts->request_all_pids = 0; gf_odf_desc_copy((GF_Descriptor *)prog->pmt_iod, &desc); return desc; } @@ -1289,9 +870,9 @@ static GF_Descriptor *M2TS_GetServiceDesc(GF_InputService *plug, u32 expect_type } /* restart the thread if the same service is reused and if the previous thread terminated */ - if (m2ts->run_state == 2) { - m2ts->file_regulate = 0; - gf_th_run(m2ts->th, M2TS_Run, m2ts); + if (m2ts->ts->run_state == 2) { + m2ts->ts->file_regulate = 0; + TSDemux_DemuxPlay(m2ts->ts); } return NULL; @@ -1316,7 +897,10 @@ static GF_Err M2TS_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, c for (i=0; its->ess[i]; if (!pes || (pes->pid==pes->program->pmt_pid)) continue; - if (pes->mpeg4_es_id == ES_ID) { + if ((pes->mpeg4_es_id == ES_ID) + /*for pid:// url*/ + || (!pes->mpeg4_es_id && (pes->pid == ES_ID)) + ) { if (pes->user) { e = GF_SERVICE_ERROR; gf_term_on_connect(m2ts->service, channel, e); @@ -1379,6 +963,7 @@ static GF_Err M2TS_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) { GF_M2TS_PES *pes; M2TSIn *m2ts = plug->priv; + GF_M2TS_Demuxer *ts = m2ts->ts; if (com->command_type==GF_NET_SERVICE_HAS_AUDIO) { char *frag = strchr(com->audio.base_url, '#'); @@ -1398,7 +983,7 @@ static GF_Err M2TS_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) com->buffer.min = 0; return GF_OK; case GF_NET_CHAN_DURATION: - com->duration.duration = m2ts->duration; + com->duration.duration = ts->duration; return GF_OK; case GF_NET_CHAN_PLAY: pes = M2TS_GetChannel(m2ts, com->base.on_channel); @@ -1413,15 +998,15 @@ static GF_Err M2TS_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) gf_m2ts_set_pes_framing(pes, GF_M2TS_PES_FRAMING_DEFAULT); GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[M2TSIn] Setting default reframing for PID %d\n", pes->pid)); /*this is a multplex, only trigger the play command for the first stream activated*/ - if (!m2ts->nb_playing) { - m2ts->start_range = (u32) (com->play.start_range*1000); - m2ts->end_range = (com->play.end_range>0) ? (u32) (com->play.end_range*1000) : 0; + if (!ts->nb_playing) { + ts->start_range = (u32) (com->play.start_range*1000); + ts->end_range = (com->play.end_range>0) ? (u32) (com->play.end_range*1000) : 0; /*start demuxer*/ - if (m2ts->run_state!=1) { - gf_th_run(m2ts->th, M2TS_Run, m2ts); + if (ts->run_state!=1) { + return TSDemux_DemuxPlay(ts); } } - m2ts->nb_playing++; + ts->nb_playing++; return GF_OK; case GF_NET_CHAN_STOP: pes = M2TS_GetChannel(m2ts, com->base.on_channel); @@ -1434,15 +1019,15 @@ static GF_Err M2TS_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) gf_m2ts_set_pes_framing(pes, GF_M2TS_PES_FRAMING_SKIP); /* In case of EOS, we may receive a stop command after no one is playing */ - if (m2ts->nb_playing) - m2ts->nb_playing--; + if (ts->nb_playing) + ts->nb_playing--; /*stop demuxer*/ - if (!m2ts->nb_playing && (m2ts->run_state==1)) { - m2ts->run_state=0; - while (m2ts->run_state!=2) gf_sleep(2); - if (gf_list_count(m2ts->requested_progs)) { - m2ts->file_regulate = 0; - gf_th_run(m2ts->th, M2TS_Run, m2ts); + if (!ts->nb_playing && (ts->run_state==1)) { + ts->run_state=0; + while (ts->run_state!=2) gf_sleep(2); + if (gf_list_count(m2ts->ts->requested_progs)) { + ts->file_regulate = 0; + return TSDemux_DemuxPlay(ts); } } return GF_OK; @@ -1471,6 +1056,20 @@ static u32 M2TS_RegisterMimeTypes(const GF_InputService * service){ return i; } +static void M2TS_GetNetworkType(GF_InputService *plug,M2TSIn *reader) +{ + const char *mob_on; + const char *mcast_ifce; + + mob_on = gf_modules_get_option((GF_BaseInterface*)plug, "Network", "MobileIPEnabled"); + if(mob_on && !strcmp(mob_on, "yes")){ + reader->ts->MobileIPEnabled = 1; + reader->ts->network_type = gf_modules_get_option((GF_BaseInterface*)plug, "Network", "MobileIP"); + } + + mcast_ifce = gf_modules_get_option((GF_BaseInterface*)plug, "Network", "DefaultMCastInterface"); + if(mcast_ifce) reader->ts->network_type = gf_strdup(mcast_ifce); +} GF_InputService *NewM2TSReader() { @@ -1492,12 +1091,14 @@ GF_InputService *NewM2TSReader() reader = gf_malloc(sizeof(M2TSIn)); memset(reader, 0, sizeof(M2TSIn)); plug->priv = reader; - reader->requested_progs = gf_list_new(); - reader->requested_pids = gf_list_new(); reader->ts = gf_m2ts_demux_new(); reader->ts->on_event = M2TS_OnEvent; reader->ts->user = reader; + reader->ts->demux_and_play = 1; + reader->ts->th = gf_th_new("MPEG-2 TS Demux"); + reader->mx = gf_mx_new("MPEG2 Demux"); + return plug; } @@ -1511,25 +1112,25 @@ void DeleteM2TSReader(void *ifce) m2ts = plug->priv; if (!m2ts) return; - if( m2ts->requested_progs ){ - count = gf_list_count(m2ts->requested_progs); + if( m2ts->ts->requested_progs ){ + count = gf_list_count(m2ts->ts->requested_progs); for (i = 0; i < count; i++) { - M2TSIn_Prog *prog = gf_list_get(m2ts->requested_progs, i); + M2TSIn_Prog *prog = gf_list_get(m2ts->ts->requested_progs, i); gf_free(prog->fragment); gf_free(prog); } - gf_list_del(m2ts->requested_progs); + gf_list_del(m2ts->ts->requested_progs); } - m2ts->requested_progs = NULL; - if( m2ts->requested_pids ){ - count = gf_list_count(m2ts->requested_pids); + m2ts->ts->requested_progs = NULL; + if( m2ts->ts->requested_pids ){ + count = gf_list_count(m2ts->ts->requested_pids); for (i = 0; i < count; i++) { - M2TSIn_Prog *prog = gf_list_get(m2ts->requested_pids, i); + M2TSIn_Prog *prog = gf_list_get(m2ts->ts->requested_pids, i); gf_free(prog); } - gf_list_del(m2ts->requested_pids); + gf_list_del(m2ts->ts->requested_pids); } - m2ts->requested_pids = NULL; + m2ts->ts->requested_pids = NULL; if (m2ts->network_buffer) gf_free(m2ts->network_buffer); m2ts->network_buffer = NULL; diff --git a/modules/odf_dec/Makefile b/modules/odf_dec/Makefile index 3299357..4192681 100644 --- a/modules/odf_dec/Makefile +++ b/modules/odf_dec/Makefile @@ -31,7 +31,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_odf_dec-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_odf_dec-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static endif diff --git a/modules/odf_dec/odf_dec.c b/modules/odf_dec/odf_dec.c index ac05da3..c2bd4c4 100644 --- a/modules/odf_dec/odf_dec.c +++ b/modules/odf_dec/odf_dec.c @@ -236,14 +236,14 @@ err_exit: } -Bool ODF_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, GF_ESD *esd, u8 PL) +static u32 ODF_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, GF_ESD *esd, u8 PL) { ODPriv *priv = (ODPriv *)ifce->privateStack; if (StreamType==GF_STREAM_OD) { priv->PL = PL; - return 1; + return GF_CODEC_SUPPORTED; } - return 0; + return GF_CODEC_NOT_SUPPORTED; } diff --git a/modules/ogg/ogg_load.c b/modules/ogg/ogg_load.c index 5324336..fa7783a 100644 --- a/modules/ogg/ogg_load.c +++ b/modules/ogg/ogg_load.c @@ -25,47 +25,47 @@ #include "ogg_in.h" -static Bool OGG_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, u8 PL) +static u32 OGG_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, u8 PL) { /*video decs*/ if (StreamType == GF_STREAM_VISUAL) { char *dsi; /*media type query*/ - if (!esd) return 1; + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; dsi = esd->decoderConfig->decoderSpecificInfo ? esd->decoderConfig->decoderSpecificInfo->data : NULL; switch (esd->decoderConfig->objectTypeIndication) { #ifdef GPAC_HAS_THEORA case GPAC_OTI_MEDIA_OGG: if (dsi && (esd->decoderConfig->decoderSpecificInfo->dataLength>=9) && !strncmp((char *) &dsi[3], "theora", 6)) { - return NewTheoraDecoder(dec); + if (NewTheoraDecoder(dec)) return GF_CODEC_SUPPORTED; } - return 0; + return GF_CODEC_NOT_SUPPORTED; #endif default: - return 0; + return GF_CODEC_NOT_SUPPORTED; } } /*audio decs*/ if (StreamType == GF_STREAM_AUDIO) { char *dsi; /*media type query*/ - if (!esd) return 1; + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; dsi = esd->decoderConfig->decoderSpecificInfo ? esd->decoderConfig->decoderSpecificInfo->data : NULL; switch (esd->decoderConfig->objectTypeIndication) { #ifdef GPAC_HAS_VORBIS case GPAC_OTI_MEDIA_OGG: if (dsi && (esd->decoderConfig->decoderSpecificInfo->dataLength>=9) && !strncmp((char *) &dsi[3], "vorbis", 6)) { - return NewVorbisDecoder(dec); + if (NewVorbisDecoder(dec)) return GF_CODEC_SUPPORTED; } - return 0; + return GF_CODEC_NOT_SUPPORTED; #endif default: - return 0; + return GF_CODEC_NOT_SUPPORTED; } } - return 0; + return GF_CODEC_NOT_SUPPORTED; } diff --git a/modules/opensvc_dec/Makefile b/modules/opensvc_dec/Makefile index a4f65e4..dec8bf2 100644 --- a/modules/opensvc_dec/Makefile +++ b/modules/opensvc_dec/Makefile @@ -30,7 +30,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_opensvc_dec-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_opensvc_dec-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static endif diff --git a/modules/opensvc_dec/opensvc_dec.c b/modules/opensvc_dec/opensvc_dec.c index ed49fc0..20639f7 100644 --- a/modules/opensvc_dec/opensvc_dec.c +++ b/modules/opensvc_dec/opensvc_dec.c @@ -1,399 +1,399 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) Telecom ParisTech 2010- - * Author(s): Jean Le Feuvre - * All rights reserved - * - * This file is part of GPAC / OpenSVC Decoder module - * - * 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 -#include -#include - - -#if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(__GNUC__) -# pragma comment(lib, "OpenSVCDecoder") -#endif - -typedef struct{ - int Width; - int Height; - unsigned char* pY[1]; - unsigned char* pU[1]; - unsigned char* pV[1]; -} OPENSVCFRAME; - - -enum { - SVC_STATUS_ERROR = -1, - SVC_STATUS_OK = 0, // no error and no frame ready - SVC_IMAGE_READY = 1, // no error and image ready - SVC_GHOST_IMAGE = 2 // no image for chosen layer but image could be ready for other layers -}; - -int SVCDecoder_init(void **PlayerStruct); -int SVCDecoder_close(void *PlayerStruct); -//TODO -int decodeNAL(void *PlayerStruct, unsigned char* nal, int nal_length, OPENSVCFRAME *Frame, int *LayerCommand); -/*ID vient du NAL type 14 et 20*/ -//TODO -void SetCommandLayer(int *Command, int DqIdMax, int CurrDqId, int *TemporalCom, int TemporalId); -void ParseAuPlayers(void *PlayerStruct, const unsigned char *buf, int buf_size, int nal_length_size, int is_avc); -int GetDqIdMax(const unsigned char *buf, int buf_size, int nal_length_size, int *DqidTable, int is_avc); - - -typedef struct -{ - u16 ES_ID; - u32 width, stride, height, out_size, pixel_ar, layer; - Bool first_frame; - - u32 nalu_size_length; - - /*OpenSVC things*/ - void *codec; - int InitParseAU; - int svc_init_done; - int save_Width; - int save_Height; - int CurrDqId; - int MaxDqId; - int DqIdTable [8]; - int TemporalId; - int TemporalCom; -} OSVCDec; - -static GF_Err OSVC_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) -{ - u32 i, count; - s32 res; - OPENSVCFRAME Picture; - int Layer[4]; - OSVCDec *ctx = (OSVCDec*) ifcg->privateStack; - - /*not supported in this version*/ - if (esd->dependsOnESID) return GF_NOT_SUPPORTED; - - ctx->ES_ID = esd->ESID; - ctx->width = ctx->height = ctx->out_size = 0; - - if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) { - GF_AVCConfig *cfg = gf_odf_avc_cfg_read(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); - if (!cfg) return GF_NON_COMPLIANT_BITSTREAM; - ctx->nalu_size_length = cfg->nal_unit_size; - if (SVCDecoder_init(&ctx->codec) == SVC_STATUS_ERROR) return GF_IO_ERR; - - /*decode all NALUs*/ - count = gf_list_count(cfg->sequenceParameterSets); - SetCommandLayer(Layer, 255, 0, &i, 0);//bufindex can be reset without pb - for (i=0; isequenceParameterSets, i); - - gf_avc_get_sps_info(slc->data, slc->size, &slc->id, &w, &h, &par_n, &par_d); - /*by default use the base layer*/ - if (!i) { - if ((ctx->widthheightwidth = w; - ctx->height = h; - if ( ((s32)par_n>0) && ((s32)par_d>0) ) - ctx->pixel_ar = (par_n<<16) || par_d; - } - } - res = decodeNAL(ctx->codec, slc->data, slc->size, &Picture, Layer); - if (res<0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[SVC Decoder] Error decoding SPS %d\n", res)); - } - } - - count = gf_list_count(cfg->pictureParameterSets); - for (i=0; ipictureParameterSets, i); - res = decodeNAL(ctx->codec, slc->data, slc->size, &Picture, Layer); - if (res<0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[SVC Decoder] Error decoding PPS %d\n", res)); - } - } - - gf_odf_avc_cfg_del(cfg); - } else { - ctx->nalu_size_length = 0; - if (SVCDecoder_init(&ctx->codec) == SVC_STATUS_ERROR) return GF_IO_ERR; - } - ctx->stride = ctx->width + 32; - ctx->layer = 0; - ctx->CurrDqId = ctx->layer; - ctx->out_size = ctx->stride * ctx->height * 3 / 2; - return GF_OK; -} -static GF_Err OSVC_DetachStream(GF_BaseDecoder *ifcg, u16 ES_ID) -{ - OSVCDec *ctx = (OSVCDec*) ifcg->privateStack; - - if (ctx->codec) SVCDecoder_close(ctx->codec); - ctx->codec = NULL; - ctx->width = ctx->height = ctx->out_size = 0; - return GF_OK; -} -static GF_Err OSVC_GetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability *capability) -{ - OSVCDec *ctx = (OSVCDec*) ifcg->privateStack; - - switch (capability->CapCode) { - case GF_CODEC_RESILIENT: - capability->cap.valueInt = 1; - break; - case GF_CODEC_WIDTH: - capability->cap.valueInt = ctx->width; - break; - case GF_CODEC_HEIGHT: - capability->cap.valueInt = ctx->height; - break; - case GF_CODEC_STRIDE: - capability->cap.valueInt = ctx->stride; - break; - case GF_CODEC_PAR: - capability->cap.valueInt = ctx->pixel_ar; - break; - case GF_CODEC_OUTPUT_SIZE: - capability->cap.valueInt = ctx->out_size; - break; - case GF_CODEC_PIXEL_FORMAT: - capability->cap.valueInt = GF_PIXEL_YV12; - break; - case GF_CODEC_BUFFER_MIN: - capability->cap.valueInt = 1; - break; - case GF_CODEC_BUFFER_MAX: - capability->cap.valueInt = 4; - break; - case GF_CODEC_PADDING_BYTES: - capability->cap.valueInt = 32; - break; - case GF_CODEC_REORDER: - capability->cap.valueInt = 1; - break; - /*not known at our level...*/ - case GF_CODEC_CU_DURATION: - default: - capability->cap.valueInt = 0; - break; - } - return GF_OK; -} -static GF_Err OSVC_SetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability capability) -{ - OSVCDec *ctx = (OSVCDec*) ifcg->privateStack; - switch (capability.CapCode) { - case GF_CODEC_MEDIA_SWITCH_QUALITY: - if (capability.cap.valueInt) { - if (ctx->layer<32) { - ctx->layer += 8; - ctx->CurrDqId = ctx->layer; - } - } else { - if (ctx->layer>=8) { - ctx->layer -= 8; - ctx->CurrDqId = ctx->layer; - } - } - return GF_OK; - } - /*return unsupported to avoid confusion by the player (like color space changing ...) */ - return GF_NOT_SUPPORTED; - -} - -static GF_Err OSVC_ProcessData(GF_MediaDecoder *ifcg, - char *inBuffer, u32 inBufferLength, - u16 ES_ID, - char *outBuffer, u32 *outBufferLength, - u8 PaddingBits, u32 mmlevel) -{ - - s32 got_pic; - OPENSVCFRAME pic; - int Layer[4]; - OSVCDec *ctx = (OSVCDec*) ifcg->privateStack; - - if (!ES_ID || (ES_ID!=ctx->ES_ID) || !ctx->codec) { - *outBufferLength = 0; - return GF_OK; - } - if (*outBufferLength < ctx->out_size) { - *outBufferLength = ctx->out_size; - return GF_BUFFER_TOO_SMALL; - } - - got_pic = 0; - if (ctx->nalu_size_length) { - u32 i, nalu_size = 0; - u8 *ptr = inBuffer; - - ctx->MaxDqId = GetDqIdMax(inBuffer, inBufferLength, ctx->nalu_size_length, ctx->DqIdTable, 1); - if(!ctx->InitParseAU){ - if (ctx->MaxDqId == -1) { - //AVC stream in a h264 file - ctx->MaxDqId = 0; - } else { - //Firts time only, we parse the first AU to know the file configuration - //does not need to ba called again ever after, unless SPS or PPS changed - ParseAuPlayers(ctx->codec, inBuffer, inBufferLength, ctx->nalu_size_length, 1); - } - ctx->InitParseAU = 1; - } - SetCommandLayer(Layer, ctx->MaxDqId, ctx->CurrDqId, &ctx->TemporalCom, ctx->TemporalId); - - while (inBufferLength) { - for (i=0; inalu_size_length; i++) { - nalu_size = (nalu_size<<8) + ptr[i]; - } - ptr += ctx->nalu_size_length; - - if (!got_pic) - got_pic = decodeNAL(ctx->codec, ptr, nalu_size, &pic, Layer); - else - decodeNAL(ctx->codec, ptr, nalu_size, &pic, Layer); - - ptr += nalu_size; - if (inBufferLength < nalu_size + ctx->nalu_size_length) break; - - inBufferLength -= nalu_size + ctx->nalu_size_length; - } - } else { - } - if (got_pic!=1) return GF_OK; - - if ((pic.Width != ctx->width) || (pic.Height!=ctx->height)) { - ctx->width = pic.Width; - ctx->stride = pic.Width + 32; - ctx->height = pic.Height; - ctx->out_size = ctx->stride * ctx->height * 3 / 2; - - /*always force layer resize*/ - *outBufferLength = ctx->out_size; - return GF_BUFFER_TOO_SMALL; - } - *outBufferLength = ctx->out_size; - memcpy(outBuffer, pic.pY[0], ctx->stride*ctx->height); - memcpy(outBuffer + ctx->stride * ctx->height, pic.pU[0], ctx->stride*ctx->height/4); - memcpy(outBuffer + 5*ctx->stride * ctx->height/4, pic.pV[0], ctx->stride*ctx->height/4); - - return GF_OK; -} - -static Bool OSVC_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, u8 PL) -{ - if (StreamType != GF_STREAM_VISUAL) return 0; - - /*media type query*/ - if (!esd) return 1; - - switch (esd->decoderConfig->objectTypeIndication) { - case GPAC_OTI_VIDEO_AVC: - if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) { - Bool is_svc = 0; - u32 i, count; - GF_AVCConfig *cfg = gf_odf_avc_cfg_read(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); - if (!cfg) return 0; - - /*decode all NALUs*/ - count = gf_list_count(cfg->sequenceParameterSets); - for (i=0; isequenceParameterSets, i); - u8 nal_type = slc->data[0] & 0x1F; - - if (nal_type==GF_AVC_NALU_SVC_SUBSEQ_PARAM) { - is_svc = 1; - break; - } - } - gf_odf_avc_cfg_del(cfg); - return is_svc; - } - return 1; - } - return 0; -} - -static const char *OSVC_GetCodecName(GF_BaseDecoder *dec) -{ - return "OpenSVC Decoder"; -} - -GF_BaseDecoder *NewOSVCDec() -{ - GF_MediaDecoder *ifcd; - OSVCDec *dec; - - GF_SAFEALLOC(ifcd, GF_MediaDecoder); - GF_SAFEALLOC(dec, OSVCDec); - GF_REGISTER_MODULE_INTERFACE(ifcd, GF_MEDIA_DECODER_INTERFACE, "OpenSVC Decoder", "gpac distribution") - - ifcd->privateStack = dec; - - /*setup our own interface*/ - ifcd->AttachStream = OSVC_AttachStream; - ifcd->DetachStream = OSVC_DetachStream; - ifcd->GetCapabilities = OSVC_GetCapabilities; - ifcd->SetCapabilities = OSVC_SetCapabilities; - ifcd->GetName = OSVC_GetCodecName; - ifcd->CanHandleStream = OSVC_CanHandleStream; - ifcd->ProcessData = OSVC_ProcessData; - return (GF_BaseDecoder *) ifcd; -} - -void DeleteOSVCDec(GF_BaseDecoder *ifcg) -{ - OSVCDec *ctx = (OSVCDec*) ifcg->privateStack; - gf_free(ctx); - gf_free(ifcg); -} - -const u32 *QueryInterfaces() -{ - static u32 si [] = { -#ifndef GPAC_DISABLE_AV_PARSERS - GF_MEDIA_DECODER_INTERFACE, -#endif - 0 - }; - return si; -} - -GF_BaseInterface *LoadInterface(u32 InterfaceType) -{ -#ifndef GPAC_DISABLE_AV_PARSERS - if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return (GF_BaseInterface *)NewOSVCDec(); -#endif - return NULL; -} - -void ShutdownInterface(GF_BaseInterface *ifce) -{ - switch (ifce->InterfaceType) { -#ifndef GPAC_DISABLE_AV_PARSERS - case GF_MEDIA_DECODER_INTERFACE: - DeleteOSVCDec((GF_BaseDecoder*)ifce); - break; -#endif - } -} +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Telecom ParisTech 2010- + * Author(s): Jean Le Feuvre + * All rights reserved + * + * This file is part of GPAC / OpenSVC Decoder module + * + * 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 +#include +#include + + +#if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(__GNUC__) +# pragma comment(lib, "OpenSVCDecoder") +#endif + +typedef struct{ + int Width; + int Height; + unsigned char* pY[1]; + unsigned char* pU[1]; + unsigned char* pV[1]; +} OPENSVCFRAME; + + +enum { + SVC_STATUS_ERROR = -1, + SVC_STATUS_OK = 0, // no error and no frame ready + SVC_IMAGE_READY = 1, // no error and image ready + SVC_GHOST_IMAGE = 2 // no image for chosen layer but image could be ready for other layers +}; + +int SVCDecoder_init(void **PlayerStruct); +int SVCDecoder_close(void *PlayerStruct); +//TODO +int decodeNAL(void *PlayerStruct, unsigned char* nal, int nal_length, OPENSVCFRAME *Frame, int *LayerCommand); +/*ID vient du NAL type 14 et 20*/ +//TODO +void SetCommandLayer(int *Command, int DqIdMax, int CurrDqId, int *TemporalCom, int TemporalId); +void ParseAuPlayers(void *PlayerStruct, const unsigned char *buf, int buf_size, int nal_length_size, int is_avc); +int GetDqIdMax(const unsigned char *buf, int buf_size, int nal_length_size, int *DqidTable, int is_avc); + + +typedef struct +{ + u16 ES_ID; + u32 width, stride, height, out_size, pixel_ar, layer; + Bool first_frame; + + u32 nalu_size_length; + + /*OpenSVC things*/ + void *codec; + int InitParseAU; + int svc_init_done; + int save_Width; + int save_Height; + int CurrDqId; + int MaxDqId; + int DqIdTable [8]; + int TemporalId; + int TemporalCom; +} OSVCDec; + +static GF_Err OSVC_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) +{ + u32 i, count; + s32 res; + OPENSVCFRAME Picture; + int Layer[4]; + OSVCDec *ctx = (OSVCDec*) ifcg->privateStack; + + /*not supported in this version*/ + if (esd->dependsOnESID) return GF_NOT_SUPPORTED; + + ctx->ES_ID = esd->ESID; + ctx->width = ctx->height = ctx->out_size = 0; + + if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) { + GF_AVCConfig *cfg = gf_odf_avc_cfg_read(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); + if (!cfg) return GF_NON_COMPLIANT_BITSTREAM; + ctx->nalu_size_length = cfg->nal_unit_size; + if (SVCDecoder_init(&ctx->codec) == SVC_STATUS_ERROR) return GF_IO_ERR; + + /*decode all NALUs*/ + count = gf_list_count(cfg->sequenceParameterSets); + SetCommandLayer(Layer, 255, 0, &i, 0);//bufindex can be reset without pb + for (i=0; isequenceParameterSets, i); + + gf_avc_get_sps_info(slc->data, slc->size, &slc->id, &w, &h, &par_n, &par_d); + /*by default use the base layer*/ + if (!i) { + if ((ctx->widthheightwidth = w; + ctx->height = h; + if ( ((s32)par_n>0) && ((s32)par_d>0) ) + ctx->pixel_ar = (par_n<<16) || par_d; + } + } + res = decodeNAL(ctx->codec, slc->data, slc->size, &Picture, Layer); + if (res<0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[SVC Decoder] Error decoding SPS %d\n", res)); + } + } + + count = gf_list_count(cfg->pictureParameterSets); + for (i=0; ipictureParameterSets, i); + res = decodeNAL(ctx->codec, slc->data, slc->size, &Picture, Layer); + if (res<0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[SVC Decoder] Error decoding PPS %d\n", res)); + } + } + + gf_odf_avc_cfg_del(cfg); + } else { + ctx->nalu_size_length = 0; + if (SVCDecoder_init(&ctx->codec) == SVC_STATUS_ERROR) return GF_IO_ERR; + } + ctx->stride = ctx->width + 32; + ctx->layer = 0; + ctx->CurrDqId = ctx->layer; + ctx->out_size = ctx->stride * ctx->height * 3 / 2; + return GF_OK; +} +static GF_Err OSVC_DetachStream(GF_BaseDecoder *ifcg, u16 ES_ID) +{ + OSVCDec *ctx = (OSVCDec*) ifcg->privateStack; + + if (ctx->codec) SVCDecoder_close(ctx->codec); + ctx->codec = NULL; + ctx->width = ctx->height = ctx->out_size = 0; + return GF_OK; +} +static GF_Err OSVC_GetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability *capability) +{ + OSVCDec *ctx = (OSVCDec*) ifcg->privateStack; + + switch (capability->CapCode) { + case GF_CODEC_RESILIENT: + capability->cap.valueInt = 1; + break; + case GF_CODEC_WIDTH: + capability->cap.valueInt = ctx->width; + break; + case GF_CODEC_HEIGHT: + capability->cap.valueInt = ctx->height; + break; + case GF_CODEC_STRIDE: + capability->cap.valueInt = ctx->stride; + break; + case GF_CODEC_PAR: + capability->cap.valueInt = ctx->pixel_ar; + break; + case GF_CODEC_OUTPUT_SIZE: + capability->cap.valueInt = ctx->out_size; + break; + case GF_CODEC_PIXEL_FORMAT: + capability->cap.valueInt = GF_PIXEL_YV12; + break; + case GF_CODEC_BUFFER_MIN: + capability->cap.valueInt = 1; + break; + case GF_CODEC_BUFFER_MAX: + capability->cap.valueInt = 4; + break; + case GF_CODEC_PADDING_BYTES: + capability->cap.valueInt = 32; + break; + case GF_CODEC_REORDER: + capability->cap.valueInt = 1; + break; + /*not known at our level...*/ + case GF_CODEC_CU_DURATION: + default: + capability->cap.valueInt = 0; + break; + } + return GF_OK; +} +static GF_Err OSVC_SetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability capability) +{ + OSVCDec *ctx = (OSVCDec*) ifcg->privateStack; + switch (capability.CapCode) { + case GF_CODEC_MEDIA_SWITCH_QUALITY: + if (capability.cap.valueInt) { + if (ctx->layer<32) { + ctx->layer += 8; + ctx->CurrDqId = ctx->layer; + } + } else { + if (ctx->layer>=8) { + ctx->layer -= 8; + ctx->CurrDqId = ctx->layer; + } + } + return GF_OK; + } + /*return unsupported to avoid confusion by the player (like color space changing ...) */ + return GF_NOT_SUPPORTED; + +} + +static GF_Err OSVC_ProcessData(GF_MediaDecoder *ifcg, + char *inBuffer, u32 inBufferLength, + u16 ES_ID, + char *outBuffer, u32 *outBufferLength, + u8 PaddingBits, u32 mmlevel) +{ + + s32 got_pic; + OPENSVCFRAME pic; + int Layer[4]; + OSVCDec *ctx = (OSVCDec*) ifcg->privateStack; + + if (!ES_ID || (ES_ID!=ctx->ES_ID) || !ctx->codec) { + *outBufferLength = 0; + return GF_OK; + } + if (*outBufferLength < ctx->out_size) { + *outBufferLength = ctx->out_size; + return GF_BUFFER_TOO_SMALL; + } + + got_pic = 0; + if (ctx->nalu_size_length) { + u32 i, nalu_size = 0; + u8 *ptr = inBuffer; + + ctx->MaxDqId = GetDqIdMax(inBuffer, inBufferLength, ctx->nalu_size_length, ctx->DqIdTable, 1); + if(!ctx->InitParseAU){ + if (ctx->MaxDqId == -1) { + //AVC stream in a h264 file + ctx->MaxDqId = 0; + } else { + //Firts time only, we parse the first AU to know the file configuration + //does not need to ba called again ever after, unless SPS or PPS changed + ParseAuPlayers(ctx->codec, inBuffer, inBufferLength, ctx->nalu_size_length, 1); + } + ctx->InitParseAU = 1; + } + SetCommandLayer(Layer, ctx->MaxDqId, ctx->CurrDqId, &ctx->TemporalCom, ctx->TemporalId); + + while (inBufferLength) { + for (i=0; inalu_size_length; i++) { + nalu_size = (nalu_size<<8) + ptr[i]; + } + ptr += ctx->nalu_size_length; + + if (!got_pic) + got_pic = decodeNAL(ctx->codec, ptr, nalu_size, &pic, Layer); + else + decodeNAL(ctx->codec, ptr, nalu_size, &pic, Layer); + + ptr += nalu_size; + if (inBufferLength < nalu_size + ctx->nalu_size_length) break; + + inBufferLength -= nalu_size + ctx->nalu_size_length; + } + } else { + } + if (got_pic!=1) return GF_OK; + + if ((pic.Width != ctx->width) || (pic.Height!=ctx->height)) { + ctx->width = pic.Width; + ctx->stride = pic.Width + 32; + ctx->height = pic.Height; + ctx->out_size = ctx->stride * ctx->height * 3 / 2; + + /*always force layer resize*/ + *outBufferLength = ctx->out_size; + return GF_BUFFER_TOO_SMALL; + } + *outBufferLength = ctx->out_size; + memcpy(outBuffer, pic.pY[0], ctx->stride*ctx->height); + memcpy(outBuffer + ctx->stride * ctx->height, pic.pU[0], ctx->stride*ctx->height/4); + memcpy(outBuffer + 5*ctx->stride * ctx->height/4, pic.pV[0], ctx->stride*ctx->height/4); + + return GF_OK; +} + +static u32 OSVC_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, u8 PL) +{ + if (StreamType != GF_STREAM_VISUAL) return GF_CODEC_NOT_SUPPORTED; + + /*media type query*/ + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; + + switch (esd->decoderConfig->objectTypeIndication) { + case GPAC_OTI_VIDEO_AVC: + if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) { + Bool is_svc = 0; + u32 i, count; + GF_AVCConfig *cfg = gf_odf_avc_cfg_read(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); + if (!cfg) return GF_CODEC_NOT_SUPPORTED; + + /*decode all NALUs*/ + count = gf_list_count(cfg->sequenceParameterSets); + for (i=0; isequenceParameterSets, i); + u8 nal_type = slc->data[0] & 0x1F; + + if (nal_type==GF_AVC_NALU_SVC_SUBSEQ_PARAM) { + is_svc = 1; + break; + } + } + gf_odf_avc_cfg_del(cfg); + return is_svc ? GF_CODEC_SUPPORTED : GF_CODEC_MAYBE_SUPPORTED; + } + return GF_CODEC_MAYBE_SUPPORTED; + } + return GF_CODEC_NOT_SUPPORTED; +} + +static const char *OSVC_GetCodecName(GF_BaseDecoder *dec) +{ + return "OpenSVC Decoder"; +} + +GF_BaseDecoder *NewOSVCDec() +{ + GF_MediaDecoder *ifcd; + OSVCDec *dec; + + GF_SAFEALLOC(ifcd, GF_MediaDecoder); + GF_SAFEALLOC(dec, OSVCDec); + GF_REGISTER_MODULE_INTERFACE(ifcd, GF_MEDIA_DECODER_INTERFACE, "OpenSVC Decoder", "gpac distribution") + + ifcd->privateStack = dec; + + /*setup our own interface*/ + ifcd->AttachStream = OSVC_AttachStream; + ifcd->DetachStream = OSVC_DetachStream; + ifcd->GetCapabilities = OSVC_GetCapabilities; + ifcd->SetCapabilities = OSVC_SetCapabilities; + ifcd->GetName = OSVC_GetCodecName; + ifcd->CanHandleStream = OSVC_CanHandleStream; + ifcd->ProcessData = OSVC_ProcessData; + return (GF_BaseDecoder *) ifcd; +} + +void DeleteOSVCDec(GF_BaseDecoder *ifcg) +{ + OSVCDec *ctx = (OSVCDec*) ifcg->privateStack; + gf_free(ctx); + gf_free(ifcg); +} + +const u32 *QueryInterfaces() +{ + static u32 si [] = { +#ifndef GPAC_DISABLE_AV_PARSERS + GF_MEDIA_DECODER_INTERFACE, +#endif + 0 + }; + return si; +} + +GF_BaseInterface *LoadInterface(u32 InterfaceType) +{ +#ifndef GPAC_DISABLE_AV_PARSERS + if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return (GF_BaseInterface *)NewOSVCDec(); +#endif + return NULL; +} + +void ShutdownInterface(GF_BaseInterface *ifce) +{ + switch (ifce->InterfaceType) { +#ifndef GPAC_DISABLE_AV_PARSERS + case GF_MEDIA_DECODER_INTERFACE: + DeleteOSVCDec((GF_BaseDecoder*)ifce); + break; +#endif + } +} diff --git a/modules/oss_audio/Makefile b/modules/oss_audio/Makefile index cd5e60d..1582048 100644 --- a/modules/oss_audio/Makefile +++ b/modules/oss_audio/Makefile @@ -37,7 +37,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac $(OSS_LDFLAGS) ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_oss_audio-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static $(OSS_LDFLAGS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_oss_audio-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static $(OSS_LDFLAGS) endif diff --git a/modules/platinum/GPACPlatinum.cpp b/modules/platinum/GPACPlatinum.cpp index e1e66bb..6431d7e 100644 --- a/modules/platinum/GPACPlatinum.cpp +++ b/modules/platinum/GPACPlatinum.cpp @@ -1550,8 +1550,13 @@ static Bool upnp_process(GF_TermExt *termext, u32 action, void *param) case GF_TERM_EXT_START: opt = gf_modules_get_option((GF_BaseInterface*)termext, "UPnP", "Enabled"); if (!opt) { +#ifdef GPAC_CONFIG_DARWIN + opt = "no"; + fprintf(stdout, "Disabling UPnP - to enable it, modify section [UPnP] key \"Enabled\" in /Users/yourname/.gpacrc"); +#else opt = "yes"; - gf_modules_set_option((GF_BaseInterface*)termext, "UPnP", "Enabled", "yes"); +#endif + gf_modules_set_option((GF_BaseInterface*)termext, "UPnP", "Enabled", opt); } if (!strcmp(opt, "yes")) { upnp->Load((GF_Terminal *)param); diff --git a/modules/raw_out/Makefile b/modules/raw_out/Makefile index a900efb..ed6e0dd 100644 --- a/modules/raw_out/Makefile +++ b/modules/raw_out/Makefile @@ -39,7 +39,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_raw_out-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_raw_out-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static endif diff --git a/modules/redirect_av/Makefile b/modules/redirect_av/Makefile index d43bd3e..c514a1b 100644 --- a/modules/redirect_av/Makefile +++ b/modules/redirect_av/Makefile @@ -1,58 +1,58 @@ -include ../../config.mak - -vpath %.c $(SRC_PATH)/modules/redirect_av - -CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include" $(ffmpeg_cflags) - -ifeq ($(DEBUGBUILD), yes) -CFLAGS+=-g -LDFLAGS+=-g -endif - -ifeq ($(GPROFBUILD), yes) -CFLAGS+=-pg -LDFLAGS+=-pg -endif - -LINKLIBS= -lgpac $(ffmpeg_lflags) -LOCAL_LIB=../../bin/gcc - -#common objects -OBJS=redirect_av.o - - - -SRCS := $(OBJS:.o=.c) - -LIB=gm_redirect_av.$(DYN_LIB_SUFFIX) - -all: $(LIB) - - -$(LIB): $(OBJS) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS) - - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< - - -clean: - rm -f $(OBJS) ../../bin/gcc/$(LIB) - -dep: depend - -depend: - rm -f .depend - $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend - -distclean: clean - rm -f Makefile.bak .depend - - - -# include dependency files if they exist -# -ifneq ($(wildcard .depend),) -include .depend -endif +include ../../config.mak + +vpath %.c $(SRC_PATH)/modules/redirect_av + +CFLAGS= $(OPTFLAGS) -I"$(SRC_PATH)/include" $(ffmpeg_cflags) + +ifeq ($(DEBUGBUILD), yes) +CFLAGS+=-g +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD), yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + +LINKLIBS= -lgpac $(ffmpeg_lflags) +LOCAL_LIB=../../bin/gcc + +#common objects +OBJS=redirect_av.o + + + +SRCS := $(OBJS:.o=.c) + +LIB=gm_redirect_av.$(DYN_LIB_SUFFIX) + +all: $(LIB) + + +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + + +clean: + rm -f $(OBJS) ../../bin/gcc/$(LIB) + +dep: depend + +depend: + rm -f .depend + $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend + +distclean: clean + rm -f Makefile.bak .depend + + + +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/modules/redirect_av/ffmpeg_ts_muxer.c b/modules/redirect_av/ffmpeg_ts_muxer.c index 6d8a40e..2489fec 100644 --- a/modules/redirect_av/ffmpeg_ts_muxer.c +++ b/modules/redirect_av/ffmpeg_ts_muxer.c @@ -41,6 +41,7 @@ static AVPacketList * wait_for_packet(GF_AbstractTSMuxer* ts, GF_Mutex * mx, AVP while (ts->encode && !(*pkts)) { gf_mx_v(mx); gf_mx_p(mx); + gf_sleep(1); } if (!ts->encode) { gf_mx_v(mx); @@ -138,6 +139,7 @@ static Bool ts_interleave_thread_run(void *param) { } gf_free(pl); } + gf_sleep(1); } exit: GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[AVRedirect] Ending TS thread...\n")); @@ -166,6 +168,7 @@ GF_AbstractTSMuxer * ts_amux_new(GF_AVRedirect * avr, u32 videoBitrateInBitsPerS if (!ts->oc->oformat) ts->oc->oformat = GUESS_FORMAT("mpegts", NULL, NULL); assert( ts->oc->oformat); +#if REDIRECT_AV_AUDIO_ENABLED ts->audio_st = av_new_stream(ts->oc, avr->audioCodec->id); { AVCodecContext * c = ts->audio_st->codec; @@ -176,14 +179,15 @@ GF_AbstractTSMuxer * ts_amux_new(GF_AVRedirect * avr, u32 videoBitrateInBitsPerS c->bit_rate = audioBitRateInBitsPerSec; c->sample_rate = avr->audioSampleRate; c->channels = 2; - c->time_base.num = 1; - c->time_base.den = 1000; + c->time_base.num = 1; + c->time_base.den = 1000; // some formats want stream headers to be separate if (ts->oc->oformat->flags & AVFMT_GLOBALHEADER) c->flags |= CODEC_FLAG_GLOBAL_HEADER; } - ts->video_st = av_new_stream(ts->oc, avr->videoCodec->id); +#endif + ts->video_st = av_new_stream(ts->oc, avr->videoCodec->id); { AVCodecContext * c = ts->video_st->codec; c->codec_id = avr->videoCodec->id; @@ -231,12 +235,14 @@ GF_AbstractTSMuxer * ts_amux_new(GF_AVRedirect * avr, u32 videoBitrateInBitsPerS GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[AVRedirect] failed to open video codec\n")); return NULL; } +#if REDIRECT_AV_AUDIO_ENABLED if (avcodec_open(ts->audio_st->codec, avr->audioCodec) < 0) { GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[AVRedirect] failed to open audio codec\n")); return NULL; } - ts->videoMx = gf_mx_new("TS_VideoMx"); ts->audioMx = gf_mx_new("TS_AudioMx"); +#endif + ts->videoMx = gf_mx_new("TS_VideoMx"); ts->tsEncodingThread = gf_th_new("ts_interleave_thread_run"); ts->encode = 1; ts->audioPackets = NULL; @@ -252,18 +258,22 @@ void ts_amux_del(GF_AbstractTSMuxer * muxerToDelete) { gf_sleep(100); gf_th_stop(muxerToDelete->tsEncodingThread); muxerToDelete->tsEncodingThread = NULL; +#if REDIRECT_AV_AUDIO_ENABLED gf_mx_del(muxerToDelete->audioMx); muxerToDelete->audioMx = NULL; +#endif gf_mx_del(muxerToDelete->videoMx); muxerToDelete->videoMx = NULL; if (muxerToDelete->video_st) { avcodec_close(muxerToDelete->video_st->codec); muxerToDelete->video_st = NULL; } +#if REDIRECT_AV_AUDIO_ENABLED if (muxerToDelete->audio_st) { avcodec_close(muxerToDelete->audio_st->codec); muxerToDelete->audio_st = NULL; } +#endif /* write the trailer, if any. the trailer must be written * before you close the CodecContexts open when you wrote the * header; otherwise write_trailer may try to use memory that diff --git a/modules/redirect_av/redirect_av.c b/modules/redirect_av/redirect_av.c index 5e4b8c0..0c7f15c 100644 --- a/modules/redirect_av/redirect_av.c +++ b/modules/redirect_av/redirect_av.c @@ -1,815 +1,830 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Jean le Feuvre - * Copyright (c) 2010-20XX Telecom ParisTech - * All rights reserved - * - * This file is part of GPAC / AVI Recorder demo module - * - * 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 - -#if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(__MINGW32__) - -#define EMULATE_INTTYPES -#define EMULATE_FAST_INT -#ifndef inline -#define inline __inline -#endif - -#if defined(__SYMBIAN32__) -#define EMULATE_INTTYPES -#endif - - -#ifndef __MINGW32__ -#define __attribute__(s) -#endif - - -/*include FFMPEG APIs*/ -#ifdef _WIN32_WCE -#define inline __inline -#endif - - -# define INT64_C(x) (x ## i64) -# define UINT64_C(x) (x ## Ui64) - - -#endif - - -#include "ts_muxer.h" - -#define USE_GPAC_MPEG2TS -#undef USE_GPAC_MPEG2TS - -#ifdef USE_GPAC_MPEG2TS -#include "gpac_ts_muxer.c" -#else -#include "ffmpeg_ts_muxer.c" -#endif /* USE_GPAC_MPEG2TS */ - -#include -#include -#include - - -#if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(__GNUC__) - -#if defined(_WIN32_WCE) -#pragma comment(lib, "toolhelp") -#pragma comment(lib, "winsock") -#endif - -#define _TOSTR(_val) #_val -#define TOSTR(_val) _TOSTR(_val) - -#pragma comment(lib, "avcodec-"TOSTR(LIBAVCODEC_VERSION_MAJOR) ) -#pragma comment(lib, "avformat-"TOSTR(LIBAVFORMAT_VERSION_MAJOR) ) -#pragma comment(lib, "avutil-"TOSTR(LIBAVUTIL_VERSION_MAJOR) ) -#pragma comment(lib, "swscale-"TOSTR(LIBSWSCALE_VERSION_MAJOR) ) - -#endif - - -/* This number * 188 should be lower than the UDP packet size */ -#define TS_PACKETS_PER_UDP_PACKET 1 - -#define audioCodecBitrate 96000 - -#if !defined(WIN32) && !defined(_WIN32_WCE) -#include -#endif - -static const u32 maxFPS = 25; - -static const char * moduleName = "AVRedirect"; - -static const char * AVR_VIDEO_CODEC_OPTION = "VideoCodec"; - - -#define AVR_TIMERS_LENGHT 25 - -#define U32_ABS( a, b ) (a > b ? a - b : b - a) - -#define DUMP_MP3 -#undef DUMP_MP3 - -/** - * This thread sends the frame to TS mux - * \param Parameter The GF_AVRedirect pointer - */ -static Bool audio_encoding_thread_run(void *param) -{ - u8 * inBuff; - u8 * outBuff; - u32 inBuffSize, outBuffSize, samplesReaden, toRead; - u64 myTime = 0; - u32 frameCountSinceReset = 0; - u32 lastCurrentTime; - Bool sendPts = 1; - GF_AVRedirect * avr = (GF_AVRedirect*) param; - AVCodecContext * ctx = NULL; - assert( avr ); - - outBuffSize = FF_MIN_BUFFER_SIZE; - - outBuff = gf_malloc(outBuffSize* sizeof(u8)); - inBuff = NULL; -#ifdef DUMP_MP3 - FILE * mp3 = fopen("/tmp/dump.mp3", "w"); -#endif /* DUMP_MP3 */ - sendPts = 1; - gf_sc_add_audio_listener ( avr->term->compositor, &avr->audio_listen ); - while (avr->is_running && !ctx) { - ctx = ts_get_audio_codec_context(avr->ts_implementation); - gf_sleep(16); - } - if (!ctx) { - goto exit; - } - - printf("******* Audio Codec Context = %d/%d, start="LLU", frame_size=%u\n", ctx->time_base.num, ctx->time_base.den, ctx->timecode_frame_start, ctx->frame_size); - samplesReaden = ctx->frame_size * ctx->channels; - - //printf("SETUP input sample size=%u, output samplesize=%u, buffsize=%u, samplesReaden=%u\n", ctx->input_sample_size, ctx->frame_size, sizeof(outbuf), samplesReaden); - // 2 chars are needed for each short - toRead = samplesReaden * 2; - inBuffSize = toRead; - inBuff = gf_malloc(inBuffSize * sizeof(u8)); - while (avr->is_running && !avr->audioCurrentTime) { - gf_sleep(16); - } - myTime = lastCurrentTime = avr->audioCurrentTime; - frameCountSinceReset = 0; - while (avr->is_running) { - u32 readen; - if (U32_ABS(avr->audioCurrentTime, myTime) > 25000) { - //GF_LOG( GF_LOG_ERROR, GF_LOG_MODULE, ("[AVRedirect] Drift in audio : audioCurrentTime = %u, myTime=%u, resync...\n", avr->audioCurrentTime, myTime)); - //myTime = lastCurrentTime = avr->audioCurrentTime; - //frameCountSinceReset = 0; - sendPts = 1; - } - while (toRead <= gf_ringbuffer_available_for_read(avr->pcmAudio) ) { - memset( inBuff, 0, inBuffSize); - memset( outBuff, 0, outBuffSize); - readen = gf_ringbuffer_read(avr->pcmAudio, inBuff, toRead); - assert( readen == toRead ); - if (avr->encode) - { - //u32 oldFrameSize = ctx->frame_size; - //ctx->frame_size = readable / (2 * ctx->channels); - //assert( oldFrameSize <= ctx->frame_size ); - /* buf_size * input_sample_size / output_sample_size */ - int encoded = avcodec_encode_audio(ctx, outBuff, outBuffSize, (const short *) inBuff); - if (encoded < 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[RedirectAV]: failed to encode audio, buffer size=%u, readen=%u, frame_size=%u\n", outBuffSize, readen, ctx->frame_size)); - } else if (encoded > 0) { - ts_encode_audio_frame(avr->ts_implementation, outBuff, encoded, sendPts ? myTime : AV_NOPTS_VALUE ); - frameCountSinceReset++; -#ifdef DUMP_MP3 - fwrite( outBuff, sizeof(char), encoded, mp3); -#endif /* DUMP_MP3 */ - //if (ctx->codec->id == CODEC_ID_MP3) { - /* It seems the MP3 codec only fetches 50% of data... */ - // myTime= lastCurrentTime + (frameCountSinceReset * ctx->frame_size * 500 / ctx->sample_rate); - //} else - //myTime = lastCurrentTime + (frameCountSinceReset * toRead * 1000 / ctx->sample_rate/ ctx->channels / 4); - /* Avoid overflow , multiply by 10 and divide sample rate by 100 instead of *1000 / sampleRate */ - myTime = lastCurrentTime + (frameCountSinceReset * toRead * 10 / (ctx->sample_rate / 100) / ctx->channels / 4); - //sendPts = 0; - sendPts = 1; - } else { - GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[RedirectAV]: no encoded frame.\n")); - //frameCountSinceReset++; - } - //ctx->frame_size = oldFrameSize; - } - } - } -exit: - GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[AVRedirect] Ending audio encoding thread...\n")); - if (inBuff) - gf_free( inBuff ); - if (outBuff) - gf_free( outBuff ); -#ifdef DUMP_MP3 - if (mp3) - fclose(mp3); -#endif /* DUMP_MP3 */ - if (avr->term) - gf_sc_remove_audio_listener ( avr->term->compositor, &avr->audio_listen ); - return GF_OK; -} - -/** - * This thread sends the frame to TS mux - * \param Parameter The GF_AVRedirect pointer - */ -static Bool video_encoding_thread_run(void *param) -{ - GF_AVRedirect * avr = (GF_AVRedirect*) param; - u64 currentFrameTimeProcessed = 0; - u32 lastEncodedFrameTime = 0; - AVCodecContext * ctx = NULL; - assert( avr ); - gf_sc_add_video_listener ( avr->term->compositor, &avr->video_listen ); - while (avr->is_running && (!ctx || !avr->swsContext)) { - ctx = ts_get_video_codec_context(avr->ts_implementation); - gf_sleep(16); - } - if (!ctx) { - goto exit; - } - printf("******* Video Codec Context = %d/%d, start="LLU"\n", ctx->time_base.num, ctx->time_base.den, ctx->timecode_frame_start); - while (avr->is_running) { - { - gf_mx_p(avr->frameMutex); - while (!avr->frameTime || currentFrameTimeProcessed == avr->frameTime) { - gf_mx_v(avr->frameMutex); - if (!avr->is_running) { - goto exit; - } - gf_mx_p(avr->frameMutex); - } - assert( currentFrameTimeProcessed != avr->frameTime); - currentFrameTimeProcessed = avr->frameTime; - { - avpicture_fill ( ( AVPicture * ) avr->RGBpicture, avr->frame, PIX_FMT_RGB24, avr->srcWidth, avr->srcHeight ); - assert( avr->swsContext ); - sws_scale ( avr->swsContext, -#ifdef USE_AVCODEC2 - ( const uint8_t * const * ) -#else - ( uint8_t ** ) -#endif /* USE_AVCODEC2 */ - avr->RGBpicture->data, avr->RGBpicture->linesize, - 0, avr->srcHeight, - avr->YUVpicture->data, avr->YUVpicture->linesize ); -#ifdef AVR_DUMP_RAW_AVI - if ( AVI_write_frame ( avr->avi_out, avr->frame, avr->size, 1 ) <0 ) - { - GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Error writing video frame\n" ) ); - } -#endif /* AVR_DUMP_RAW_AVI */ - gf_mx_v(avr->frameMutex); - if (avr->encode) - { - int written; - //u32 sysclock = gf_sys_clock(); - avr->YUVpicture->pts = currentFrameTimeProcessed; - //printf("Encoding frame PTS="LLU", frameNum=%u, time=%u...", avr->YUVpicture->pts, avr->YUVpicture->coded_picture_number, currentFrameTimeProcessed); - written = avcodec_encode_video ( ctx, avr->videoOutbuf, avr->videoOutbufSize, avr->YUVpicture ); - //ctx->coded_frame->pts = currentFrameTimeProcessed; - if ( written < 0 ) - { - GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Error while encoding video frame =%d\n", written ) ); - } else - if ( written > 0 ) - { - ts_encode_video_frame(avr->ts_implementation, avr->videoOutbuf, written); - } - lastEncodedFrameTime = currentFrameTimeProcessed; - } - } - } - avr->frameTimeEncoded = currentFrameTimeProcessed; - } /* End of main loop */ -exit: - GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[AVRedirect] Ending video encoding thread...\n")); - if (avr->term) - gf_sc_remove_video_listener ( avr->term->compositor, &avr->video_listen ); - return 0; -} - -#define VIDEO_RATE 400000 - -static Bool start_if_needed(GF_AVRedirect *avr) { - enum PixelFormat pxlFormatForCodec = PIX_FMT_YUV420P; - if (avr->is_open) - return 0; - gf_mx_p(avr->frameMutex); - if (avr->is_open) { - gf_mx_v(avr->frameMutex); - return 0; - } - if (!avr->srcWidth || !avr->srcHeight || !avr->audioSampleRate || !avr->audioChannels) { - gf_mx_v(avr->frameMutex); - return 3; - } -#ifdef AVR_DUMP_RAW_AVI - avr->avi_out = AVI_open_output_file ( "dump.avi" ); - if ( !avr->avi_out ) - { - gf_mx_v(avr->frameMutex); - GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Error opening output AVI file\n" ) ); - return 4; - } -#endif /* AVR_DUMP_RAW_AVI */ - GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[AVRedirect] Initializing...\n")); - if (!avr->pcmAudio) - avr->pcmAudio = gf_ringbuffer_new(32768); - - /* Setting up the video encoding ... */ - { - avr->YUVpicture = avr->RGBpicture = NULL; - avr->videoOutbuf = NULL; - if ( !avr->audioCodec) - { - gf_mx_v(avr->frameMutex); - GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Cannot find audio codec.\n" ) ); - return 1; - } - - if ( !avr->videoCodec ) - { - GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Cannot find video codec.\n" ) ); - return 2; - } - - if (avr->videoCodec->id == CODEC_ID_MJPEG) { - pxlFormatForCodec = PIX_FMT_YUVJ420P; - } - - avr->RGBpicture = avcodec_alloc_frame(); - assert ( avr->RGBpicture ); - avr->RGBpicture->data[0] = NULL; - avr->YUVpicture = avcodec_alloc_frame(); - assert ( avr->YUVpicture ); - { - u32 sz = sizeof ( uint8_t ) * avpicture_get_size ( pxlFormatForCodec, avr->srcWidth, avr->srcHeight ); - avr->yuv_data = av_malloc ( sz ); /* size for YUV 420 */ - assert ( avr->yuv_data ); - memset ( avr->yuv_data, 0, sz ); - avpicture_fill ( ( AVPicture* ) avr->YUVpicture, avr->yuv_data, pxlFormatForCodec, avr->srcWidth, avr->srcHeight ); - avr->YUVpicture->coded_picture_number = 0; - } - avr->videoOutbufSize = avr->srcHeight * avr->srcWidth * 4; - avr->videoOutbuf = gf_malloc ( avr->videoOutbufSize ); - memset ( avr->videoOutbuf, 0, avr->videoOutbufSize ); - } -#ifdef AVR_DUMP_RAW_AVI - GF_LOG ( GF_LOG_INFO, GF_LOG_MODULE, ( "[AVRedirect] Open output AVI file %s\n", "dump.avi" ) ); -#endif /* AVR_DUMP_RAW_AVI */ - /* Setting up the TS mux */ - { - /* - GF_Socket * ts_output_udp_sk = gf_sk_new ( GF_SOCK_TYPE_UDP ); - if ( gf_sk_is_multicast_address ( avr->udp_address ) ) - { - e = gf_sk_setup_multicast ( ts_output_udp_sk, avr->udp_address, avr->udp_port, 0, 0, NULL ); - } - else - { - e = gf_sk_bind ( ts_output_udp_sk, NULL, avr->udp_port, avr->udp_address, avr->udp_port, GF_SOCK_REUSE_PORT ); - } - gf_sk_set_buffer_size(ts_output_udp_sk, 0, 188 * TS_PACKETS_PER_UDP_PACKET); - gf_sk_set_block_mode(ts_output_udp_sk, 0);*/ - assert( avr->destination ); - avr->ts_implementation = ts_amux_new(avr, VIDEO_RATE, avr->srcWidth, avr->srcHeight, audioCodecBitrate); - } - /* - if ( e ) - { - GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Error while initializing UDP address %s\n", gf_error_to_string ( e ) ) ); - return e; - } - */ - avr->is_open = avr->ts_implementation != NULL; - gf_mx_v(avr->frameMutex); - return avr->is_open ? 1 : 0; -} - - -static GF_Err avr_open ( GF_AVRedirect *avr ) -{ - assert( avr ); - if ( avr->is_open) - return GF_OK; - if (!avr->is_running) { - avr->is_running = 1; - gf_th_run(avr->encodingThread, video_encoding_thread_run, avr); - gf_th_run(avr->audioEncodingThread, audio_encoding_thread_run, avr); - } - return GF_OK; -} - - - -static void avr_on_audio_frame ( void *udta, char *buffer, u32 buffer_size, u32 time, u32 delay_ms ) -{ - GF_AVRedirect *avr = ( GF_AVRedirect * ) udta; - if (start_if_needed(avr)) - return; -#ifdef AVR_DUMP_RAW_AVI - AVI_write_audio ( avr->avi_out, buffer, buffer_size ); -#endif /* AVR_DUMP_RAW_AVI */ - { - gf_ringbuffer_write(avr->pcmAudio, buffer, buffer_size); - avr->audioCurrentTime = time - delay_ms; - } -} - -static void avr_on_audio_reconfig ( void *udta, u32 samplerate, u32 bits_per_sample, u32 nb_channel, u32 channel_cfg ) -{ - GF_AVRedirect *avr = ( GF_AVRedirect * ) udta; - if (avr->audioSampleRate != samplerate || avr->audioChannels != nb_channel) { - GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[AVRedirect] Audio %u Hz, bitsPerSample=%u, nbchannels=%u\n", samplerate, bits_per_sample, nb_channel)); -#ifdef AVR_DUMP_RAW_AVI - AVI_set_audio ( avr->avi_out, nb_channel, samplerate, bits_per_sample, WAVE_FORMAT_PCM, 0 ); -#endif /* AVR_DUMP_RAW_AVI */ - avr->audioChannels = nb_channel; - avr->audioSampleRate = samplerate; - } -} - -static void avr_on_video_frame ( void *udta, u32 time ) -{ - u32 i, j; - GF_Err e; - GF_VideoSurface fb; - GF_AVRedirect *avr = ( GF_AVRedirect * ) udta; - if (start_if_needed(avr)) - return; - gf_mx_p(avr->frameMutex); - e = gf_sc_get_screen_buffer ( avr->term->compositor, &fb, 0 ); - if ( e ) - { - GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Error grabing frame buffer %s\n", gf_error_to_string ( e ) ) ); - return; - } - /*convert frame*/ - for ( i=0; iframe + i * fb.width * 3; - char *src = fb.video_buffer + i * fb.pitch_y; - for ( j=0; jframeTime = time; - gf_mx_v(avr->frameMutex); - gf_sc_release_screen_buffer ( avr->term->compositor, &fb ); - GF_LOG ( GF_LOG_DEBUG, GF_LOG_MODULE, ( "[AVRedirect] Writing video frame\n" ) ); -} - -static void avr_on_video_reconfig ( void *udta, u32 width, u32 height ) -{ - - GF_AVRedirect *avr = ( GF_AVRedirect * ) udta; - - if ((avr->srcHeight != height || avr->srcWidth != width)) - { -#ifdef AVR_DUMP_RAW_AVI - char comp[5]; - comp[0] = comp[1] = comp[2] = comp[3] = comp[4] = 0; - AVI_set_video ( avr->avi_out, width, height, 30, comp ); -#endif /* AVR_DUMP_RAW_AVI */ - GF_LOG ( GF_LOG_INFO, GF_LOG_MODULE, ( "[AVRedirect] Video reconfig width %d height %d\n", width, height ) ); - gf_mx_p(avr->frameMutex); - if ( avr->frame ) gf_free ( avr->frame ); - avr->size = 3*width*height; - avr->frame = gf_malloc ( sizeof ( char ) *avr->size ); - avr->srcWidth = width; - avr->srcHeight = height; - avr->swsContext = sws_getCachedContext ( avr->swsContext, avr->srcWidth, avr->srcHeight, PIX_FMT_RGB24, avr->srcWidth, avr->srcHeight, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL ); - gf_mx_v(avr->frameMutex); - } -} - - -#ifdef MULTITHREAD_REDIRECT_AV -/** - * This thread sends the TS packets over the network - * \param Parameter The GF_AVRedirect pointer - */ -static Bool ts_thread_run(void *param) -{ - GF_Err e; - GF_AVRedirect * avr = (GF_AVRedirect*) param; - assert( avr ); - gf_mx_p(avr->tsMutex); - while (!avr->frameTimeEncoded && avr->is_running) { - gf_mx_v(avr->tsMutex); - gf_sleep(1); - gf_mx_p(avr->tsMutex); - } - printf("avr->frameTimeEncoded="LLU"\n", avr->frameTimeEncoded); - - while (avr->is_running) { - e = sendTSMux(avr); - gf_mx_v(avr->tsMutex); - gf_mx_p(avr->tsMutex); - } - gf_mx_v(avr->tsMutex); - return 0; -} -#endif /* MULTITHREAD_REDIRECT_AV */ - -static const char * possibleCodecs = "supported codecs : MPEG-1, MPEG-2, MPEG-4, MSMPEG-4, H263, H263I, H263P, RV10, MJPEG"; - -/*#define DEFAULT_UDP_OUT_ADDRESS "127.0.0.1" -#define DEFAULT_UDP_OUT_PORT 1234 -#define DEFAULT_UDP_OUT_PORT_STR "1234"*/ - -#define AVR_DEFAULT_DESTINATION "udp://224.0.0.1:1234" - -#include - - -static void avr_close ( GF_AVRedirect *avr ) -{ - if ( !avr->is_open ) return; - avr->is_open = 0; -#ifdef AVR_DUMP_RAW_AVI - GF_LOG ( GF_LOG_INFO, GF_LOG_MODULE, ( "[AVRedirect] Closing output AVI file\n" ) ); - AVI_close ( avr->avi_out ); - avr->avi_out = NULL; -#endif /* AVR_DUMP_RAW_AVI */ -} - -static Bool avr_on_event ( void *udta, GF_Event *evt, Bool consumed_by_compositor ) -{ - GF_AVRedirect *avr = udta; - switch ( evt->type ) - { - case GF_EVENT_CONNECT: - if ( evt->connect.is_connected ) - { - avr_open ( avr ); - } - else - { - avr_close ( avr ); - } - break; - } - return 0; -} - -static const char * AVR_ENABLED_OPTION = "Enabled"; - -//static const char * AVR_UDP_PORT_OPTION = "udp.port"; - -//static const char * AVR_UDP_ADDRESS_OPTION = "udp.address"; - -static const char * AVR_DESTINATION = "destination"; - -static Bool avr_process ( GF_TermExt *termext, u32 action, void *param ) -{ - const char *opt; - GF_AVRedirect *avr = termext->udta; - - switch ( action ) - { - case GF_TERM_EXT_START: - avr->term = ( GF_Terminal * ) param; - opt = gf_modules_get_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_ENABLED_OPTION ); - if ( !opt ) - gf_modules_set_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_ENABLED_OPTION, "no" ); - if ( !opt || strcmp ( opt, "yes" ) ) return 0; - opt = gf_modules_get_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_VIDEO_CODEC_OPTION ); - avr->globalLock = gf_global_resource_lock("AVRedirect:output"); - if (!avr->globalLock) { - GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("Failed to lock global resource 'AVRedirect:output', another GPAC instance must be running, disabling AVRedirect\n")); - return 0; - } - /* must be called before using avcodec lib */ - avcodec_init(); - - /* register all the codecs */ - avcodec_register_all(); - if ( !opt ) - gf_modules_set_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_VIDEO_CODEC_OPTION, possibleCodecs ); - { - if ( !opt ) - { - avr->videoCodec = avcodec_find_encoder ( CODEC_ID_MPEG2VIDEO ); - } - else if ( !strcmp ( "MPEG-1", opt ) ) - { - avr->videoCodec=avcodec_find_encoder ( CODEC_ID_MPEG1VIDEO ); - } - else if ( !strcmp ( "MPEG-2", opt ) ) - { - avr->videoCodec=avcodec_find_encoder ( CODEC_ID_MPEG2VIDEO ); - } - else if ( !strcmp ( "MPEG-4", opt ) ) - { - avr->videoCodec=avcodec_find_encoder ( CODEC_ID_MPEG4 ); - } - else if ( !strcmp ( "MSMPEG-4", opt ) ) - { - avr->videoCodec=avcodec_find_encoder ( CODEC_ID_MSMPEG4V3 ); - } - else if ( !strcmp ( "H263", opt ) ) - { - avr->videoCodec=avcodec_find_encoder ( CODEC_ID_H263 ); - } - else if ( !strcmp ( "RV10", opt ) ) - { - avr->videoCodec = avcodec_find_encoder ( CODEC_ID_RV10 ); - } - else if ( !strcmp ( "H263P", opt ) ) - { - avr->videoCodec=avcodec_find_encoder ( CODEC_ID_H263P ); - } - else if ( !strcmp ( "H263I", opt ) ) - { - avr->videoCodec=avcodec_find_encoder ( CODEC_ID_H263I ); - } - else if ( !strcmp( "MJPEG", opt)) - { - avr->videoCodec=avcodec_find_encoder( CODEC_ID_MJPEG); - } - else - { - GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Not a known Video codec : %s, using MPEG-2 video instead, %s\n", opt, possibleCodecs ) ); - avr->videoCodec = avcodec_find_encoder ( CODEC_ID_MPEG2VIDEO ); - } - } - avr->audioCodec = avcodec_find_encoder( CODEC_ID_MP3); - /* - opt = gf_modules_get_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_UDP_ADDRESS_OPTION); - if (!opt) { - gf_modules_set_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_UDP_ADDRESS_OPTION, DEFAULT_UDP_OUT_ADDRESS); - avr->udp_address = DEFAULT_UDP_OUT_ADDRESS; - GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] %s not set, using %s\n", AVR_UDP_ADDRESS_OPTION, DEFAULT_UDP_OUT_ADDRESS ) ); - } else - avr->udp_address = opt; - opt = gf_modules_get_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_UDP_PORT_OPTION); - if (opt) { - char *endPtr = NULL; - unsigned int x = strtoul(opt, &endPtr, 10); - if (endPtr == opt || x > 65536) { - printf("Failed to parse : %s\n", opt); - opt = NULL; - } else - avr->udp_port = (u16) x; - } - if (!opt) { - gf_modules_set_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_UDP_PORT_OPTION, DEFAULT_UDP_OUT_PORT_STR); - GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] %s is not set or valid, using %s\n", AVR_UDP_PORT_OPTION, DEFAULT_UDP_OUT_PORT_STR ) ); - avr->udp_port = DEFAULT_UDP_OUT_PORT; - } - */ - opt = gf_modules_get_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_DESTINATION); - if (!opt) { - gf_modules_set_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_DESTINATION, AVR_DEFAULT_DESTINATION); - avr->destination = AVR_DEFAULT_DESTINATION; - GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] %s not set, using %s\n", AVR_DESTINATION, AVR_DEFAULT_DESTINATION ) ); - } else - avr->destination = opt; - avr->audio_listen.udta = avr; - avr->audio_listen.on_audio_frame = avr_on_audio_frame; - avr->audio_listen.on_audio_reconfig = avr_on_audio_reconfig; - avr->video_listen.udta = avr; - avr->video_listen.on_video_frame = avr_on_video_frame; - avr->video_listen.on_video_reconfig = avr_on_video_reconfig; - - avr->term_listen.udta = avr; - avr->term_listen.on_event = avr_on_event; - gf_term_add_event_filter ( avr->term, &avr->term_listen ); - return 1; - - case GF_TERM_EXT_STOP: - gf_term_remove_event_filter ( avr->term, &avr->term_listen ); - avr->term = NULL; - break; - - /*if not threaded, perform our tasks here*/ - case GF_TERM_EXT_PROCESS: - break; - } - return 0; -} - - -GF_TermExt *avr_new() -{ - GF_TermExt *dr; - GF_AVRedirect *uir; - dr = gf_malloc ( sizeof ( GF_TermExt ) ); - memset ( dr, 0, sizeof ( GF_TermExt ) ); - GF_REGISTER_MODULE_INTERFACE ( dr, GF_TERM_EXT_INTERFACE, "GPAC Output Recorder", "gpac distribution" ); - - GF_SAFEALLOC ( uir, GF_AVRedirect ); - dr->process = avr_process; - dr->udta = uir; - uir->encodingMutex = gf_mx_new("RedirectAV_encodingMutex"); - assert( uir->encodingMutex); - uir->frameMutex = gf_mx_new("RedirectAV_frameMutex"); - uir->encodingThread = gf_th_new("RedirectAV_EncodingThread"); - uir->audioEncodingThread = gf_th_new("RedirectAV_AudioEncodingThread"); - uir->encode = 1; - uir->is_open = 0; - uir->is_running = 0; - return dr; -} - - -void avr_delete ( GF_BaseInterface *ifce ) -{ - GF_TermExt *dr = ( GF_TermExt * ) ifce; - GF_AVRedirect *avr = dr->udta; - avr->is_running = 0; - /* Ensure encoding is finished */ - gf_mx_p(avr->frameMutex); - gf_mx_v(avr->frameMutex); - gf_sleep(200); - gf_th_stop(avr->encodingThread); - gf_mx_del(avr->frameMutex); - avr->frameMutex = NULL; - gf_th_del(avr->encodingThread); - avr->encodingThread = NULL; - gf_mx_del(avr->encodingMutex); - avr->encodingMutex = NULL; - if ( avr->ts_implementation ) - { - ts_amux_del(avr->ts_implementation); - avr->ts_implementation = NULL; - } - avr->videoCodec = NULL; - if ( avr->YUVpicture ) - { - av_free ( avr->YUVpicture ); - } - if ( avr->yuv_data ) - av_free ( avr->yuv_data ); - avr->yuv_data = NULL; - avr->YUVpicture = NULL; - if ( avr->RGBpicture ) - { - av_free ( avr->RGBpicture ); - } - avr->RGBpicture = NULL; - if ( avr->swsContext ) - sws_freeContext ( avr->swsContext ); - avr->swsContext = NULL; - if ( avr->videoOutbuf ) - gf_free ( avr->videoOutbuf ); - avr->videoOutbuf = NULL; - if ( avr->pcmAudio ) - gf_ringbuffer_del(avr->pcmAudio); - avr->pcmAudio = NULL; - gf_global_resource_unlock(avr->globalLock); - avr->globalLock = NULL; - if (avr->audioEncodingThread){ - gf_th_stop(avr->audioEncodingThread); - gf_th_del(avr->audioEncodingThread); - } - avr->audioEncodingThread = NULL; - gf_free ( avr ); - gf_free ( dr ); -} - -GF_EXPORT -const u32 *QueryInterfaces() -{ - static u32 si [] = - { - GF_TERM_EXT_INTERFACE, - 0 - }; - return si; -} - -GF_EXPORT -GF_BaseInterface *LoadInterface ( u32 InterfaceType ) -{ - if ( InterfaceType == GF_TERM_EXT_INTERFACE ) return ( GF_BaseInterface * ) avr_new(); - return NULL; -} - -GF_EXPORT -void ShutdownInterface ( GF_BaseInterface *ifce ) -{ - switch ( ifce->InterfaceType ) - { - case GF_TERM_EXT_INTERFACE: - avr_delete ( ifce ); - break; - } -} +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean le Feuvre + * Copyright (c) 2010-20XX Telecom ParisTech + * All rights reserved + * + * This file is part of GPAC / AVI Recorder demo module + * + * 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 + +#if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(__MINGW32__) + +#define EMULATE_INTTYPES +#define EMULATE_FAST_INT +#ifndef inline +#define inline __inline +#endif + +#if defined(__SYMBIAN32__) +#define EMULATE_INTTYPES +#endif + + +#ifndef __MINGW32__ +#define __attribute__(s) +#endif + + +/*include FFMPEG APIs*/ +#ifdef _WIN32_WCE +#define inline __inline +#endif + + +# define INT64_C(x) (x ## i64) +# define UINT64_C(x) (x ## Ui64) + + +#endif + + +#include "ts_muxer.h" + +#define USE_GPAC_MPEG2TS +#undef USE_GPAC_MPEG2TS + +#define REDIRECT_AV_AUDIO_ENABLED 1 + +#ifdef USE_GPAC_MPEG2TS +#include "gpac_ts_muxer.c" +#else +#include "ffmpeg_ts_muxer.c" +#endif /* USE_GPAC_MPEG2TS */ + +#include +#include +#include + + +#if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(__GNUC__) + +#if defined(_WIN32_WCE) +#pragma comment(lib, "toolhelp") +#pragma comment(lib, "winsock") +#endif + +#define _TOSTR(_val) #_val +#define TOSTR(_val) _TOSTR(_val) + +#pragma comment(lib, "avcodec-"TOSTR(LIBAVCODEC_VERSION_MAJOR) ) +#pragma comment(lib, "avformat-"TOSTR(LIBAVFORMAT_VERSION_MAJOR) ) +#pragma comment(lib, "avutil-"TOSTR(LIBAVUTIL_VERSION_MAJOR) ) +#pragma comment(lib, "swscale-"TOSTR(LIBSWSCALE_VERSION_MAJOR) ) + +#endif + + +/* This number * 188 should be lower than the UDP packet size */ +#define TS_PACKETS_PER_UDP_PACKET 1 + +#define audioCodecBitrate 96000 + +#if !defined(WIN32) && !defined(_WIN32_WCE) +#include +#endif + +static const u32 maxFPS = 25; + +static const char * moduleName = "AVRedirect"; + +static const char * AVR_VIDEO_CODEC_OPTION = "VideoCodec"; + + +#define AVR_TIMERS_LENGHT 25 + +#define U32_ABS( a, b ) (a > b ? a - b : b - a) + +#define DUMP_MP3 +#undef DUMP_MP3 + +#if REDIRECT_AV_AUDIO_ENABLED +/** + * This thread sends the frame to TS mux + * \param Parameter The GF_AVRedirect pointer + */ +static Bool audio_encoding_thread_run(void *param) +{ + u8 * inBuff; + u8 * outBuff; + u32 inBuffSize, outBuffSize, samplesReaden, toRead; + u64 myTime = 0; + u32 frameCountSinceReset = 0; + u32 lastCurrentTime; + Bool sendPts = 1; + GF_AVRedirect * avr = (GF_AVRedirect*) param; + AVCodecContext * ctx = NULL; + assert( avr ); + + outBuffSize = FF_MIN_BUFFER_SIZE; + + outBuff = gf_malloc(outBuffSize* sizeof(u8)); + inBuff = NULL; +#ifdef DUMP_MP3 + FILE * mp3 = fopen("/tmp/dump.mp3", "w"); +#endif /* DUMP_MP3 */ + sendPts = 1; + gf_sc_add_audio_listener ( avr->term->compositor, &avr->audio_listen ); + while (avr->is_running && !ctx) { + ctx = ts_get_audio_codec_context(avr->ts_implementation); + gf_sleep(16); + } + if (!ctx) { + goto exit; + } + + printf("******* Audio Codec Context = %d/%d, start="LLU", frame_size=%u\n", ctx->time_base.num, ctx->time_base.den, ctx->timecode_frame_start, ctx->frame_size); + samplesReaden = ctx->frame_size * ctx->channels; + + //printf("SETUP input sample size=%u, output samplesize=%u, buffsize=%u, samplesReaden=%u\n", ctx->input_sample_size, ctx->frame_size, sizeof(outbuf), samplesReaden); + // 2 chars are needed for each short + toRead = samplesReaden * 2; + inBuffSize = toRead; + inBuff = gf_malloc(inBuffSize * sizeof(u8)); + while (avr->is_running && !avr->audioCurrentTime) { + gf_sleep(16); + } + myTime = lastCurrentTime = avr->audioCurrentTime; + frameCountSinceReset = 0; + while (avr->is_running) { + u32 readen; + if (U32_ABS(avr->audioCurrentTime, myTime) > 25000) { + //GF_LOG( GF_LOG_ERROR, GF_LOG_MODULE, ("[AVRedirect] Drift in audio : audioCurrentTime = %u, myTime=%u, resync...\n", avr->audioCurrentTime, myTime)); + //myTime = lastCurrentTime = avr->audioCurrentTime; + //frameCountSinceReset = 0; + sendPts = 1; + } + while (toRead <= gf_ringbuffer_available_for_read(avr->pcmAudio) ) { + memset( inBuff, 0, inBuffSize); + memset( outBuff, 0, outBuffSize); + readen = gf_ringbuffer_read(avr->pcmAudio, inBuff, toRead); + assert( readen == toRead ); + if (avr->encode) + { + //u32 oldFrameSize = ctx->frame_size; + //ctx->frame_size = readable / (2 * ctx->channels); + //assert( oldFrameSize <= ctx->frame_size ); + /* buf_size * input_sample_size / output_sample_size */ + int encoded = avcodec_encode_audio(ctx, outBuff, outBuffSize, (const short *) inBuff); + if (encoded < 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[RedirectAV]: failed to encode audio, buffer size=%u, readen=%u, frame_size=%u\n", outBuffSize, readen, ctx->frame_size)); + } else if (encoded > 0) { + ts_encode_audio_frame(avr->ts_implementation, outBuff, encoded, sendPts ? myTime : AV_NOPTS_VALUE ); + frameCountSinceReset++; +#ifdef DUMP_MP3 + fwrite( outBuff, sizeof(char), encoded, mp3); +#endif /* DUMP_MP3 */ + //if (ctx->codec->id == CODEC_ID_MP3) { + /* It seems the MP3 codec only fetches 50% of data... */ + // myTime= lastCurrentTime + (frameCountSinceReset * ctx->frame_size * 500 / ctx->sample_rate); + //} else + //myTime = lastCurrentTime + (frameCountSinceReset * toRead * 1000 / ctx->sample_rate/ ctx->channels / 4); + /* Avoid overflow , multiply by 10 and divide sample rate by 100 instead of *1000 / sampleRate */ + myTime = lastCurrentTime + (frameCountSinceReset * toRead * 10 / (ctx->sample_rate / 100) / ctx->channels / 4); + //sendPts = 0; + sendPts = 1; + } else { + GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[RedirectAV]: no encoded frame.\n")); + //frameCountSinceReset++; + } + //ctx->frame_size = oldFrameSize; + } + } + gf_sleep(1); + } +exit: + GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[AVRedirect] Ending audio encoding thread...\n")); + if (inBuff) + gf_free( inBuff ); + if (outBuff) + gf_free( outBuff ); +#ifdef DUMP_MP3 + if (mp3) + fclose(mp3); +#endif /* DUMP_MP3 */ + if (avr->term) + gf_sc_remove_audio_listener ( avr->term->compositor, &avr->audio_listen ); + return GF_OK; +} +#endif + +/** + * This thread sends the frame to TS mux + * \param Parameter The GF_AVRedirect pointer + */ +static Bool video_encoding_thread_run(void *param) +{ + GF_AVRedirect * avr = (GF_AVRedirect*) param; + u64 currentFrameTimeProcessed = 0, lastEncodedFrameTime = 0; + AVCodecContext * ctx = NULL; + assert( avr ); + gf_sc_add_video_listener ( avr->term->compositor, &avr->video_listen ); + while (avr->is_running && (!ctx || !avr->swsContext)) { + ctx = ts_get_video_codec_context(avr->ts_implementation); + gf_sleep(16); + } + if (!ctx) { + goto exit; + } + printf("******* Video Codec Context = %d/%d, start="LLU"\n", ctx->time_base.num, ctx->time_base.den, ctx->timecode_frame_start); + while (avr->is_running) { + { + gf_mx_p(avr->frameMutex); + while (!avr->frameTime || currentFrameTimeProcessed == avr->frameTime) { + gf_mx_v(avr->frameMutex); + if (!avr->is_running) { + goto exit; + } + gf_mx_p(avr->frameMutex); + gf_sleep(1); + } + assert( currentFrameTimeProcessed != avr->frameTime); + currentFrameTimeProcessed = avr->frameTime; + { + avpicture_fill ( ( AVPicture * ) avr->RGBpicture, avr->frame, PIX_FMT_RGB24, avr->srcWidth, avr->srcHeight ); + assert( avr->swsContext ); + sws_scale ( avr->swsContext, +#ifdef USE_AVCODEC2 + ( const uint8_t * const * ) +#else + ( uint8_t ** ) +#endif /* USE_AVCODEC2 */ + avr->RGBpicture->data, avr->RGBpicture->linesize, + 0, avr->srcHeight, + avr->YUVpicture->data, avr->YUVpicture->linesize ); +#ifdef AVR_DUMP_RAW_AVI + if ( AVI_write_frame ( avr->avi_out, avr->frame, avr->size, 1 ) <0 ) + { + GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Error writing video frame\n" ) ); + } +#endif /* AVR_DUMP_RAW_AVI */ + gf_mx_v(avr->frameMutex); + if (avr->encode) + { + int written; + //u32 sysclock = gf_sys_clock(); + avr->YUVpicture->pts = currentFrameTimeProcessed; + //printf("Encoding frame PTS="LLU", frameNum=%u, time=%u...", avr->YUVpicture->pts, avr->YUVpicture->coded_picture_number, currentFrameTimeProcessed); + written = avcodec_encode_video ( ctx, avr->videoOutbuf, avr->videoOutbufSize, avr->YUVpicture ); + //ctx->coded_frame->pts = currentFrameTimeProcessed; + if ( written < 0 ) + { + GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Error while encoding video frame =%d\n", written ) ); + } else + if ( written > 0 ) + { + ts_encode_video_frame(avr->ts_implementation, avr->videoOutbuf, written); + } + lastEncodedFrameTime = currentFrameTimeProcessed; + } + } + } + avr->frameTimeEncoded = currentFrameTimeProcessed; + gf_sleep(1); + } /* End of main loop */ +exit: + GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[AVRedirect] Ending video encoding thread...\n")); + if (avr->term) + gf_sc_remove_video_listener ( avr->term->compositor, &avr->video_listen ); + return 0; +} + +#define VIDEO_RATE 400000 + +static Bool start_if_needed(GF_AVRedirect *avr) { + enum PixelFormat pxlFormatForCodec = PIX_FMT_YUV420P; + if (avr->is_open) + return 0; + gf_mx_p(avr->frameMutex); + if (avr->is_open) { + gf_mx_v(avr->frameMutex); + return 0; + } + if (!avr->srcWidth || !avr->srcHeight +#if REDIRECT_AV_AUDIO_ENABLED + || !avr->audioSampleRate || !avr->audioChannels +#endif + ) { + gf_mx_v(avr->frameMutex); + return 3; + } +#ifdef AVR_DUMP_RAW_AVI + avr->avi_out = AVI_open_output_file ( "dump.avi" ); + if ( !avr->avi_out ) + { + gf_mx_v(avr->frameMutex); + GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Error opening output AVI file\n" ) ); + return 4; + } +#endif /* AVR_DUMP_RAW_AVI */ + GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[AVRedirect] Initializing...\n")); + if (!avr->pcmAudio) + avr->pcmAudio = gf_ringbuffer_new(32768); + + /* Setting up the video encoding ... */ + { + avr->YUVpicture = avr->RGBpicture = NULL; + avr->videoOutbuf = NULL; +#if REDIRECT_AV_AUDIO_ENABLED + if ( !avr->audioCodec) + { + gf_mx_v(avr->frameMutex); + GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Cannot find audio codec.\n" ) ); + return 1; + } +#endif + + if ( !avr->videoCodec ) + { + GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Cannot find video codec.\n" ) ); + return 2; + } + + if (avr->videoCodec->id == CODEC_ID_MJPEG) { + pxlFormatForCodec = PIX_FMT_YUVJ420P; + } + + avr->RGBpicture = avcodec_alloc_frame(); + assert ( avr->RGBpicture ); + avr->RGBpicture->data[0] = NULL; + avr->YUVpicture = avcodec_alloc_frame(); + assert ( avr->YUVpicture ); + { + u32 sz = sizeof ( uint8_t ) * avpicture_get_size ( pxlFormatForCodec, avr->srcWidth, avr->srcHeight ); + avr->yuv_data = av_malloc ( sz ); /* size for YUV 420 */ + assert ( avr->yuv_data ); + memset ( avr->yuv_data, 0, sz ); + avpicture_fill ( ( AVPicture* ) avr->YUVpicture, avr->yuv_data, pxlFormatForCodec, avr->srcWidth, avr->srcHeight ); + avr->YUVpicture->coded_picture_number = 0; + } + avr->videoOutbufSize = avr->srcHeight * avr->srcWidth * 4; + avr->videoOutbuf = gf_malloc ( avr->videoOutbufSize ); + memset ( avr->videoOutbuf, 0, avr->videoOutbufSize ); + } +#ifdef AVR_DUMP_RAW_AVI + GF_LOG ( GF_LOG_INFO, GF_LOG_MODULE, ( "[AVRedirect] Open output AVI file %s\n", "dump.avi" ) ); +#endif /* AVR_DUMP_RAW_AVI */ + /* Setting up the TS mux */ + { + /* + GF_Socket * ts_output_udp_sk = gf_sk_new ( GF_SOCK_TYPE_UDP ); + if ( gf_sk_is_multicast_address ( avr->udp_address ) ) + { + e = gf_sk_setup_multicast ( ts_output_udp_sk, avr->udp_address, avr->udp_port, 0, 0, NULL ); + } + else + { + e = gf_sk_bind ( ts_output_udp_sk, NULL, avr->udp_port, avr->udp_address, avr->udp_port, GF_SOCK_REUSE_PORT ); + } + gf_sk_set_buffer_size(ts_output_udp_sk, 0, 188 * TS_PACKETS_PER_UDP_PACKET); + gf_sk_set_block_mode(ts_output_udp_sk, 0);*/ + assert( avr->destination ); + avr->ts_implementation = ts_amux_new(avr, VIDEO_RATE, avr->srcWidth, avr->srcHeight, audioCodecBitrate); + } + /* + if ( e ) + { + GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Error while initializing UDP address %s\n", gf_error_to_string ( e ) ) ); + return e; + } + */ + avr->is_open = avr->ts_implementation != NULL; + gf_mx_v(avr->frameMutex); + return avr->is_open ? 1 : 0; +} + + +static GF_Err avr_open ( GF_AVRedirect *avr ) +{ + assert( avr ); + if ( avr->is_open) + return GF_OK; + if (!avr->is_running) { + avr->is_running = 1; + gf_th_run(avr->encodingThread, video_encoding_thread_run, avr); +#if REDIRECT_AV_AUDIO_ENABLED + gf_th_run(avr->audioEncodingThread, audio_encoding_thread_run, avr); +#endif + } + return GF_OK; +} + + + +static void avr_on_audio_frame ( void *udta, char *buffer, u32 buffer_size, u32 time, u32 delay_ms ) +{ + GF_AVRedirect *avr = ( GF_AVRedirect * ) udta; + if (start_if_needed(avr)) + return; +#ifdef AVR_DUMP_RAW_AVI + AVI_write_audio ( avr->avi_out, buffer, buffer_size ); +#endif /* AVR_DUMP_RAW_AVI */ + { + gf_ringbuffer_write(avr->pcmAudio, buffer, buffer_size); + avr->audioCurrentTime = time - delay_ms; + } +} + +static void avr_on_audio_reconfig ( void *udta, u32 samplerate, u32 bits_per_sample, u32 nb_channel, u32 channel_cfg ) +{ + GF_AVRedirect *avr = ( GF_AVRedirect * ) udta; + if (avr->audioSampleRate != samplerate || avr->audioChannels != nb_channel) { + GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[AVRedirect] Audio %u Hz, bitsPerSample=%u, nbchannels=%u\n", samplerate, bits_per_sample, nb_channel)); +#ifdef AVR_DUMP_RAW_AVI + AVI_set_audio ( avr->avi_out, nb_channel, samplerate, bits_per_sample, WAVE_FORMAT_PCM, 0 ); +#endif /* AVR_DUMP_RAW_AVI */ + avr->audioChannels = nb_channel; + avr->audioSampleRate = samplerate; + } +} + +static void avr_on_video_frame ( void *udta, u32 time ) +{ + u32 i, j; + GF_Err e; + GF_VideoSurface fb; + GF_AVRedirect *avr = ( GF_AVRedirect * ) udta; + if (start_if_needed(avr)) + return; + gf_mx_p(avr->frameMutex); + e = gf_sc_get_screen_buffer ( avr->term->compositor, &fb, 0 ); + if ( e ) + { + GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Error grabing frame buffer %s\n", gf_error_to_string ( e ) ) ); + return; + } + /*convert frame*/ + for ( i=0; iframe + i * fb.width * 3; + char *src = fb.video_buffer + i * fb.pitch_y; + for ( j=0; jframeTime = time; + gf_mx_v(avr->frameMutex); + gf_sc_release_screen_buffer ( avr->term->compositor, &fb ); + GF_LOG ( GF_LOG_DEBUG, GF_LOG_MODULE, ( "[AVRedirect] Writing video frame\n" ) ); +} + +static void avr_on_video_reconfig ( void *udta, u32 width, u32 height ) +{ + + GF_AVRedirect *avr = ( GF_AVRedirect * ) udta; + + if ((avr->srcHeight != height || avr->srcWidth != width)) + { +#ifdef AVR_DUMP_RAW_AVI + char comp[5]; + comp[0] = comp[1] = comp[2] = comp[3] = comp[4] = 0; + AVI_set_video ( avr->avi_out, width, height, 30, comp ); +#endif /* AVR_DUMP_RAW_AVI */ + GF_LOG ( GF_LOG_INFO, GF_LOG_MODULE, ( "[AVRedirect] Video reconfig width %d height %d\n", width, height ) ); + gf_mx_p(avr->frameMutex); + if ( avr->frame ) gf_free ( avr->frame ); + avr->size = 3*width*height; + avr->frame = gf_malloc ( sizeof ( char ) *avr->size ); + avr->srcWidth = width; + avr->srcHeight = height; + avr->swsContext = sws_getCachedContext ( avr->swsContext, avr->srcWidth, avr->srcHeight, PIX_FMT_RGB24, avr->srcWidth, avr->srcHeight, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL ); + gf_mx_v(avr->frameMutex); + } +} + + +#ifdef MULTITHREAD_REDIRECT_AV +/** + * This thread sends the TS packets over the network + * \param Parameter The GF_AVRedirect pointer + */ +static Bool ts_thread_run(void *param) +{ + GF_Err e; + GF_AVRedirect * avr = (GF_AVRedirect*) param; + assert( avr ); + gf_mx_p(avr->tsMutex); + while (!avr->frameTimeEncoded && avr->is_running) { + gf_mx_v(avr->tsMutex); + gf_sleep(1); + gf_mx_p(avr->tsMutex); + } + printf("avr->frameTimeEncoded="LLU"\n", avr->frameTimeEncoded); + + while (avr->is_running) { + e = sendTSMux(avr); + gf_mx_v(avr->tsMutex); + gf_mx_p(avr->tsMutex); + } + gf_mx_v(avr->tsMutex); + return 0; +} +#endif /* MULTITHREAD_REDIRECT_AV */ + +static const char * possibleCodecs = "supported codecs : MPEG-1, MPEG-2, MPEG-4, MSMPEG-4, H263, H263I, H263P, RV10, MJPEG"; + +/*#define DEFAULT_UDP_OUT_ADDRESS "127.0.0.1" +#define DEFAULT_UDP_OUT_PORT 1234 +#define DEFAULT_UDP_OUT_PORT_STR "1234"*/ + +#define AVR_DEFAULT_DESTINATION "udp://224.0.0.1:1234" + +#include + + +static void avr_close ( GF_AVRedirect *avr ) +{ + if ( !avr->is_open ) return; + avr->is_open = 0; +#ifdef AVR_DUMP_RAW_AVI + GF_LOG ( GF_LOG_INFO, GF_LOG_MODULE, ( "[AVRedirect] Closing output AVI file\n" ) ); + AVI_close ( avr->avi_out ); + avr->avi_out = NULL; +#endif /* AVR_DUMP_RAW_AVI */ +} + +static Bool avr_on_event ( void *udta, GF_Event *evt, Bool consumed_by_compositor ) +{ + GF_AVRedirect *avr = udta; + switch ( evt->type ) + { + case GF_EVENT_CONNECT: + if ( evt->connect.is_connected ) + { + avr_open ( avr ); + } + else + { + avr_close ( avr ); + } + break; + } + return 0; +} + +static const char * AVR_ENABLED_OPTION = "Enabled"; + +//static const char * AVR_UDP_PORT_OPTION = "udp.port"; + +//static const char * AVR_UDP_ADDRESS_OPTION = "udp.address"; + +static const char * AVR_DESTINATION = "destination"; + +static Bool avr_process ( GF_TermExt *termext, u32 action, void *param ) +{ + const char *opt; + GF_AVRedirect *avr = termext->udta; + + switch ( action ) + { + case GF_TERM_EXT_START: + avr->term = ( GF_Terminal * ) param; + opt = gf_modules_get_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_ENABLED_OPTION ); + if ( !opt ) + gf_modules_set_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_ENABLED_OPTION, "no" ); + if ( !opt || strcmp ( opt, "yes" ) ) return 0; + opt = gf_modules_get_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_VIDEO_CODEC_OPTION ); + avr->globalLock = gf_global_resource_lock("AVRedirect:output"); + if (!avr->globalLock) { + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("Failed to lock global resource 'AVRedirect:output', another GPAC instance must be running, disabling AVRedirect\n")); + return 0; + } + /* must be called before using avcodec lib */ + avcodec_init(); + + /* register all the codecs */ + avcodec_register_all(); + if ( !opt ) + gf_modules_set_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_VIDEO_CODEC_OPTION, possibleCodecs ); + { + if ( !opt ) + { + avr->videoCodec = avcodec_find_encoder ( CODEC_ID_MPEG2VIDEO ); + } + else if ( !strcmp ( "MPEG-1", opt ) ) + { + avr->videoCodec=avcodec_find_encoder ( CODEC_ID_MPEG1VIDEO ); + } + else if ( !strcmp ( "MPEG-2", opt ) ) + { + avr->videoCodec=avcodec_find_encoder ( CODEC_ID_MPEG2VIDEO ); + } + else if ( !strcmp ( "MPEG-4", opt ) ) + { + avr->videoCodec=avcodec_find_encoder ( CODEC_ID_MPEG4 ); + } + else if ( !strcmp ( "MSMPEG-4", opt ) ) + { + avr->videoCodec=avcodec_find_encoder ( CODEC_ID_MSMPEG4V3 ); + } + else if ( !strcmp ( "H263", opt ) ) + { + avr->videoCodec=avcodec_find_encoder ( CODEC_ID_H263 ); + } + else if ( !strcmp ( "RV10", opt ) ) + { + avr->videoCodec = avcodec_find_encoder ( CODEC_ID_RV10 ); + } + else if ( !strcmp ( "H263P", opt ) ) + { + avr->videoCodec=avcodec_find_encoder ( CODEC_ID_H263P ); + } + else if ( !strcmp ( "H263I", opt ) ) + { + avr->videoCodec=avcodec_find_encoder ( CODEC_ID_H263I ); + } + else if ( !strcmp( "MJPEG", opt)) + { + avr->videoCodec=avcodec_find_encoder( CODEC_ID_MJPEG); + } + else + { + GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] Not a known Video codec : %s, using MPEG-2 video instead, %s\n", opt, possibleCodecs ) ); + avr->videoCodec = avcodec_find_encoder ( CODEC_ID_MPEG2VIDEO ); + } + } +#if REDIRECT_AV_AUDIO_ENABLED + avr->audioCodec = avcodec_find_encoder(CODEC_ID_MP2); +#endif + /* + opt = gf_modules_get_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_UDP_ADDRESS_OPTION); + if (!opt) { + gf_modules_set_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_UDP_ADDRESS_OPTION, DEFAULT_UDP_OUT_ADDRESS); + avr->udp_address = DEFAULT_UDP_OUT_ADDRESS; + GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] %s not set, using %s\n", AVR_UDP_ADDRESS_OPTION, DEFAULT_UDP_OUT_ADDRESS ) ); + } else + avr->udp_address = opt; + opt = gf_modules_get_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_UDP_PORT_OPTION); + if (opt) { + char *endPtr = NULL; + unsigned int x = strtoul(opt, &endPtr, 10); + if (endPtr == opt || x > 65536) { + printf("Failed to parse : %s\n", opt); + opt = NULL; + } else + avr->udp_port = (u16) x; + } + if (!opt) { + gf_modules_set_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_UDP_PORT_OPTION, DEFAULT_UDP_OUT_PORT_STR); + GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] %s is not set or valid, using %s\n", AVR_UDP_PORT_OPTION, DEFAULT_UDP_OUT_PORT_STR ) ); + avr->udp_port = DEFAULT_UDP_OUT_PORT; + } + */ + opt = gf_modules_get_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_DESTINATION); + if (!opt) { + gf_modules_set_option ( ( GF_BaseInterface* ) termext, moduleName, AVR_DESTINATION, AVR_DEFAULT_DESTINATION); + avr->destination = AVR_DEFAULT_DESTINATION; + GF_LOG ( GF_LOG_ERROR, GF_LOG_MODULE, ( "[AVRedirect] %s not set, using %s\n", AVR_DESTINATION, AVR_DEFAULT_DESTINATION ) ); + } else + avr->destination = opt; + avr->audio_listen.udta = avr; + avr->audio_listen.on_audio_frame = avr_on_audio_frame; + avr->audio_listen.on_audio_reconfig = avr_on_audio_reconfig; + avr->video_listen.udta = avr; + avr->video_listen.on_video_frame = avr_on_video_frame; + avr->video_listen.on_video_reconfig = avr_on_video_reconfig; + + avr->term_listen.udta = avr; + avr->term_listen.on_event = avr_on_event; + gf_term_add_event_filter ( avr->term, &avr->term_listen ); + return 1; + + case GF_TERM_EXT_STOP: + gf_term_remove_event_filter ( avr->term, &avr->term_listen ); + avr->term = NULL; + break; + + /*if not threaded, perform our tasks here*/ + case GF_TERM_EXT_PROCESS: + break; + } + return 0; +} + + +GF_TermExt *avr_new() +{ + GF_TermExt *dr; + GF_AVRedirect *uir; + GF_SAFEALLOC ( dr, GF_TermExt ); + GF_REGISTER_MODULE_INTERFACE ( dr, GF_TERM_EXT_INTERFACE, "GPAC Output Recorder", "gpac distribution" ); + + GF_SAFEALLOC ( uir, GF_AVRedirect ); + dr->process = avr_process; + dr->udta = uir; + uir->encodingMutex = gf_mx_new("RedirectAV_encodingMutex"); + assert( uir->encodingMutex); + uir->frameMutex = gf_mx_new("RedirectAV_frameMutex"); + uir->encodingThread = gf_th_new("RedirectAV_EncodingThread"); + uir->audioEncodingThread = gf_th_new("RedirectAV_AudioEncodingThread"); + uir->encode = 1; + uir->is_open = 0; + uir->is_running = 0; + return dr; +} + + +void avr_delete ( GF_BaseInterface *ifce ) +{ + GF_TermExt *dr = ( GF_TermExt * ) ifce; + GF_AVRedirect *avr = dr->udta; + avr->is_running = 0; + /* Ensure encoding is finished */ + gf_mx_p(avr->frameMutex); + gf_mx_v(avr->frameMutex); + gf_sleep(200); + gf_th_stop(avr->encodingThread); + gf_mx_del(avr->frameMutex); + avr->frameMutex = NULL; + gf_th_del(avr->encodingThread); + avr->encodingThread = NULL; + gf_mx_del(avr->encodingMutex); + avr->encodingMutex = NULL; + if ( avr->ts_implementation ) + { + ts_amux_del(avr->ts_implementation); + avr->ts_implementation = NULL; + } + avr->videoCodec = NULL; + if ( avr->YUVpicture ) + { + av_free ( avr->YUVpicture ); + } + if ( avr->yuv_data ) + av_free ( avr->yuv_data ); + avr->yuv_data = NULL; + avr->YUVpicture = NULL; + if ( avr->RGBpicture ) + { + av_free ( avr->RGBpicture ); + } + avr->RGBpicture = NULL; + if ( avr->swsContext ) + sws_freeContext ( avr->swsContext ); + avr->swsContext = NULL; + if ( avr->videoOutbuf ) + gf_free ( avr->videoOutbuf ); + avr->videoOutbuf = NULL; + if ( avr->pcmAudio ) + gf_ringbuffer_del(avr->pcmAudio); + avr->pcmAudio = NULL; + gf_global_resource_unlock(avr->globalLock); + avr->globalLock = NULL; + if (avr->audioEncodingThread){ + gf_th_stop(avr->audioEncodingThread); + gf_th_del(avr->audioEncodingThread); + } + avr->audioEncodingThread = NULL; + gf_free ( avr ); + gf_free ( dr ); +} + +GF_EXPORT +const u32 *QueryInterfaces() +{ + static u32 si [] = + { + GF_TERM_EXT_INTERFACE, + 0 + }; + return si; +} + +GF_EXPORT +GF_BaseInterface *LoadInterface ( u32 InterfaceType ) +{ + if ( InterfaceType == GF_TERM_EXT_INTERFACE ) return ( GF_BaseInterface * ) avr_new(); + return NULL; +} + +GF_EXPORT +void ShutdownInterface ( GF_BaseInterface *ifce ) +{ + switch ( ifce->InterfaceType ) + { + case GF_TERM_EXT_INTERFACE: + avr_delete ( ifce ); + break; + } +} diff --git a/modules/rtp_in/Makefile b/modules/rtp_in/Makefile index 194fc52..ed25165 100644 --- a/modules/rtp_in/Makefile +++ b/modules/rtp_in/Makefile @@ -32,7 +32,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(EXTRALIBS) ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_rtp_in-static.so $(OBJS) -L../../bin/gcc -lgpac_static $(EXTRALIBS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_rtp_in-static.$(DYN_LIB_SUFFIX) $(OBJS) -L../../bin/gcc -lgpac_static $(EXTRALIBS) endif diff --git a/modules/rtp_in/rtp_stream.c b/modules/rtp_in/rtp_stream.c index d42ecf0..e7bf1f0 100644 --- a/modules/rtp_in/rtp_stream.c +++ b/modules/rtp_in/rtp_stream.c @@ -135,6 +135,8 @@ RTPStream *RP_NewStream(RTPClient *rtp, GF_SDPMedia *media, GF_SDPInfo *sdp, RTP Bool force_bcast = 0; Double Start, End; Float CurrentTime; + u16 rvc_predef = 0; + char *rvc_config_att = NULL; u32 s_port_first, s_port_last; GF_X_Attribute *att; Bool is_migration = 0; @@ -166,6 +168,10 @@ RTPStream *RP_NewStream(RTPClient *rtp, GF_SDPMedia *media, GF_SDPInfo *sdp, RTP } else if (!stricmp(att->Name, "x-server-port") ) { sscanf(att->Value, "%u-%u", &s_port_first, &s_port_last); + } else if (!stricmp(att->Name, "rvc-config-predef")) { + rvc_predef = atoi(att->Value); + } else if (!stricmp(att->Name, "rvc-config")) { + rvc_config_att = att->Value; } } @@ -269,6 +275,40 @@ RTPStream *RP_NewStream(RTPClient *rtp, GF_SDPMedia *media, GF_SDPInfo *sdp, RTP gf_rtp_set_info_rtp(tmp->rtp_ch, rtp_seq, rtp_time, ssrc); tmp->status = RTP_SessionResume; } + + if (rvc_predef) { + tmp->depacketizer->sl_map.rvc_predef = rvc_predef ; + } else if (rvc_config_att) { + char *rvc_data=NULL; + u32 rvc_size; + Bool is_gz = 0; + if (!strncmp(rvc_config_att, "data:application/rvc-config+xml", 32) && strstr(rvc_config_att, "base64") ) { + char *data = strchr(rvc_config_att, ','); + if (data) { + rvc_size = strlen(data) * 3 / 4 + 1; + rvc_data = gf_malloc(sizeof(char) * rvc_size); + rvc_size = gf_base64_decode(data, strlen(data), rvc_data, rvc_size); + rvc_data[rvc_size] = 0; + } + if (!strncmp(rvc_config_att, "data:application/rvc-config+xml+gz", 35)) is_gz = 1; + } else if (!strnicmp(rvc_config_att, "http://", 7) || !strnicmp(rvc_config_att, "https://", 8) ) { + char *mime; + if (gf_dm_get_file_memory(rvc_config_att, &rvc_data, &rvc_size, &mime) == GF_OK) { + if (mime && strstr(mime, "+gz")) is_gz = 1; + if (mime) gf_free(mime); + } + } + if (rvc_data) { + if (is_gz) { + gf_gz_decompress_payload(rvc_data, rvc_size, &tmp->depacketizer->sl_map.rvc_config, &tmp->depacketizer->sl_map.rvc_config_size); + gf_free(rvc_data); + } else { + tmp->depacketizer->sl_map.rvc_config = rvc_data; + tmp->depacketizer->sl_map.rvc_config_size = rvc_size; + } + } + } + return tmp; } diff --git a/modules/rtp_in/sdp_fetch.c b/modules/rtp_in/sdp_fetch.c index 47f470a..6551d6f 100644 --- a/modules/rtp_in/sdp_fetch.c +++ b/modules/rtp_in/sdp_fetch.c @@ -101,25 +101,23 @@ void SDP_NetIO(void *cbk, GF_NETIO_Parameter *param) case GF_NETIO_DATA_TRANSFERED: if (sdp->original_url) { u32 sdp_size; - gf_dm_sess_get_stats(rtp->dnload, NULL, NULL, &sdp_size, NULL, NULL, NULL); - if (!sdp_size) - break; - } - - { - const char *szFile = gf_dm_sess_get_cache_name(rtp->dnload); - if (!szFile) { - e = GF_SERVICE_ERROR; - } else { - e = GF_OK; - RP_SDPFromFile(rtp, (char *) szFile, sdp->chan); - gf_free(sdp->remote_url); - if (sdp->original_url) gf_free(sdp->original_url); - gf_free(sdp); - rtp->sdp_temp = NULL; - return; + e = gf_dm_sess_get_stats(rtp->dnload, NULL, NULL, &sdp_size, NULL, NULL, NULL); + if (sdp_size) { + const char *szFile = gf_dm_sess_get_cache_name(rtp->dnload); + if (!szFile) { + e = GF_SERVICE_ERROR; + } else { + e = GF_OK; + RP_SDPFromFile(rtp, (char *) szFile, sdp->chan); + gf_free(sdp->remote_url); + if (sdp->original_url) gf_free(sdp->original_url); + gf_free(sdp); + rtp->sdp_temp = NULL; + return; + } } } + break; default: if (e == GF_OK) return; } diff --git a/modules/rtp_in/sdp_load.c b/modules/rtp_in/sdp_load.c index 6f7a3ae..7d691d4 100644 --- a/modules/rtp_in/sdp_load.c +++ b/modules/rtp_in/sdp_load.c @@ -186,6 +186,15 @@ static GF_ObjectDescriptor *RP_GetChannelOD(RTPStream *ch, u32 ch_idx) memcpy(esd->decoderConfig->decoderSpecificInfo->data, ch->depacketizer->sl_map.config, sizeof(char) * ch->depacketizer->sl_map.configSize); esd->decoderConfig->decoderSpecificInfo->dataLength = ch->depacketizer->sl_map.configSize; } + if (ch->depacketizer->sl_map.rvc_predef) { + esd->decoderConfig->predefined_rvc_config = ch->depacketizer->sl_map.rvc_predef; + } else if (ch->depacketizer->sl_map.rvc_config) { + esd->decoderConfig->rvc_config = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); + esd->decoderConfig->rvc_config->data = ch->depacketizer->sl_map.rvc_config; + esd->decoderConfig->rvc_config->dataLength = ch->depacketizer->sl_map.rvc_config_size; + ch->depacketizer->sl_map.rvc_config = NULL; + ch->depacketizer->sl_map.rvc_config_size = 0; + } gf_list_add(od->ESDescriptors, esd); return od; } diff --git a/modules/rvc_dec/Makefile b/modules/rvc_dec/Makefile new file mode 100644 index 0000000..008d85f --- /dev/null +++ b/modules/rvc_dec/Makefile @@ -0,0 +1,56 @@ +include ../../config.mak + +vpath %.c $(SRC_PATH)/modules/rvc_dec + +CFLAGS= $(OPTFLAGS) -I$(SRC_PATH)/include + +ifeq ($(DEBUGBUILD), yes) +CFLAGS+=-g +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD), yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + +LDFLAGS+=-lRVCDecoder + +#common obj +OBJS= rvc_dec.o + +SRCS := $(OBJS:.o=.c) + +LIB=gm_rvc_dec.$(DYN_LIB_SUFFIX) + + +all: $(LIB) + + +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + + +clean: + rm -f $(OBJS) ../../bin/gcc/$(LIB) + +dep: depend + +depend: + rm -f .depend + $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend + +distclean: clean + rm -f Makefile.bak .depend + + + +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/modules/rvc_dec/rvc_dec.c b/modules/rvc_dec/rvc_dec.c new file mode 100644 index 0000000..cb7c8ce --- /dev/null +++ b/modules/rvc_dec/rvc_dec.c @@ -0,0 +1,447 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Telecom ParisTech 2010- + * Author(s): Jean Le Feuvre + * All rights reserved + * + * This file is part of GPAC / OpenSVC Decoder module + * + * 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 +#include +#include + +#ifdef WIN32 +#define DllImport __declspec( dllimport ) + + +#if !defined(__GNUC__) +# pragma comment(lib, "RVCDecoder") +#endif + +#else +#define DllImport +#endif + + + +typedef struct{ + int Width; + int Height; + unsigned char* pY[1]; + unsigned char* pU[1]; + unsigned char* pV[1]; +} RVCFRAME; + + +DllImport int rvc_init(char* XDF, char* VTLFolder, int isAVCFile); +DllImport int rvc_decode(unsigned char* nal, int nal_length, char *outBuffer, int newBuffer); +DllImport void rvc_close(); + + +typedef struct +{ + u16 ES_ID; + u32 width, stride, height, out_size, pixel_ar, layer; + Bool first_frame; + + u32 nalu_size_length; + + void *codec; +} RVCDec; + + +static GF_Err RVCD_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) +{ + u32 i, count; + s32 res; + char Picture; + RVCDec *ctx = (RVCDec*) ifcg->privateStack; + char* VTLFolder; + char *XDF_doc = NULL; + int isAVCFile; + + /*not supported in this version*/ + if (esd->dependsOnESID) return GF_NOT_SUPPORTED; + + ctx->ES_ID = esd->ESID; + ctx->width = ctx->height = ctx->out_size = 0; + + VTLFolder = (char *)gf_modules_get_option((GF_BaseInterface *)ifcg, "RVCDecoder", "VTLPath"); + if (!VTLFolder) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[RVC_Dec] Cannot locate VTL: path is unknown. Please indicate path in GPAC config file:\n[RVCDecoder]\nVTLPath=PATH\n")); + return GF_SERVICE_ERROR; + } else { + GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[RVC_Dec] Using VTL in %s\n", VTLFolder)); + } + + /*initialize RVC*/ + if (esd->decoderConfig->predefined_rvc_config) { + char opt[100], *path; + FILE *f; + u32 size; + sprintf(opt, "Predefined_%d", esd->decoderConfig->predefined_rvc_config); + path = gf_modules_get_option((GF_BaseInterface *)ifcg, "RVCDecoder", (const char *)opt); + if (!opt) return GF_NOT_SUPPORTED; + f = fopen(path, "rt"); + if (!f) return GF_NOT_SUPPORTED; + fseek(f, 0, SEEK_END); + size = ftell(f); + fseek(f, 0, SEEK_SET); + XDF_doc = gf_malloc(sizeof(char)*(size+1)); + if (!XDF_doc) { + fclose(f); + return GF_OUT_OF_MEM; + } + fread(XDF_doc, 1, size, f); + fclose(f); + XDF_doc[size]=0; + } else { + if (!esd->decoderConfig->rvc_config) + return GF_NOT_SUPPORTED; + XDF_doc = esd->decoderConfig->rvc_config->data; + } + + + if(esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_AVC) isAVCFile = 1; + else isAVCFile = 0; + + rvc_init(XDF_doc, VTLFolder, isAVCFile); //->data contains the uncompressed XDF + + /*free data*/ + gf_free(XDF_doc); + if (esd->decoderConfig->rvc_config) { + esd->decoderConfig->rvc_config->data = NULL; + esd->decoderConfig->rvc_config->dataLength = 0; + } + + /*decoder config not known, output buffers will be reconfigured at run-time*/ + if (!esd->decoderConfig->decoderSpecificInfo || !esd->decoderConfig->decoderSpecificInfo->data) + return GF_OK; + + /*initialize the decoder */ + if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_AVC) { + GF_AVCConfig *cfg = gf_odf_avc_cfg_read(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); + if (!cfg) return GF_NON_COMPLIANT_BITSTREAM; + ctx->nalu_size_length = cfg->nal_unit_size; + + /*decode all NALUs*/ + count = gf_list_count(cfg->sequenceParameterSets); + for (i=0; isequenceParameterSets, i); + + gf_avc_get_sps_info(slc->data, slc->size, &slc->id, &w, &h, &par_n, &par_d); + /*by default use the base layer*/ + if (!i) { + if ((ctx->widthheightwidth = w; + ctx->height = h; + if ( ((s32)par_n>0) && ((s32)par_d>0) ) + ctx->pixel_ar = (par_n<<16) || par_d; + } + } + /* call decode - warning for AVC: the data blocks do not contain startcode prefixes (00000001), you may need to add them) */ + + res = rvc_decode(slc->data, slc->size, &Picture, 1); + if (res<0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[SVC Decoder] Error decoding SPS %d\n", res)); + } + + } + + count = gf_list_count(cfg->pictureParameterSets); + for (i=0; ipictureParameterSets, i); + /*same remark as above*/ + + + res = rvc_decode(slc->data, slc->size, &Picture, 1); + if (res<0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[SVC Decoder] Error decoding PPS %d\n", res)); + } + + } + + gf_odf_avc_cfg_del(cfg); + } else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) { + GF_M4VDecSpecInfo dsi; + GF_Err e; + /*decode DSI*/ + e = gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi); + if (e) return e; + if (!dsi.width || !dsi.height) return GF_NON_COMPLIANT_BITSTREAM; + ctx->width = dsi.width; + ctx->height = dsi.height; + ctx->pixel_ar = (dsi.par_num<<16) | dsi.par_den; + + + res = rvc_decode(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &Picture, 1); + if (res<0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[SVC Decoder] Error decoding PPS %d\n", res)); + } + + + } else { + /*unknown type, do what you want*/ + + res = rvc_decode(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &Picture, 1); + if (res<0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[SVC Decoder] Error decoding PPS %d\n", res)); + } + + } + /*adjust stride to what you decoder uses*/ + ctx->stride = ctx->width; + /*precompute output buffer size*/ + ctx->out_size = ctx->stride * ctx->height * 3 / 2; + return GF_OK; +} +static GF_Err RVCD_DetachStream(GF_BaseDecoder *ifcg, u16 ES_ID) +{ + RVCDec *ctx = (RVCDec*) ifcg->privateStack; + + //close RVC decoder + rvc_close(); + ctx->codec = NULL; + ctx->width = ctx->height = ctx->out_size = 0; + return GF_OK; +} +static GF_Err RVCD_GetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability *capability) +{ + RVCDec *ctx = (RVCDec*) ifcg->privateStack; + + switch (capability->CapCode) { + case GF_CODEC_RESILIENT: + capability->cap.valueInt = 1; + break; + case GF_CODEC_WIDTH: + capability->cap.valueInt = ctx->width; + break; + case GF_CODEC_HEIGHT: + capability->cap.valueInt = ctx->height; + break; + case GF_CODEC_STRIDE: + capability->cap.valueInt = ctx->stride; + break; + case GF_CODEC_PAR: + capability->cap.valueInt = ctx->pixel_ar; + break; + case GF_CODEC_OUTPUT_SIZE: + capability->cap.valueInt = ctx->out_size; + break; + case GF_CODEC_PIXEL_FORMAT: + capability->cap.valueInt = GF_PIXEL_YV12; + break; + case GF_CODEC_BUFFER_MIN: + capability->cap.valueInt = 1; + break; + case GF_CODEC_BUFFER_MAX: + capability->cap.valueInt = 2; + break; + case GF_CODEC_PADDING_BYTES: + capability->cap.valueInt = 32; + break; + case GF_CODEC_REORDER: + capability->cap.valueInt = 1; + break; + /*not known at our level...*/ + case GF_CODEC_CU_DURATION: + default: + capability->cap.valueInt = 0; + break; + } + return GF_OK; +} +static GF_Err RVCD_SetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability capability) +{ + return GF_NOT_SUPPORTED; +} + + +int bookmark = 0; + +static GF_Err RVCD_ProcessData(GF_MediaDecoder *ifcg, + char *inBuffer, u32 inBufferLength, + u16 ES_ID, + char *outBuffer, u32 *outBufferLength, + u8 PaddingBits, u32 mmlevel) +{ + s32 got_pic; + RVCDec *ctx = (RVCDec*) ifcg->privateStack; + + if (!ES_ID || (ES_ID!=ctx->ES_ID) /*|| !ctx->codec*/) { + *outBufferLength = 0; + return GF_OK; + } + if (*outBufferLength < ctx->out_size) { + *outBufferLength = ctx->out_size; + return GF_BUFFER_TOO_SMALL; + } + + //if your decoder outputs directly in the memory passed, setup pointers for your decoder output picture + + got_pic = 0; + + if (ctx->nalu_size_length) { + u32 i, nalu_size = 0; + u8 *ptr = inBuffer; + int nalNumber = 1; + + while (inBufferLength) { + for (i=0; inalu_size_length; i++) { + nalu_size = (nalu_size<<8) + ptr[i]; + } + ptr += ctx->nalu_size_length; + + //same remark as above regardin start codes + + if(nalNumber > bookmark){ + got_pic = rvc_decode(ptr, nalu_size, outBuffer, !got_pic); + bookmark ++; + if(got_pic>1){ + return GF_PACKED_FRAMES; + } + }else if(nalNumber == bookmark){ + got_pic = rvc_decode(NULL, 0, outBuffer, !got_pic); + if(got_pic>1){ + return GF_PACKED_FRAMES; + } + } + nalNumber ++; + + ptr += nalu_size; + if (inBufferLength < nalu_size + ctx->nalu_size_length) + break; + + inBufferLength -= nalu_size + ctx->nalu_size_length; + } + bookmark = 0; + + } else { + u32 nalu_size = 0; + u8 *ptr = inBuffer; + + + got_pic = rvc_decode(ptr, inBufferLength, outBuffer, 1); + } + + //if (got_pic!=1) return GF_OK; + + /*if size changed during the decoding, resize the composition buffer*/ + /*if ((pic.Width != ctx->width) || (pic.Height!=ctx->height)) + { + ctx->width = pic.Width; + ctx->stride = pic.Width; + ctx->height = pic.Height; + ctx->out_size = ctx->stride * ctx->height * 3 / 2; + *outBufferLength = ctx->out_size; + return GF_BUFFER_TOO_SMALL; + } + + *outBufferLength = ctx->out_size;*/ + + /*if your decoder does not output directly in the memory passed, copy over the data*/ + + /*memcpy(outBuffer, pic.pY[0], ctx->stride*ctx->height); + memcpy(outBuffer + ctx->stride * ctx->height, pic.pU[0], ctx->stride*ctx->height/4); + memcpy(outBuffer + 5*ctx->stride * ctx->height/4, pic.pV[0], ctx->stride*ctx->height/4);*/ + + if(got_pic>1) return GF_PACKED_FRAMES; + return GF_OK; +} + +static u32 RVCD_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, u8 PL) +{ + if (StreamType != GF_STREAM_VISUAL) return GF_CODEC_NOT_SUPPORTED; + /*media type query*/ + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; + switch (esd->decoderConfig->objectTypeIndication) { + case GPAC_OTI_VIDEO_AVC: + case GPAC_OTI_VIDEO_MPEG4_PART2: + if (!esd->decoderConfig->rvc_config && !esd->decoderConfig->predefined_rvc_config) return GF_CODEC_NOT_SUPPORTED; + return GF_CODEC_SUPPORTED+1; + } + return GF_CODEC_NOT_SUPPORTED; +} + +static const char *RVCD_GetCodecName(GF_BaseDecoder *dec) +{ + return "RVC Decoder"; +} + +GF_BaseDecoder *NewRVCDec() +{ + GF_MediaDecoder *ifcd; + RVCDec *dec; + + GF_SAFEALLOC(ifcd, GF_MediaDecoder); + GF_SAFEALLOC(dec, RVCDec); + GF_REGISTER_MODULE_INTERFACE(ifcd, GF_MEDIA_DECODER_INTERFACE, "RVC Decoder", "gpac distribution") + + ifcd->privateStack = dec; + + /*setup our own interface*/ + ifcd->AttachStream = RVCD_AttachStream; + ifcd->DetachStream = RVCD_DetachStream; + ifcd->GetCapabilities = RVCD_GetCapabilities; + ifcd->SetCapabilities = RVCD_SetCapabilities; + ifcd->GetName = RVCD_GetCodecName; + ifcd->CanHandleStream = RVCD_CanHandleStream; + ifcd->ProcessData = RVCD_ProcessData; + return (GF_BaseDecoder *) ifcd; +} + +void DeleteRVCDec(GF_BaseDecoder *ifcg) +{ + RVCDec *ctx = (RVCDec*) ifcg->privateStack; + gf_free(ctx); + gf_free(ifcg); +} + +const u32 *QueryInterfaces() +{ + static u32 si [] = { +#ifndef GPAC_DISABLE_AV_PARSERS + GF_MEDIA_DECODER_INTERFACE, +#endif + 0 + }; + return si; +} + +GF_BaseInterface *LoadInterface(u32 InterfaceType) +{ +#ifndef GPAC_DISABLE_AV_PARSERS + if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return (GF_BaseInterface *)NewRVCDec(); +#endif + return NULL; +} + +void ShutdownInterface(GF_BaseInterface *ifce) +{ + switch (ifce->InterfaceType) { +#ifndef GPAC_DISABLE_AV_PARSERS + case GF_MEDIA_DECODER_INTERFACE: + DeleteRVCDec((GF_BaseDecoder*)ifce); + break; +#endif + } +} diff --git a/modules/saf_in/Makefile b/modules/saf_in/Makefile index 30e2f75..a3ed689 100644 --- a/modules/saf_in/Makefile +++ b/modules/saf_in/Makefile @@ -32,7 +32,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_dummy_in-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_dummy_in-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static endif diff --git a/modules/sdl_out/sdl_out.h b/modules/sdl_out/sdl_out.h index 85c687a..4fa2e94 100644 --- a/modules/sdl_out/sdl_out.h +++ b/modules/sdl_out/sdl_out.h @@ -42,11 +42,18 @@ void SDLOUT_CloseSDL(); #define SDL_WINDOW_THREAD #endif +typedef enum { + SDL_STATE_STOPPED = 0, + SDL_STATE_RUNNING, + SDL_STATE_STOP_REQ, + SDL_STATE_WAIT_FOR_THREAD_TERMINATION +} GF_SDL_STATE; + typedef struct { #ifdef SDL_WINDOW_THREAD GF_Thread *sdl_th; - u32 sdl_th_state; + GF_SDL_STATE sdl_th_state; #endif GF_Mutex *evt_mx; Bool is_init, fullscreen; diff --git a/modules/sdl_out/video.c b/modules/sdl_out/video.c index 0429009..0d4da20 100644 --- a/modules/sdl_out/video.c +++ b/modules/sdl_out/video.c @@ -604,13 +604,16 @@ Bool SDLVid_ProcessMessageQueue(SDLVidCtx *ctx, GF_VideoOutput *dr) sdl_translate_key(sdl_evt.key.keysym.sym, &gpac_evt.key); gpac_evt.type = (sdl_evt.key.type==SDL_KEYDOWN) ? GF_EVENT_KEYDOWN : GF_EVENT_KEYUP; dr->on_event(dr->evt_cbk_hdl, &gpac_evt); -#ifndef SDL_TEXTINPUTEVENT_TEXT_SIZE - if ((sdl_evt.key.type==SDL_KEYDOWN) && sdl_evt.key.keysym.unicode) { + if ((sdl_evt.key.type==SDL_KEYDOWN) + && sdl_evt.key.keysym.unicode +#ifdef SDL_TEXTINPUTEVENT_TEXT_SIZE + && ((sdl_evt.key.keysym.unicode=='\r') || (sdl_evt.key.keysym.unicode=='\n') || (sdl_evt.key.keysym.unicode=='\b') || (sdl_evt.key.keysym.unicode=='\t') ) +#endif + ) { gpac_evt.character.unicode_char = sdl_evt.key.keysym.unicode; gpac_evt.type = GF_EVENT_TEXTINPUT; dr->on_event(dr->evt_cbk_hdl, &gpac_evt); } -#endif /* SDL_TEXTINPUTEVENT_TEXT_SIZE */ break; /*mouse*/ @@ -668,11 +671,11 @@ u32 SDLVid_EventProc(void *par) SDLVID(); if (!SDLVid_InitializeWindow(ctx, dr)) { - ctx->sdl_th_state = 3; + ctx->sdl_th_state = SDL_STATE_STOP_REQ; } - ctx->sdl_th_state = 1; - while (ctx->sdl_th_state==1) { + ctx->sdl_th_state = SDL_STATE_RUNNING; + while (ctx->sdl_th_state==SDL_STATE_RUNNING) { /*after much testing: we must ensure nothing is using the event queue when resizing window. -- under X, it throws Xlib "unexpected async reply" under linux, therefore we don't wait events, we check for events and execute them if any @@ -700,13 +703,20 @@ u32 SDLVid_EventProc(void *par) #endif /*QUIT message has been processed*/ - if (!ret) break; + if (!ret) { + ctx->sdl_th_state = SDL_STATE_STOP_REQ; + break; + } - gf_sleep(0); + gf_sleep(2); } + while (ctx->sdl_th_state == SDL_STATE_STOP_REQ) + gf_sleep(10); + SDLVid_ShutdownWindow(ctx); - ctx->sdl_th_state = 3; + ctx->sdl_th_state = SDL_STATE_STOPPED; + return 0; } #endif /*SDL_WINDOW_THREAD*/ @@ -726,12 +736,15 @@ GF_Err SDLVid_Setup(struct _video_out *dr, void *os_handle, void *os_display, u3 if (!SDLOUT_InitSDL()) return GF_IO_ERR; #ifdef SDL_WINDOW_THREAD - ctx->sdl_th_state = 0; + ctx->sdl_th_state = SDL_STATE_STOPPED; gf_th_run(ctx->sdl_th, SDLVid_EventProc, dr); - while (!ctx->sdl_th_state) gf_sleep(10); - if (ctx->sdl_th_state==3) { + + while (!ctx->sdl_th_state) + gf_sleep(10); + + if (ctx->sdl_th_state==SDL_STATE_STOP_REQ) { SDLOUT_CloseSDL(); - ctx->sdl_th_state = 0; + ctx->sdl_th_state = SDL_STATE_STOPPED; return GF_IO_ERR; } #else @@ -752,13 +765,16 @@ static void SDLVid_Shutdown(GF_VideoOutput *dr) if (!ctx->is_init) return; #ifdef SDL_WINDOW_THREAD - if (ctx->sdl_th_state==1) { + if (ctx->sdl_th_state==SDL_STATE_RUNNING) { SDL_Event evt; - ctx->sdl_th_state = 2; evt.type = SDL_QUIT; SDL_PushEvent(&evt); - while (ctx->sdl_th_state != 3) gf_sleep(100); } + /*wait until thread say it is stopped*/ + ctx->sdl_th_state = SDL_STATE_WAIT_FOR_THREAD_TERMINATION; + while (ctx->sdl_th_state != SDL_STATE_STOPPED) + gf_sleep(10); + #else SDLVid_ShutdownWindow(ctx); #endif @@ -885,26 +901,6 @@ u32 SDLVid_MapPixelFormat(SDL_PixelFormat *format, Bool force_alpha) } } -#ifdef UNUSED_FUNC -static char szTYPE[5]; -static const char *my_gf_4cc_to_str(u32 type) -{ - u32 ch, i; - char *ptr, *name = (char *)szTYPE; - ptr = name; - for (i = 0; i < 4; i++, name++) { - ch = type >> (8 * (3-i) ) & 0xff; - if ( ch >= 0x20 && ch <= 0x7E ) { - *name = ch; - } else { - *name = '.'; - } - } - *name = 0; - return (const char *) ptr; -} -#endif /* UNUSED_FUNC */ - static GF_Err SDLVid_LockBackBuffer(GF_VideoOutput *dr, GF_VideoSurface *video_info, u32 do_lock) { SDLVID(); @@ -1017,6 +1013,13 @@ static GF_Err SDLVid_ProcessEvent(GF_VideoOutput *dr, GF_Event *evt) SDLVid_SetCursor(dr, evt->cursor.cursor_type); break; case GF_EVENT_SET_CAPTION: +#ifdef SDL_WINDOW_THREAD + { + SDLVID(); + if (ctx->sdl_th_state != SDL_STATE_RUNNING) + break; + } +#endif SDL_WM_SetCaption(evt->caption.caption, NULL); break; case GF_EVENT_SHOWHIDE: @@ -1026,6 +1029,8 @@ static GF_Err SDLVid_ProcessEvent(GF_VideoOutput *dr, GF_Event *evt) case GF_EVENT_SIZE: SDLVid_ResizeWindow(dr, evt->size.width, evt->size.height); break; + case GF_EVENT_MOVE: + break; case GF_EVENT_VIDEO_SETUP: { SDLVID(); diff --git a/modules/soft_raster/Makefile b/modules/soft_raster/Makefile index 34114d0..740dad0 100644 --- a/modules/soft_raster/Makefile +++ b/modules/soft_raster/Makefile @@ -37,7 +37,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_soft_raster-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_soft_raster-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static endif diff --git a/modules/soft_raster/raster_argb.c b/modules/soft_raster/raster_argb.c index 0e260e3..a0b37e3 100644 --- a/modules/soft_raster/raster_argb.c +++ b/modules/soft_raster/raster_argb.c @@ -503,7 +503,7 @@ GF_Err evg_surface_clear_rgbx(GF_SURFACE surf, GF_IRect rc, GF_Color col) b = GF_COL_B(col); col = GF_COL_ARGB(0xFF, b, g, r); for (y = 0; y < h; y++) { - u32 *data = (u32 *) (_this ->pixels + (y + sy) * _this->pitch_y + st*sx); + u8 *data = _this ->pixels + (y + sy) * _this->pitch_y + st*sx; for (x = 0; x < w; x++) { data[0] = r; data[1] = g; @@ -696,7 +696,7 @@ GF_Err evg_surface_clear_rgba(GF_SURFACE surf, GF_IRect rc, GF_Color col) if (!use_memset) { for (y = 0; y < h; y++) { - data = (_this ->pixels + (sy+y)* st + _this->pitch_x * rc.x); + data = _this ->pixels + (sy+y)* st + _this->pitch_x * rc.x; for (x = 0; x < w; x++) { *(data) = r; *(data+1) = g; diff --git a/modules/svg_in/Makefile b/modules/svg_in/Makefile index 4181eb8..f5cccdd 100644 --- a/modules/svg_in/Makefile +++ b/modules/svg_in/Makefile @@ -36,7 +36,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac -lz ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_svg_in-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static -lz + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_svg_in-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static -lz endif diff --git a/modules/svg_in/svg_in.c b/modules/svg_in/svg_in.c index 83518ee..cfa5c3b 100644 --- a/modules/svg_in/svg_in.c +++ b/modules/svg_in/svg_in.c @@ -337,25 +337,28 @@ const char *SVG_GetName(struct _basedecoder *plug) return "INTERNAL ERROR"; } -Bool SVG_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, GF_ESD *esd, u8 PL) +static u32 SVG_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, GF_ESD *esd, u8 PL) { - /*don't reply to media type query*/ - if (!esd) return 0; - if (StreamType==GF_STREAM_PRIVATE_SCENE) { - if (esd->decoderConfig->objectTypeIndication == GPAC_OTI_PRIVATE_SCENE_SVG) return 1; - return 0; + /*media type query*/ + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; + + if (esd->decoderConfig->objectTypeIndication == GPAC_OTI_PRIVATE_SCENE_SVG) return GF_CODEC_SUPPORTED; + return GF_CODEC_NOT_SUPPORTED; } else if (StreamType==GF_STREAM_SCENE) { + /*media type query*/ + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; + switch (esd->decoderConfig->objectTypeIndication) { case GPAC_OTI_SCENE_SVG: case GPAC_OTI_SCENE_SVG_GZ: case GPAC_OTI_SCENE_DIMS: - return 1; + return GF_CODEC_SUPPORTED; default: - return 0; + return GF_CODEC_NOT_SUPPORTED; } } - return 0; + return GF_CODEC_NOT_SUPPORTED; } static GF_Err SVG_GetCapabilities(GF_BaseDecoder *plug, GF_CodecCapability *cap) diff --git a/modules/timedtext/Makefile b/modules/timedtext/Makefile index 4af8310..67c30a2 100644 --- a/modules/timedtext/Makefile +++ b/modules/timedtext/Makefile @@ -31,7 +31,7 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_timedtext-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_timedtext-static.$(DYN_LIB_SUFFIX) $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static endif diff --git a/modules/timedtext/timedtext_dec.c b/modules/timedtext/timedtext_dec.c index 90f87a4..26c0836 100644 --- a/modules/timedtext/timedtext_dec.c +++ b/modules/timedtext/timedtext_dec.c @@ -70,7 +70,7 @@ typedef struct { GF_Scene *inlineScene; GF_Terminal *app; - u32 PL, nb_streams; + u32 nb_streams; GF_TextConfig *cfg; @@ -1094,17 +1094,16 @@ static GF_Err TTD_ProcessData(GF_SceneDecoder*plug, const char *inBuffer, u32 in return e; } -Bool TTD_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, GF_ESD *esd, u8 PL) +static u32 TTD_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, GF_ESD *esd, u8 PL) { - TTDPriv *priv = (TTDPriv *)ifce->privateStack; - if (StreamType!=GF_STREAM_TEXT) return 0; + /*TTDPriv *priv = (TTDPriv *)ifce->privateStack;*/ + if (StreamType!=GF_STREAM_TEXT) return GF_CODEC_NOT_SUPPORTED; /*media type query*/ - if (!esd) return 1; - if (esd->decoderConfig->objectTypeIndication==0x08) { - priv->PL = PL; - return 1; - } - return 0; + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; + + if (esd->decoderConfig->objectTypeIndication==0x08) return GF_CODEC_SUPPORTED; + + return GF_CODEC_NOT_SUPPORTED; } diff --git a/modules/widgetman/unzip.h b/modules/widgetman/unzip.h index 0dceeb0..a4c1b9b 100644 --- a/modules/widgetman/unzip.h +++ b/modules/widgetman/unzip.h @@ -114,10 +114,10 @@ typedef voidp unzFile; #endif #ifndef ALLOC -# define ALLOC(size) (malloc(size)) +# define ALLOC(size) (gf_malloc(size)) #endif #ifndef TRYFREE -# define TRYFREE(p) {if (p) free(p);} +# define TRYFREE(p) {if (p) gf_free(p);} #endif #define SIZECENTRALDIRITEM (0x2e) diff --git a/modules/widgetman/wgt_load.c b/modules/widgetman/wgt_load.c index 1d34134..bf2063c 100644 --- a/modules/widgetman/wgt_load.c +++ b/modules/widgetman/wgt_load.c @@ -228,16 +228,16 @@ const char *WGT_GetName(struct _basedecoder *plug) return "GPAC W3C Widget Loader"; } -Bool WGT_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, GF_ESD *esd, u8 PL) +static u32 WGT_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, GF_ESD *esd, u8 PL) { /*don't reply to media type query*/ - if (!esd) return 0; + if (!esd) return GF_CODEC_NOT_SUPPORTED; if (StreamType==GF_STREAM_PRIVATE_SCENE) { - if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_PRIVATE_SCENE_WGT) return 1; - return 0; + if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_PRIVATE_SCENE_WGT) return GF_CODEC_SUPPORTED; + return GF_CODEC_NOT_SUPPORTED; } - return 0; + return GF_CODEC_NOT_SUPPORTED; } static GF_Err WGT_GetCapabilities(GF_BaseDecoder *plug, GF_CodecCapability *cap) diff --git a/modules/widgetman/widgetman.c b/modules/widgetman/widgetman.c index 65ec3a7..434b6e6 100644 --- a/modules/widgetman/widgetman.c +++ b/modules/widgetman/widgetman.c @@ -247,7 +247,7 @@ static GF_WidgetPackage *widget_isom_new(GF_WidgetManager *wm, const char *path) dir = gf_cfg_get_key(wm->term->user->config, "General", "CacheDirectory"); /* create the extracted path for the package root using: the cache dir + a CRC of the file path and the instance*/ - sprintf(wzip->root_extracted_path, "%s%08X", path, (u32) wzip); + sprintf(wzip->root_extracted_path, "%s%08X", path, (unsigned int)((unsigned long) wzip)); i = gf_crc_32((char *)wzip->root_extracted_path, strlen(wzip->root_extracted_path)); sprintf(wzip->archive_id, "GWM_%08X_", i); sprintf(wzip->root_extracted_path, "%s/%s", dir, wzip->archive_id); @@ -326,7 +326,7 @@ static GF_WidgetPackage *widget_zip_new(GF_WidgetManager *wm, const char *path) dir = gf_cfg_get_key(wm->term->user->config, "General", "CacheDirectory"); /* create the extracted path for the package root using: the cache dir + a CRC of the file path and the instance*/ - sprintf(wzip->root_extracted_path, "%s%08X", path, (u32) wzip); + sprintf(wzip->root_extracted_path, "%s%08X", path, (unsigned int)((unsigned long) wzip)); i = gf_crc_32((char *)wzip->root_extracted_path, strlen(wzip->root_extracted_path)); sprintf(wzip->archive_id, "GWM_%08X_", i); sprintf(wzip->root_extracted_path, "%s/%s", dir, wzip->archive_id); diff --git a/modules/x11_out/Makefile b/modules/x11_out/Makefile index c263e37..7c111ce 100644 --- a/modules/x11_out/Makefile +++ b/modules/x11_out/Makefile @@ -66,11 +66,11 @@ all: $(LIB) $(LIB): $(OBJS) $(CC) $(SHFLAGS) $(LDFLAGS) -lX11 -L../../bin/gcc -lgpac -o ../../bin/gcc/$@ $(OBJS) ifeq ($(STATICBUILD),yes) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_x11_out-static.so $(OBJS) -lX11 -L../../bin/gcc -lgpac_static + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_x11_out-static.$(DYN_LIB_SUFFIX) $(OBJS) -lX11 -L../../bin/gcc -lgpac_static endif #static-bin: -# $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_x11_out-static.so $(OBJS) -lX11 -L../../bin/gcc -lgpac_static +# $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_x11_out-static.$(DYN_LIB_SUFFIX) $(OBJS) -lX11 -L../../bin/gcc -lgpac_static %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< diff --git a/modules/x11_out/x11_out.c b/modules/x11_out/x11_out.c index 7d0a6a2..a254662 100644 --- a/modules/x11_out/x11_out.c +++ b/modules/x11_out/x11_out.c @@ -25,6 +25,7 @@ #include "x11_out.h" #include +#include #include #include #include @@ -578,9 +579,10 @@ static void X11_HandleEvents(GF_VideoOutput *vout) vout->on_event (vout->evt_cbk_hdl, &evt); if (xevent.type ==KeyPress) { - XLookupString (&xevent.xkey, (char *) keybuf, sizeof(keybuf), NULL, &state); - if (keybuf[0]) { - evt.character.unicode_char = keybuf[0]; + s32 len; + len = XLookupString (&xevent.xkey, (char *) keybuf, sizeof(keybuf), NULL, &state); + if ((len>0) && (len<5)) { + utf8_to_ucs4 (& evt.character.unicode_char, len, keybuf); evt.type = GF_EVENT_TEXTINPUT; vout->on_event (vout->evt_cbk_hdl, &evt); } diff --git a/modules/xvid_dec/xvid_dec.c b/modules/xvid_dec/xvid_dec.c index 44048e5..d470670 100644 --- a/modules/xvid_dec/xvid_dec.c +++ b/modules/xvid_dec/xvid_dec.c @@ -366,14 +366,17 @@ static GF_Err XVID_ProcessData(GF_MediaDecoder *ifcg, return GF_OK; } -static Bool XVID_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, u8 PL) +static u32 XVID_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, u8 PL) { - if (StreamType != GF_STREAM_VISUAL) return 0; + if (StreamType != GF_STREAM_VISUAL) return GF_CODEC_NOT_SUPPORTED; /*media type query*/ - if (!esd) return 1; + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; - if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) return 1; - return 0; + if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) { + if (esd->decoderConfig->rvc_config || esd->decoderConfig->predefined_rvc_config) return GF_CODEC_MAYBE_SUPPORTED; + return GF_CODEC_SUPPORTED; + } + return GF_CODEC_NOT_SUPPORTED; } static const char *XVID_GetCodecName(GF_BaseDecoder *dec) diff --git a/modules/xvid_dec/xvid_dec_wce.cpp b/modules/xvid_dec/xvid_dec_wce.cpp index 3fcdc0f..acc86e7 100644 --- a/modules/xvid_dec/xvid_dec_wce.cpp +++ b/modules/xvid_dec/xvid_dec_wce.cpp @@ -216,13 +216,13 @@ static const char *XVID_GetCodecName(GF_BaseDecoder *dec) return "XviD 1.0 for WinCE"; } -static Bool XVID_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, u8 PL) +static u32 XVID_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, GF_ESD *esd, u8 PL) { - if (StreamType != GF_STREAM_VISUAL) return 0; + if (StreamType != GF_STREAM_VISUAL) return GF_CODEC_NOT_SUPPORTED; /*media type query*/ - if (!esd) return 1; - if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) return 1; - return 0; + if (!esd) return GF_CODEC_STREAM_TYPE_SUPPORTED; + if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) return GF_CODEC_STREAM_TYPE_SUPPORTED; + return GF_CODEC_NOT_SUPPORTED; } diff --git a/regression_tests/bifs/bifs-cachetexture_nocache.bt b/regression_tests/bifs/bifs-cachetexture_nocache.bt index 590a4ee..37e0990 100644 --- a/regression_tests/bifs/bifs-cachetexture_nocache.bt +++ b/regression_tests/bifs/bifs-cachetexture_nocache.bt @@ -38,7 +38,7 @@ OrderedGroup { appearance Appearance { texture CacheTexture { objectTypeIndication 108 - image "sky.jpg" + image "../auxiliary_files/sky.jpg" } } geometry Rectangle { diff --git a/src/Makefile b/src/Makefile index 7fefc5d..248abcb 100644 --- a/src/Makefile +++ b/src/Makefile @@ -15,7 +15,7 @@ LDFLAGS+=-pg endif ## libgpac objects gathering: src/utils -LIBGPAC_UTILS=utils/os_divers.o utils/os_net.o utils/os_module.o utils/os_thread.o utils/list.o utils/base_encoding.o utils/bitstream.o utils/color.o utils/configfile.o utils/cache.o utils/downloader.o utils/error.o utils/math.o utils/path2d.o utils/path2d_stroker.o utils/module.o utils/token.o utils/uni_bidi.o utils/url.o utils/utf.o utils/xml_parser.o utils/alloc.o utils/ringbuffer.o utils/unicode.o +LIBGPAC_UTILS=utils/os_divers.o utils/os_net.o utils/os_module.o utils/os_thread.o utils/os_config_init.o utils/list.o utils/base_encoding.o utils/bitstream.o utils/color.o utils/configfile.o utils/cache.o utils/downloader.o utils/error.o utils/math.o utils/path2d.o utils/path2d_stroker.o utils/module.o utils/token.o utils/uni_bidi.o utils/url.o utils/utf.o utils/xml_parser.o utils/alloc.o utils/ringbuffer.o utils/unicode.o ## libgpac objects gathering: src/ietf LIBGPAC_IETF=ietf/rtcp.o ietf/rtp.o ietf/rtp_packetizer.o ietf/rtp_pck_3gpp.o ietf/rtp_pck_mpeg12.o ietf/rtp_pck_mpeg4.o ietf/rtsp_command.o ietf/rtsp_common.o ietf/rtsp_response.o ietf/rtsp_session.o ietf/sdp.o ietf/rtp_depacketizer.o ietf/rtp_streamer.o @@ -36,7 +36,7 @@ LIBGPAC_SCENE=scenegraph/base_scenegraph.o scenegraph/mpeg4_animators.o scenegra LIBGPAC_MCRYPT=mcrypt/cbc.o mcrypt/cfb.o mcrypt/ctr.o mcrypt/des.o mcrypt/ecb.o mcrypt/g_crypt.o mcrypt/ncfb.o mcrypt/nofb.o mcrypt/ofb.o mcrypt/rijndael-128.o mcrypt/rijndael-192.o mcrypt/rijndael-256.o mcrypt/stream.o mcrypt/tripledes.o mcrypt/sha1.o ## libgpac objects gathering: src/media tools -LIBGPAC_MEDIATOOLS=media_tools/av_parsers.o media_tools/avilib.o media_tools/filestreamer.o media_tools/gpac_ogg.o media_tools/img.o media_tools/ismacryp.o media_tools/isom_hinter.o media_tools/isom_tools.o media_tools/media_export.o media_tools/media_import.o media_tools/mpeg2_ps.o media_tools/text_import.o media_tools/saf.o media_tools/mpegts.o media_tools/dvb_mpe.o media_tools/reedsolomon.o media_tools/vobsub.o media_tools/m2ts_mux.o media_tools/m3u8.o media_tools/mpd.o +LIBGPAC_MEDIATOOLS=media_tools/av_parsers.o media_tools/avilib.o media_tools/dvb.o media_tools/filestreamer.o media_tools/gpac_ogg.o media_tools/img.o media_tools/ismacryp.o media_tools/isom_hinter.o media_tools/isom_tools.o media_tools/media_export.o media_tools/media_import.o media_tools/mpeg2_ps.o media_tools/text_import.o media_tools/saf.o media_tools/mpegts.o media_tools/dvb_mpe.o media_tools/reedsolomon.o media_tools/vobsub.o media_tools/m2ts_mux.o media_tools/m3u8.o media_tools/mpd.o media_tools/carousel.o ## libgpac objects gathering: src/scene_manager LIBGPAC_SCENEMANAGER=scene_manager/loader_bt.o scene_manager/loader_isom.o scene_manager/loader_qt.o scene_manager/loader_xmt.o scene_manager/scene_dump.o scene_manager/scene_manager.o scene_manager/scene_stats.o scene_manager/swf_parse.o scene_manager/swf_bifs.o scene_manager/text_to_bifs.o scene_manager/scene_engine.o scene_manager/encode_isom.o scene_manager/loader_svg.o @@ -157,7 +157,6 @@ MEDIATOOLS_CFLAGS+=-DGPAC_ENST_PRIVATE endif - ##libgpac library output LIB=libgpac.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) diff --git a/src/bifs/bifs_node_tables.c b/src/bifs/bifs_node_tables.c index 709f524..0c9829f 100644 --- a/src/bifs/bifs_node_tables.c +++ b/src/bifs/bifs_node_tables.c @@ -24,7 +24,7 @@ /* - DO NOT MOFIFY - File generated on GMT Mon Jan 18 12:27:12 2010 + DO NOT MOFIFY - File generated on GMT Wed Jul 20 05:50:21 2011 BY MPEG4Gen for GPAC Version 0.4.6-DEV */ diff --git a/src/bifs/com_dec.c b/src/bifs/com_dec.c index cdb8ca3..3a9044d 100644 --- a/src/bifs/com_dec.c +++ b/src/bifs/com_dec.c @@ -395,7 +395,7 @@ static GF_Err BD_DecNodeDeleteEx(GF_BifsDecoder * codec, GF_BitStream *bs) return gf_node_replace(node, NULL, 1); } -#ifdef UNUSED_FUNC +#ifdef GPAC_UNUSED_FUNC static GF_Err BD_DecOperandReplace(GF_BifsDecoder * codec, GF_BitStream *bs) { s32 pos; @@ -499,7 +499,7 @@ static GF_Err BD_DecOperandReplace(GF_BifsDecoder * codec, GF_BitStream *bs) gf_sg_vrml_field_copy(dst_ptr, src_ptr, src_type); return GF_OK; } -#endif /* UNUSED_FUNC */ +#endif /*GPAC_UNUSED_FUNC*/ static GF_Err BD_DecExtendedUpdate(GF_BifsDecoder * codec, GF_BitStream *bs) { diff --git a/src/bifs/field_decode.c b/src/bifs/field_decode.c index 87df73c..1653e99 100644 --- a/src/bifs/field_decode.c +++ b/src/bifs/field_decode.c @@ -25,7 +25,6 @@ #include -#include #include "quant.h" #include "script.h" @@ -124,65 +123,10 @@ GF_Err gf_bifs_dec_sf_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *n if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM; if (node && (node->sgprivate->tag==TAG_MPEG4_CacheTexture) && (field->fieldIndex<=2)) { - Bool skip_file_url_proto=0; - char *name; - FILE *f; M_CacheTexture *ct = (M_CacheTexture *) node; - char *buf = gf_malloc(sizeof(char)*length); - gf_bs_read_data(bs, buf, length); - if (ct->cacheURL.buffer) { - name = gf_strdup(ct->cacheURL.buffer); - } else { - char szImg[100], *ext; - switch (ct->objectTypeIndication) { - case GPAC_OTI_IMAGE_JPEG: ext = "jpg"; break; - case GPAC_OTI_IMAGE_PNG: ext = "png"; break; - case GPAC_OTI_IMAGE_JPEG_2000: ext = "jp2"; break; - default: ext = "img"; - } - sprintf(szImg, "%p%p.%s", codec, ct, ext); - name = gf_strdup(szImg); - } - - if (codec->extraction_path) { - char *path; - u32 len = strlen(name)+strlen(codec->extraction_path)+2; - if (strnicmp(codec->extraction_path, "file://", 7)) len+=7; - /*SHA1 of service in hexa*/ - if (codec->service_url) len += 41; - path = gf_malloc(sizeof(char)*len); - - path[0] = 0; - /*force using file:// URL prototype to avoid confusion with resources adressed from the root of the source server*/ - if (strnicmp(codec->extraction_path, "file://", 7)) strcpy(path, "file://"); - strcat(path, codec->extraction_path); - strcat(path, "/"); - - if (codec->service_url) { - u8 hash[20]; - u32 i; - gf_sha1_csum(codec->service_url, strlen(codec->service_url), hash); - for (i=0; i<20; i++) { - char t[3]; - t[2] = 0; - sprintf(t, "%02X", hash[i]); - strcat(path, t); - } - strcat(path, "_"); - } - strcat(path, name); - - gf_free(name); - name = path; - skip_file_url_proto = 1; - } - - ((SFString *)field->far_ptr)->buffer = name; - /*skip the initial file://*/ - f = gf_f64_open(name + (skip_file_url_proto ? 7 : 0), "wb"); - fwrite(buf, 1, length, f); - fclose(f); - gf_free(buf); + ct->data_len = length; + ct->data = gf_malloc(sizeof(char)*length); + gf_bs_read_data(bs, ct->data, length); } else { if ( ((SFString *)field->far_ptr)->buffer ) gf_free( ((SFString *)field->far_ptr)->buffer); ((SFString *)field->far_ptr)->buffer = (char *)gf_malloc(sizeof(char)*(length+1)); diff --git a/src/compositor/audio_input.c b/src/compositor/audio_input.c index 1692cae..3b01a78 100644 --- a/src/compositor/audio_input.c +++ b/src/compositor/audio_input.c @@ -29,8 +29,9 @@ /*diff time in ms to consider an audio frame too early and insert silence*/ #define MIN_RESYNC_TIME 500 -/*diff time in ms to consider an audio frame too late and drop it*/ -#define MAX_RESYNC_TIME 500 +/*diff time in ms to consider an audio frame too late and drop it - we should try to dynamically figure this out +since the drift may be high on TS for example, where PTS-PCR>500ms is quite common*/ +#define MAX_RESYNC_TIME 1000 struct __audiofilteritem { diff --git a/src/compositor/camera.c b/src/compositor/camera.c index 965d8d6..5a4a7ba 100644 --- a/src/compositor/camera.c +++ b/src/compositor/camera.c @@ -166,8 +166,8 @@ SFRotation camera_get_orientation(SFVec3f pos, SFVec3f target, SFVec3f up) return gf_quat_to_rotation(&rot); } -#define FAR_PLANE_2D -60000 -#define NEAR_PLANE_2D 6000 +#define FAR_PLANE_2D -10000 +#define NEAR_PLANE_2D 1000 void camera_set_2d(GF_Camera *cam) { @@ -275,24 +275,26 @@ void camera_update(GF_Camera *cam, GF_Matrix2D *user_transform, Bool center_coor gf_mx_ortho(&cam->projection, -hw, hw, -hh, hh, cam->z_near, cam->z_far); /*setup modelview*/ -#ifdef FORCE_CAMERA_3D - gf_mx_lookat(&cam->modelview, cam->position, cam->target, cam->up); -#else gf_mx_init(cam->modelview); +#ifdef FORCE_CAMERA_3D + if (! (cam->flags & CAM_NO_LOOKAT)) + gf_mx_lookat(&cam->modelview, cam->position, cam->target, cam->up); #endif + if (!center_coords) { gf_mx_add_scale(&post_model_view, 1, -1, 1); gf_mx_add_translation(&post_model_view, -hw, -hh, 0); } if (user_transform) { #ifdef FORCE_CAMERA_3D - GF_Matrix mx; - gf_mx_from_mx2d(&mx, user_transform); - mx.m[10] = mx.m[0]; - gf_mx_add_matrix(&post_model_view, &mx); -#else - gf_mx_add_matrix_2d(&post_model_view, user_transform); + if (! (cam->flags & CAM_NO_LOOKAT)) { + GF_Matrix mx; + gf_mx_from_mx2d(&mx, user_transform); + mx.m[10] = mx.m[0]; + gf_mx_add_matrix(&post_model_view, &mx); + } else #endif + gf_mx_add_matrix_2d(&post_model_view, user_transform); } if (cam->end_zoom != FIX_ONE) gf_mx_add_scale(&post_model_view, cam->end_zoom, cam->end_zoom, cam->end_zoom); if (cam->flags & CAM_HAS_VIEWPORT) gf_mx_add_matrix(&post_model_view, &cam->viewport); @@ -306,6 +308,9 @@ void camera_update(GF_Camera *cam, GF_Matrix2D *user_transform, Bool center_coor gf_bbox_refresh(&b); cam->center = b.center; cam->radius = b.radius; + + if (camera_layout==GF_3D_CAMERA_OFFAXIS) + camera_layout=GF_3D_CAMERA_LINEAR; } if (camera_layout == GF_3D_CAMERA_CIRCULAR) { diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 57e037a..9bed866 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -78,7 +78,7 @@ static void gf_sc_set_fullscreen(GF_Compositor *compositor) GF_LOG(GF_LOG_INFO, GF_LOG_COMPOSE, ("[Compositor] recomputing aspect ratio\n")); compositor->recompute_ar = 1; /*force signaling graphics reset*/ - compositor->reset_graphics = 1; + if (!compositor->reset_graphics) compositor->reset_graphics = 1; } @@ -152,7 +152,7 @@ static void gf_sc_reconfig_task(GF_Compositor *compositor) compositor->recompute_ar = 1; gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); } - compositor->reset_graphics = 1; + if (!compositor->reset_graphics) compositor->reset_graphics = 1; notif_size=1; } @@ -443,7 +443,7 @@ static u32 gf_sc_proc(void *par) else gf_sc_simulation_tick(compositor); } - /*destroy video out here if w're using openGL, to avoid threading issues*/ + /*destroy video out here if we're using openGL, to avoid threading issues*/ compositor->video_out->Shutdown(compositor->video_out); gf_modules_close_interface((GF_BaseInterface *)compositor->video_out); compositor->video_out = NULL; @@ -501,7 +501,7 @@ GF_Compositor *gf_sc_new(GF_User *user, Bool self_threaded, GF_Terminal *term) } /*try to load GL extensions*/ #ifndef GPAC_DISABLE_3D - gf_sc_load_opengl_extensions(tmp); + gf_sc_load_opengl_extensions(tmp, 0); #endif GF_LOG(GF_LOG_DEBUG, GF_LOG_RTI, ("[RTI]\tCompositor Cycle Log\tNetworks\tDecoders\tFrame\tDirect Draw\tVisual Config\tEvent\tRoute\tSMIL Timing\tTime node\tTexture\tSMIL Anim\tTraverse setup\tTraverse (and direct Draw)\tTraverse (and direct Draw) without anim\tIndirect Draw\tTraverse And Draw (Indirect or Not)\tFlush\tCycle\n")); @@ -637,7 +637,7 @@ u32 gf_sc_get_clock(GF_Compositor *compositor) return gf_sc_ar_get_clock(compositor->audio_renderer); } -static GF_Err gf_sc_set_scene_size(GF_Compositor *compositor, u32 Width, u32 Height) +GF_Err gf_sc_set_scene_size(GF_Compositor *compositor, u32 Width, u32 Height, Bool force_size) { if (!Width || !Height) { if (compositor->override_size_flags) { @@ -653,6 +653,7 @@ static GF_Err gf_sc_set_scene_size(GF_Compositor *compositor, u32 Width, u32 Hei compositor->scene_height = Height; compositor->scene_width = Width; } + if (force_size) compositor->has_size_info = 1; return GF_OK; } @@ -899,7 +900,7 @@ GF_Err gf_sc_set_scene(GF_Compositor *compositor, GF_SceneGraph *scene_graph) /*set scene size only if different, otherwise keep scaling/FS*/ if ( !width || (compositor->scene_width!=width) || !height || (compositor->scene_height!=height)) { do_notif = do_notif || compositor->has_size_info || (!compositor->scene_width && !compositor->scene_height); - gf_sc_set_scene_size(compositor, width, height); + gf_sc_set_scene_size(compositor, width, height, 0); /*get actual size in pixels*/ width = compositor->scene_width; @@ -1170,20 +1171,21 @@ void gf_sc_reload_config(GF_Compositor *compositor) sOpt = "100"; gf_cfg_set_key(compositor->user->config, "Compositor", "DepthScale", sOpt); } - compositor->depth_gl_scale = (Float) atof(sOpt); + compositor->depth_gl_scale = FLT2FIX( (Float) atof(sOpt) ); sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "DepthType"); if (!sOpt) { - sOpt = "Strips"; + sOpt = "VertexArray"; gf_cfg_set_key(compositor->user->config, "Compositor", "DepthType", sOpt); } - if (sOpt && !strcmp(sOpt, "Points")) compositor->depth_gl_type = 1; + if (sOpt && !strcmp(sOpt, "Points")) compositor->depth_gl_type = GF_SC_DEPTH_GL_POINTS; else if (sOpt && !strnicmp(sOpt, "Strips", 6)) { - compositor->depth_gl_type = 2; + compositor->depth_gl_type = GF_SC_DEPTH_GL_STRIPS; compositor->depth_gl_strips_filter = 0; - if (strlen(sOpt)>7) compositor->depth_gl_strips_filter = (Float) atof(sOpt+7); + if (strlen(sOpt)>7) compositor->depth_gl_strips_filter = FLT2FIX( (Float) atof(sOpt+7) ); } - else compositor->depth_gl_type = 0; + else if (sOpt && !strcmp(sOpt, "VertexArray")) compositor->depth_gl_type = GF_SC_DEPTH_GL_VBO; + else compositor->depth_gl_type = GF_SC_DEPTH_GL_NONE; sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "NumViews"); if (!sOpt) { @@ -1200,14 +1202,19 @@ void gf_sc_reload_config(GF_Compositor *compositor) } if (!strcmp(sOpt, "SideBySide")) compositor->visual->autostereo_type = GF_3D_STEREO_SIDE; else if (!strcmp(sOpt, "TopToBottom")) compositor->visual->autostereo_type = GF_3D_STEREO_TOP; + else if (!strcmp(sOpt, "Custom")) compositor->visual->autostereo_type = GF_3D_STEREO_CUSTOM; + /*built-in interleavers*/ else if (!strcmp(sOpt, "Anaglyph")) compositor->visual->autostereo_type = GF_3D_STEREO_ANAGLYPH; else if (!strcmp(sOpt, "Columns")) compositor->visual->autostereo_type = GF_3D_STEREO_COLUMNS; else if (!strcmp(sOpt, "Rows")) compositor->visual->autostereo_type = GF_3D_STEREO_ROWS; - else if (!strcmp(sOpt, "Custom")) compositor->visual->autostereo_type = GF_3D_STEREO_CUSTOM; + else if (!strcmp(sOpt, "SPV19")) compositor->visual->autostereo_type = GF_3D_STEREO_5VSP19; + else { compositor->visual->autostereo_type = GF_3D_STEREO_NONE; compositor->visual->nb_views = 1; } + if (compositor->visual->autostereo_type) + compositor->force_opengl_2d = 1; switch (compositor->visual->autostereo_type) { case GF_3D_STEREO_ANAGLYPH: @@ -1232,15 +1239,23 @@ void gf_sc_reload_config(GF_Compositor *compositor) sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "ReverseViews"); if (sOpt && !strcmp(sOpt, "yes")) compositor->visual->reverse_views = 1; -#endif + +#endif //GPAC_DISABLE_3D #ifdef GF_SR_USE_DEPTH sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "AutoStereoCalibration"); - compositor->auto_calibration = (sOpt && !strcmp(sOpt, "yes")) ? 1 : 0; + compositor->auto_calibration = (!sOpt || !strcmp(sOpt, "yes")) ? 1 : 0; sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "DisplayDepth"); compositor->display_depth = sOpt ? (!strcmp(sOpt, "auto") ? -1 : atoi(sOpt)) : 0; +#ifndef GPAC_DISABLE_3D + /*if auto-stereo mode, turn on display depth by default*/ + if (compositor->visual->autostereo_type && !compositor->display_depth) { + compositor->display_depth = -1; + } +#endif + if (!compositor->video_out->view_distance) { sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "ViewDistance"); compositor->video_out->view_distance = FLT2FIX( sOpt ? (Float) atof(sOpt) : 50.0f ); @@ -1574,6 +1589,15 @@ u32 gf_sc_get_option(GF_Compositor *compositor, u32 type) return 0; #endif break; + case GF_OPT_NUM_STEREO_VIEWS: +#ifndef GPAC_DISABLE_3D + if (compositor->visual->type_3d) { + if (compositor->visual->nb_views && compositor->visual->autostereo_type>GF_3D_STEREO_SIDE) + return compositor->visual->nb_views; + } +#endif + return 1; + default: return 0; } } @@ -1606,6 +1630,22 @@ GF_Err gf_sc_get_screen_buffer(GF_Compositor *compositor, GF_VideoSurface *frame return e; } +GF_Err gf_sc_get_offscreen_buffer(GF_Compositor *compositor, GF_VideoSurface *framebuffer, u32 view_idx, u32 depth_dump_mode) +{ + GF_Err e; + if (!compositor || !framebuffer) return GF_BAD_PARAM; +#ifndef GPAC_DISABLE_3D + if (compositor->visual->type_3d && compositor->visual->nb_views && (compositor->visual->autostereo_type>GF_3D_STEREO_SIDE)) { + gf_mx_p(compositor->mx); + e = compositor_3d_get_offscreen_buffer(compositor, framebuffer, view_idx, depth_dump_mode); + if (e != GF_OK) gf_mx_v(compositor->mx); + return e; + } +#endif + return GF_BAD_PARAM; +} + + GF_Err gf_sc_release_screen_buffer(GF_Compositor *compositor, GF_VideoSurface *framebuffer) { GF_Err e; @@ -1805,7 +1845,7 @@ static void gf_sc_recompute_ar(GF_Compositor *compositor, GF_Node *top_node) #ifndef GPAC_DISABLE_3D if (compositor->visual->type_3d) { compositor_3d_set_aspect_ratio(compositor); - gf_sc_load_opengl_extensions(compositor); + gf_sc_load_opengl_extensions(compositor, compositor->visual->type_3d); } else #endif @@ -1847,6 +1887,11 @@ static void gf_sc_draw_scene(GF_Compositor *compositor) if (! visual_draw_frame(compositor->visual, top_node, compositor->traverse_state, 1)) compositor->skip_flush = 1; + + /*if using OpenGL, flush even if no changes as the display may be dirty (as seen on android, likely other devices)*/ +#ifdef GPAC_ANDROID + compositor->skip_flush = 0; +#endif compositor->traverse_state->immediate_draw = flags; @@ -2475,9 +2520,13 @@ static Bool gf_sc_on_event_ex(GF_Compositor *compositor , GF_Event *event, Bool { /*not assigned yet*/ if (!compositor || !compositor->visual) return 0; - /*we're reconfiguring the video output, cancel all messages*/ - if (compositor->msg_type & GF_SR_IN_RECONFIG) return 0; - + /*we're reconfiguring the video output, cancel all messages except GL reconfig (context lost)*/ + if (compositor->msg_type & GF_SR_IN_RECONFIG) { + if (event->type==GF_EVENT_VIDEO_SETUP) { + compositor->reset_graphics = 2; + } + return 0; + } switch (event->type) { case GF_EVENT_MOVE: case GF_EVENT_REFRESH: diff --git a/src/compositor/compositor_2d.c b/src/compositor/compositor_2d.c index 79a5eb5..154dd5c 100644 --- a/src/compositor/compositor_2d.c +++ b/src/compositor/compositor_2d.c @@ -498,6 +498,8 @@ static Bool compositor_2d_draw_bitmap_ex(GF_VisualManager *visual, GF_TextureHan case GF_PIXEL_YV12: case GF_PIXEL_IYUV: case GF_PIXEL_I420: + case GF_PIXEL_YVYU: + case GF_PIXEL_YUY2: case GF_PIXEL_YUVD: if (hw_caps & GF_VIDEO_HW_HAS_YUV) use_soft_stretch = 0; else if (hw_caps & GF_VIDEO_HW_HAS_YUV_OVERLAY) overlay_type = 1; @@ -702,6 +704,8 @@ Bool compositor_2d_draw_bitmap(GF_VisualManager *visual, GF_TraverseState *tr_st case GF_PIXEL_RGBA: case GF_PIXEL_YV12: case GF_PIXEL_IYUV: + case GF_PIXEL_YVYU: + case GF_PIXEL_YUY2: case GF_PIXEL_I420: case GF_PIXEL_YUVA: case GF_PIXEL_RGBS: diff --git a/src/compositor/compositor_3d.c b/src/compositor/compositor_3d.c index b93a7cf..d1c8f27 100644 --- a/src/compositor/compositor_3d.c +++ b/src/compositor/compositor_3d.c @@ -186,24 +186,30 @@ void compositor_3d_draw_bitmap(Drawable *stack, DrawAspect2D *asp, GF_TraverseSt #endif GF_TextureHandler *txh; GF_Compositor *compositor = tr_state->visual->compositor; + Bool use_texture = !compositor->bitmap_use_pixels; - - if (!asp->fill_texture) return; + if (!asp->fill_texture) + return; txh = asp->fill_texture; - if (!txh || !txh->tx_io || !txh->width || !txh->height) return; - - if ((txh->pixelformat==GF_PIXEL_RGBD) || (txh->pixelformat==GF_PIXEL_YUVD)) { - if (txh->data && gf_sc_texture_convert(txh) ) - visual_3d_point_sprite(tr_state->visual, stack, txh, tr_state); + if (!txh || !txh->tx_io || !txh->width || !txh->height) return; - } + + if (((txh->pixelformat==GF_PIXEL_RGBD) || (txh->pixelformat==GF_PIXEL_YUVD))) { + if (compositor->depth_gl_type) { + if (txh->data && gf_sc_texture_convert(txh) ) + visual_3d_point_sprite(tr_state->visual, stack, txh, tr_state); + return; + } else { + use_texture = 1; + } + } alpha = GF_COL_A(asp->fill_color); /*THIS IS A HACK, will not work when setting filled=0, transparency and XLineProps*/ if (!alpha) alpha = GF_COL_A(asp->line_color); /*texture is available in hw, use it - if blending, force using texture*/ - if (!gf_sc_texture_needs_reload(txh) || (alpha != 0xFF) || !compositor->bitmap_use_pixels + if (!gf_sc_texture_needs_reload(txh) || (alpha != 0xFF) || use_texture #ifdef GF_SR_USE_DEPTH || tr_state->depth_offset #endif diff --git a/src/compositor/events.c b/src/compositor/events.c index ab76d54..bb4c25c 100644 --- a/src/compositor/events.c +++ b/src/compositor/events.c @@ -714,8 +714,11 @@ static Bool exec_event_dom(GF_Compositor *compositor, GF_Event *event) evt.button = event->mouse.button; evt.detail = compositor->num_clicks; ret += gf_dom_event_fire_ex(compositor->grab_node, &evt, compositor->hit_use_stack); - -#if !defined(_WIN32_WCE) +/* +TODO quick- fix for iPhone as well +TODO clean: figure out whether we use a mouse or a touch device - if touch device, remove this test +*/ +#if !defined(_WIN32_WCE) || !defined(GPAC_ANDROID) if ((compositor->grab_x == X) && (compositor->grab_y == Y)) #endif { diff --git a/src/compositor/gl_inc.h b/src/compositor/gl_inc.h index 295ac66..d0aa84b 100644 --- a/src/compositor/gl_inc.h +++ b/src/compositor/gl_inc.h @@ -100,7 +100,7 @@ extern proc_ ## funname funname; \ //no extensions with TinyGL #elif defined (GPAC_USE_OGL_ES) //no extensions with OpenGL ES -#elif defined (GPAC_CONFIG_WIN32) +#elif defined(WIN32) || defined (GPAC_CONFIG_WIN32) #define LOAD_GL_FUNCS #define GET_GLFUN(funname) funname = (proc_ ## funname) wglGetProcAddress(#funname) #elif defined(CONFIG_DARWIN_GL) @@ -282,13 +282,15 @@ GLDECL(void, glActiveTexture, (GLenum texture) ) GLDECL(void, glClientActiveTexture, (GLenum texture) ) #define GL_ARRAY_BUFFER 0x8892 +#define GL_STREAM_DRAW 0x88E0 #define GL_STATIC_DRAW 0x88E4 +#define GL_DYNAMIC_DRAW 0x88E8 GLDECL(void, glGenBuffers, (GLsizei , GLuint *) ) GLDECL(void, glDeleteBuffers, (GLsizei , GLuint *) ) GLDECL(void, glBindBuffer, (GLenum, GLuint ) ) GLDECL(void, glBufferData, (GLenum, int, void *, GLenum) ) - +GLDECL(void, glBufferSubData, (GLenum, int, int, void *) ) #endif //GL_VERSION_1_3 diff --git a/src/compositor/hardcoded_protos.c b/src/compositor/hardcoded_protos.c index b188ec6..159b27a 100644 --- a/src/compositor/hardcoded_protos.c +++ b/src/compositor/hardcoded_protos.c @@ -663,7 +663,7 @@ static void TraverseDepthGroup(GF_Node *node, void *rs, Bool is_destroy) gf_mx_copy(mx_bckup, tr_state->model_matrix); gf_mx_init(mx); - mx.m[14] = stack->dg.depth_offset; + mx.m[14] = gf_mulfix(stack->dg.depth_offset, tr_state->visual->compositor->depth_gl_scale); gf_mx_add_matrix(&tr_state->model_matrix, &mx); if (tr_state->traversing_mode == TRAVERSE_SORT) { @@ -889,6 +889,8 @@ static void TraverseUntransform(GF_Node *node, void *rs, Bool is_destroy) GF_Matrix mx_model; GF_Camera backup_cam; + if (!tr_state->camera) return; + gf_mx_copy(mx_model, tr_state->model_matrix); gf_mx_init(tr_state->model_matrix); @@ -897,6 +899,8 @@ static void TraverseUntransform(GF_Node *node, void *rs, Bool is_destroy) camera_invalidate(tr_state->camera); tr_state->camera->is_3D=0; + tr_state->camera->flags |= CAM_NO_LOOKAT; + tr_state->camera->end_zoom = FIX_ONE; camera_update(tr_state->camera, NULL, 1, 0, 0, 0, GF_3D_CAMERA_STRAIGHT); diff --git a/src/compositor/mpeg4_background2d.c b/src/compositor/mpeg4_background2d.c index 2e84fd8..214330c 100644 --- a/src/compositor/mpeg4_background2d.c +++ b/src/compositor/mpeg4_background2d.c @@ -233,11 +233,16 @@ static void DrawBackground2D_3D(M_Background2D *bck, Background2DStack *st, GF_T tr_state->bbox.max_edge.y - tr_state->bbox.min_edge.y, FIX_ONE); /*when in layer2D, DON'T MOVE BACKGROUND TO ZFAR*/ + if (!tr_state->is_layer) { + Fixed tr; #ifdef GPAC_FIXED_POINT - if (!tr_state->is_layer) gf_mx_add_translation(&mx, 0, 0, -(tr_state->camera->z_far/100)*99); + tr = -(tr_state->camera->z_far/100)*99; #else - if (!tr_state->is_layer) gf_mx_add_translation(&mx, 0, 0, -0.999f*tr_state->camera->z_far); + tr = -0.999f*tr_state->camera->z_far; #endif + if (!tr_state->camera->is_3D) tr = -tr; + gf_mx_add_translation(&mx, 0, 0, tr); + } } visual_3d_matrix_add(tr_state->visual, mx.m); visual_3d_mesh_paint(tr_state, st->mesh); diff --git a/src/compositor/mpeg4_composite.c b/src/compositor/mpeg4_composite.c index 2a9af10..0f8b92a 100644 --- a/src/compositor/mpeg4_composite.c +++ b/src/compositor/mpeg4_composite.c @@ -421,6 +421,8 @@ static void composite_update(GF_TextureHandler *txh) st->unsupported = 1; return; } + /*reload openGL ext*/ + gf_sc_load_opengl_extensions(compositor, 1); #endif } } else { @@ -440,7 +442,7 @@ static void composite_update(GF_TextureHandler *txh) #ifdef GPAC_USE_TINYGL if (st->visual->type_3d && !compositor->visual->type_3d) { st->tgl_ctx = ostgl_create_context(txh->width, txh->height, txh->transparent ? 32 : 24, &txh->data, 1); - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[CompositeTexture] Creating TinyGL Offscreen context 0x%08x (%d %d - pf %s)\n", st->tgl_ctx, txh->width, txh->width, gf_4cc_to_str(txh->pixelformat))); + GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[CompositeTexture] Creating TinyGL Offscreen context %p (%d %d - pf %s)\n", st->tgl_ctx, txh->width, txh->width, gf_4cc_to_str(txh->pixelformat))); } #endif diff --git a/src/compositor/mpeg4_grouping.c b/src/compositor/mpeg4_grouping.c index bf05282..88119bd 100644 --- a/src/compositor/mpeg4_grouping.c +++ b/src/compositor/mpeg4_grouping.c @@ -467,6 +467,7 @@ void group_3d_traverse(GF_Node *node, GroupingNode *group, GF_TraverseState *tr_ /*not parent (eg form, layout...) sub-tree not dirty and getting bounds, direct copy */ else if (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) { tr_state->bbox = group->bbox; + if (!tr_state->bbox.is_set) tr_state->bbox.radius=-FIX_ONE; gf_node_dirty_clear(node, 0); return; } diff --git a/src/compositor/mpeg4_grouping_2d.c b/src/compositor/mpeg4_grouping_2d.c index f67f0a7..dfd09e5 100644 --- a/src/compositor/mpeg4_grouping_2d.c +++ b/src/compositor/mpeg4_grouping_2d.c @@ -52,7 +52,6 @@ static void TraverseSwitch(GF_Node *node, void *rs, Bool is_destroy) gf_free(st); return; } - if (gf_node_get_name(node)) { node = node; @@ -97,7 +96,26 @@ static void TraverseSwitch(GF_Node *node, void *rs, Bool is_destroy) tr_state->switched_off = prev_switch; } - if (children && (whichChoice>=0)) { + if (!children) return; + if (whichChoice==-2) { +#ifndef GPAC_DISABLE_3D + if (tr_state->visual->autostereo_type) { + u32 idx; + u32 count = gf_node_list_get_count(children); + /*this should be a bit more subtle (reusing views if missing, ...)...*/ + idx = tr_state->visual->current_view % count; + + child = (GF_Node*)gf_node_list_get_child(children, idx); + gf_node_traverse(child, tr_state); + return; + } else +#endif //GPAC_DISABLE_3D + { + /*fallback to first view*/ + whichChoice=0; + } + } + if (whichChoice>=0) { child = (GF_Node*)gf_node_list_get_child(children, whichChoice); gf_node_traverse(child, tr_state); } @@ -379,6 +397,7 @@ static void TraverseOrderedGroup(GF_Node *node, void *rs, Bool is_destroy) } if (!og->order.count || (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) ) { + gf_node_dirty_clear(node, GF_SG_NODE_DIRTY); group_2d_traverse(node, (GroupingNode2D*)stack, tr_state); return; } diff --git a/src/compositor/mpeg4_layer_3d.c b/src/compositor/mpeg4_layer_3d.c index d4cba7d..23e0041 100644 --- a/src/compositor/mpeg4_layer_3d.c +++ b/src/compositor/mpeg4_layer_3d.c @@ -170,8 +170,8 @@ u32 layer3d_setup_offscreen(GF_Node *node, Layer3DStack *st, GF_TraverseState *t #endif /*FIXME - we assume RGB+Depth+bitshape, we should check with the video out module*/ -#ifdef GF_SR_USE_DEPTH - new_pixel_format = GF_PIXEL_RGBDS; +#if defined(GF_SR_USE_DEPTH) && !defined(GPAC_DISABLE_3D) + if (st->visual->type_3d && (compositor->video_out->hw_caps & GF_VIDEO_HW_HAS_DEPTH) ) new_pixel_format = GF_PIXEL_RGBDS; #endif w = (u32) FIX2INT(gf_ceil(width)); @@ -251,6 +251,8 @@ u32 layer3d_setup_offscreen(GF_Node *node, Layer3DStack *st, GF_TraverseState *t st->unsupported = 1; return 0; } + /*reload openGL ext*/ + gf_sc_load_opengl_extensions(compositor, 1); } #endif st->txh.data = (char*)gf_malloc(sizeof(unsigned char) * st->txh.stride * st->txh.height); @@ -605,7 +607,7 @@ layer3d_unchanged_2d: start.y = gf_muldiv(start.y, st->visual->camera.height, st->clip.height); } - visual_3d_setup_projection(tr_state); + visual_3d_setup_projection(tr_state, 1); in_x = 2 * gf_divfix(start.x, st->visual->camera.width); in_y = 2 * gf_divfix(start.y, st->visual->camera.height); diff --git a/src/compositor/mpeg4_layout.c b/src/compositor/mpeg4_layout.c index ee714a7..7b864e9 100644 --- a/src/compositor/mpeg4_layout.c +++ b/src/compositor/mpeg4_layout.c @@ -667,7 +667,8 @@ static void TraverseLayout(GF_Node *node, void *rs, Bool is_destroy) } recompute_layout = 0; - if (gf_node_dirty_get(node)) recompute_layout = 1; + if (gf_node_dirty_get(node)) + recompute_layout = 1; /*setup clipping*/ prev_clip = tr_state->visual->top_clipper; @@ -705,9 +706,11 @@ static void TraverseLayout(GF_Node *node, void *rs, Bool is_destroy) /*apply justification*/ layout_justify(st, l); - - /*prepare initial scroll bounds*/ -// layout_setup_scroll_bounds(st, l); + + /*if scrolling, update bounds*/ + if (l->scrollRate && st->is_scrolling) { + layout_setup_scroll_bounds(st, l); + } } diff --git a/src/compositor/mpeg4_textures.c b/src/compositor/mpeg4_textures.c index fbafe8a..62d6fe5 100644 --- a/src/compositor/mpeg4_textures.c +++ b/src/compositor/mpeg4_textures.c @@ -23,7 +23,6 @@ */ #include "texturing.h" -//#include "nodes_stacks.h" #include #include @@ -34,6 +33,12 @@ #ifdef __cplusplus extern "C" { #endif + +/*for cache texture decode and hash*/ +#include +#include + + typedef struct { GF_TextureHandler txh; @@ -237,6 +242,9 @@ static void imagetexture_destroy(GF_Node *node, void *rs, Bool is_destroy) gf_delete_file((char*)file); gf_cfg_del_section(txh->compositor->user->config, section); } + + if (txh->data) gf_free(txh->data); + txh->data = NULL; } gf_sc_texture_destroy(txh); gf_free(txh); @@ -245,31 +253,123 @@ static void imagetexture_destroy(GF_Node *node, void *rs, Bool is_destroy) static void imagetexture_update(GF_TextureHandler *txh) { - MFURL url; - SFURL sfurl; if (gf_node_get_tag(txh->owner)!=TAG_MPEG4_CacheTexture) { - url = ((M_ImageTexture *) txh->owner)->url; - } else { - url.count = 1; - sfurl.OD_ID=GF_MEDIA_EXTERNAL_ID; - sfurl.url = ((M_CacheTexture *) txh->owner)->image.buffer; - url.vals = &sfurl; - } + MFURL url = ((M_ImageTexture *) txh->owner)->url; - /*setup texture if needed*/ - if (!txh->is_open && url.count) { - gf_sc_texture_play(txh, &url); - } - gf_sc_texture_update_frame(txh, 0); - - if ( - /*URL is present but not opened - redraw till fetch*/ - /* (txh->stream && !txh->tx_io) && */ - /*image has been updated*/ - txh->needs_refresh) { - /*mark all subtrees using this image as dirty*/ - gf_node_dirty_parents(txh->owner); - gf_sc_invalidate(txh->compositor, NULL); + /*setup texture if needed*/ + if (!txh->is_open && url.count) { + gf_sc_texture_play(txh, &url); + } + gf_sc_texture_update_frame(txh, 0); + + if ( + /*URL is present but not opened - redraw till fetch*/ + /* (txh->stream && !txh->tx_io) && */ + /*image has been updated*/ + txh->needs_refresh) { + /*mark all subtrees using this image as dirty*/ + gf_node_dirty_parents(txh->owner); + gf_sc_invalidate(txh->compositor, NULL); + } + return; + } + /*cache texture case*/ + else { + M_CacheTexture *ct = (M_CacheTexture *) txh->owner; + + /*decode cacheTexture data */ + if (ct->data && !txh->data) { + u32 out_size; + GF_Err e; + switch (ct->objectTypeIndication) { + case GPAC_OTI_IMAGE_JPEG: + out_size = 0; + e = gf_img_jpeg_dec(ct->data, ct->data_len, &txh->width, &txh->height, &txh->pixelformat, NULL, &out_size, 3); + if (e==GF_BUFFER_TOO_SMALL) { + u32 BPP; + txh->data = gf_malloc(sizeof(char) * out_size); + if (txh->pixelformat==GF_PIXEL_GREYSCALE) BPP = 1; + else BPP = 3; + + e = gf_img_jpeg_dec(ct->data, ct->data_len, &txh->width, &txh->height, &txh->pixelformat, txh->data, &out_size, BPP); + if (e==GF_OK) { + txh->needs_refresh = 1; + txh->stride = out_size / txh->height; + } + } + break; + case GPAC_OTI_IMAGE_PNG: + out_size = 0; + e = gf_img_png_dec(ct->data, ct->data_len, &txh->width, &txh->height, &txh->pixelformat, NULL, &out_size); + if (e==GF_BUFFER_TOO_SMALL) { + txh->data = gf_malloc(sizeof(char) * out_size); + e = gf_img_png_dec(ct->data, ct->data_len, &txh->width, &txh->height, &txh->pixelformat, txh->data, &out_size); + if (e==GF_OK) { + txh->needs_refresh = 1; + txh->stride = out_size / txh->height; + } + } + break; + } + + /*cacheURL is specified, store the image*/ + if (ct->cacheURL.buffer) { + u32 i; + u8 hash[20]; + FILE *cached_texture; + char szExtractName[GF_MAX_PATH], section[16], *opt, *src_url; + opt = (char *) gf_cfg_get_key(txh->compositor->user->config, "General", "CacheDirectory"); + if (opt) { + strcpy(szExtractName, opt); + } else { + opt = gf_get_default_cache_directory(); + strcpy(szExtractName, opt); + gf_free(opt); + } + strcat(szExtractName, "/"); + src_url = (char *) gf_scene_get_service_url( gf_node_get_graph(txh->owner ) ); + + gf_sha1_csum(src_url, strlen(src_url), hash); + for (i=0; i<20; i++) { + char t[3]; + t[2] = 0; + sprintf(t, "%02X", hash[i]); + strcat(szExtractName, t); + } + strcat(szExtractName, "_"); + + strcat(szExtractName, ct->cacheURL.buffer); + cached_texture = gf_f64_open(szExtractName, "wb"); + if (cached_texture) { + fwrite(ct->data, 1, ct->data_len, cached_texture); + fclose(cached_texture); + } + + /*and write cache info*/ + if (ct->expirationDate!=0) { + sprintf(section, "@cache=%08X", (u32) (PTR_TO_U_CAST ct)); + gf_cfg_set_key(txh->compositor->user->config, section, "serviceURL", src_url); + gf_cfg_set_key(txh->compositor->user->config, section, "cacheFile", szExtractName); + gf_cfg_set_key(txh->compositor->user->config, section, "cacheName", ct->cacheURL.buffer); + + if (ct->expirationDate>0) { + char exp[50]; + u32 sec, frac; + gf_net_get_ntp(&sec, &frac); + sec += ct->expirationDate; + sprintf(exp, "%u", sec); + gf_cfg_set_key(txh->compositor->user->config, section, "expireAfterNTP", exp); + } else { + gf_cfg_set_key(txh->compositor->user->config, section, "expireAfterNTP", "0"); + } + } + } + + /*done with image, destroy buffer*/ + gf_free(ct->data); + ct->data =NULL; + ct->data_len = 0; + } } } @@ -287,7 +387,6 @@ void compositor_init_imagetexture(GF_Compositor *compositor, GF_Node *node) if (((M_ImageTexture*)node)->repeatS) txh->flags |= GF_SR_TEXTURE_REPEAT_S; if (((M_ImageTexture*)node)->repeatT) txh->flags |= GF_SR_TEXTURE_REPEAT_T; } else { - char section[16]; const char *url; u32 i, count; M_CacheTexture*ct = (M_CacheTexture*)node; @@ -314,25 +413,6 @@ void compositor_init_imagetexture(GF_Compositor *compositor, GF_Node *node) } } - sprintf(section, "@cache=%08X", (u32) (PTR_TO_U_CAST ct)); - gf_cfg_set_key(compositor->user->config, section, "serviceURL", url); - gf_cfg_set_key(compositor->user->config, section, "cacheFile", ct->image.buffer); - - /*setup cache if needed*/ - if (ct->cacheURL.buffer && (ct->expirationDate!=0) ) { - char exp[50]; - u32 sec, frac; - gf_cfg_set_key(compositor->user->config, section, "cacheName", ct->cacheURL.buffer); - - if (ct->expirationDate>0) { - gf_net_get_ntp(&sec, &frac); - sec += ct->expirationDate; - sprintf(exp, "%u", sec); - } else { - strcpy(exp, "0"); - } - gf_cfg_set_key(compositor->user->config, section, "expireAfterNTP", exp); - } } } diff --git a/src/compositor/navigate.c b/src/compositor/navigate.c index bd46767..d4cf4b1 100644 --- a/src/compositor/navigate.c +++ b/src/compositor/navigate.c @@ -218,6 +218,10 @@ Bool gf_sc_fit_world_to_screen(GF_Compositor *compositor) if (!tr_state.bbox.is_set) { gf_mx_v(compositor->mx); + /*empty world ...*/ + if (tr_state.bbox.radius==-1) return 1; + /*2D world with 3D camera forced*/ + if (tr_state.bounds.width&&tr_state.bounds.height) return 1; return 0; } diff --git a/src/compositor/svg_base.c b/src/compositor/svg_base.c index 54a8a77..c45be6d 100644 --- a/src/compositor/svg_base.c +++ b/src/compositor/svg_base.c @@ -114,7 +114,7 @@ void compositor_svg_restore_parent_transformation(GF_TraverseState *tr_state, GF gf_mx2d_copy(tr_state->transform, *backup_matrix_2d); } -#ifdef UNUSED_FUNC +#ifdef GPAC_UNUSED_FUNC static void gf_svg_apply_inheritance_no_inheritance(SVGAllAttributes *all_atts, SVGPropertiesPointers *render_svg_props) { #define CHECK_PROP(a, b) if (b) a = b; @@ -138,7 +138,7 @@ static void gf_svg_apply_inheritance_no_inheritance(SVGAllAttributes *all_atts, CHECK_PROP(render_svg_props->stroke_width, all_atts->stroke_width); CHECK_PROP(render_svg_props->visibility, all_atts->visibility); } -#endif /* UNUSED_FUNC */ +#endif /*GPAC_UNUSED_FUNC*/ static const struct svg_11_feature { const char *name; Bool supported; } svg11_features[] = { diff --git a/src/compositor/svg_filters.c b/src/compositor/svg_filters.c index da43f8c..b6070d8 100644 --- a/src/compositor/svg_filters.c +++ b/src/compositor/svg_filters.c @@ -1,429 +1,429 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Jean le Feuvre - * Copyright (c) 2010-200X ENST - * All rights reserved - * - * This file is part of GPAC / Scene Compositor 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 "visual_manager.h" - -#ifndef GPAC_DISABLE_SVG -#include "nodes_stacks.h" -#include "texturing.h" - -typedef struct -{ - GF_TextureHandler txh; - Drawable *drawable; - u8 *data; - u32 alloc_size; -} GF_FilterStack; - - - -void apply_feComponentTransfer(GF_Node *node, GF_TextureHandler *source, GF_Rect *region) -{ - GF_ChildNodeItem *l = ((GF_ParentNode*)node)->children; - while (l) { - SVG_Filter_TransferType type = SVG_FILTER_TRANSFER_IDENTITY; - u32 i, j; - GF_List *table = NULL; - Fixed slope = FIX_ONE; - Fixed intercept = 0; - Fixed amplitude = 1; - Fixed exponent = 1; - Fixed offset = 0; - u8 *ptr = NULL; - /*FIXME: unused u32 tag = gf_node_get_tag(l->node);*/ - GF_DOMAttribute *att = ((SVG_Element *)l->node)->attributes; - - while (att) { - switch (att->tag) { - case TAG_SVG_ATT_filter_transfer_type: type = *(u8*)att->data; break; - case TAG_SVG_ATT_filter_table_values: table = *(GF_List **)att->data; break; - case TAG_SVG_ATT_slope: slope = ((SVG_Number *)att->data)->value; break; - case TAG_SVG_ATT_filter_intercept: intercept = ((SVG_Number *)att->data)->value; break; - case TAG_SVG_ATT_filter_amplitude: amplitude = ((SVG_Number *)att->data)->value; break; - case TAG_SVG_ATT_filter_exponent: exponent = ((SVG_Number *)att->data)->value; break; - case TAG_SVG_ATT_offset: offset = ((SVG_Number *)att->data)->value; break; - } - att = att->next; - } - if (type==SVG_FILTER_TRANSFER_IDENTITY) { - l = l->next; - continue; - } - switch (gf_node_get_tag(l->node)) { - case TAG_SVG_feFuncR: - if (source->pixelformat==GF_PIXEL_RGBA) ptr = source->data; - else ptr = source->data+2; - break; - case TAG_SVG_feFuncG: - if (source->pixelformat==GF_PIXEL_RGBA) ptr = source->data+1; - else ptr = source->data+1; - break; - case TAG_SVG_feFuncB: - if (source->pixelformat==GF_PIXEL_RGBA) ptr = source->data+2; - else ptr = source->data; - break; - case TAG_SVG_feFuncA: - if (source->pixelformat==GF_PIXEL_RGBA) ptr = source->data+3; - else ptr = source->data+3; - break; - } - - if ((type==SVG_FILTER_TRANSFER_LINEAR) && (intercept || (slope!=FIX_ONE)) ) { - intercept *= 255; - assert( ptr ); - for (i=0; iheight; i++) { - for (j=0; jwidth; j++) { - Fixed p = (*ptr) * slope + intercept; - ptr[0] = (u8) MIN(MAX(0, p), 255); - ptr += 4; - } - } - } else if (type==SVG_FILTER_TRANSFER_GAMMA) { - assert( ptr ); - for (i=0; iheight; i++) { - for (j=0; jwidth; j++) { - Fixed p = 255 * gf_mulfix(amplitude, FLT2FIX( pow( INT2FIX(*ptr)/255, FIX2FLT(exponent) ) ) ) + offset; - ptr[0] = (u8) MIN(MAX(0, p), 255); - ptr += 4; - } - } - } else if ((type==SVG_FILTER_TRANSFER_TABLE) && table && (gf_list_count(table)>=2) ) { - u32 count = gf_list_count(table); - u32 N = count-1; - assert( ptr ); - for (i=0; iheight; i++) { - for (j=0; jwidth; j++) { - SVG_Number *vk, *vk1; - Fixed p = INT2FIX(ptr[0]) / 255; - Fixed pN = p*N; - u32 k = FIX2INT(p*N); - if (k==N) k--; - vk = gf_list_get(table, k); - vk1 = gf_list_get(table, k+1); - p = 255 * ( vk->value + gf_mulfix( pN - INT2FIX(k), (vk1->value - vk->value)) ); - ptr[0] = (u8) MIN(MAX(0, p), 255); - ptr += 4; - } - } - } else if ((type==SVG_FILTER_TRANSFER_DISCRETE) && table && gf_list_count(table) ) { - u32 count = gf_list_count(table); - assert( ptr ); - for (i=0; iheight; i++) { - for (j=0; jwidth; j++) { - SVG_Number *vk; - Fixed p = INT2FIX(ptr[0]) / 255; - Fixed pN = p*count; - u32 k = 0; - while (kpN) break; - k++; - } - if (k) k--; - vk = gf_list_get(table, k); - p = 255 * vk->value; - ptr[0] = (u8) MIN(MAX(0, p), 255); - ptr += 4; - } - } - } - l = l->next; - } -} - -void svg_filter_apply(GF_Node *node, GF_TextureHandler *source, GF_Rect *region) -{ - GF_ChildNodeItem *l = ((GF_ParentNode*)node)->children; - - while (l) { - switch (gf_node_get_tag(l->node)) { - case TAG_SVG_feComponentTransfer: - apply_feComponentTransfer(l->node, source, region); - break; - } - l = l->next; - } -} - -/* - This is a crude draft implementation of filter. The main drawback is that we don't cache any data. - We should be able to check for changes in the sub-group or in the filter -*/ -void svg_draw_filter(GF_Node *filter, GF_Node *node, GF_TraverseState *tr_state) -{ - GF_IRect rc1, rc2; - -#ifndef GPAC_DISABLE_3D - u32 type_3d; -#endif - u32 prev_flags; - GF_IRect txrc; - Fixed scale_x, scale_y, temp_x, temp_y; - DrawableContext *ctx, *child_ctx; - GF_SURFACE offscreen_surface, old_surf; - GF_Rect bounds, local_bounds, rc; - GF_Matrix2D backup; - SVGAllAttributes all_atts; - GF_FilterStack *st = gf_node_get_private(filter); - assert(tr_state->traversing_mode==TRAVERSE_SORT); - - /*store the current transform matrix, create a new one for group_cache*/ - gf_mx2d_copy(backup, tr_state->transform); - gf_mx2d_init(tr_state->transform); - - gf_node_allow_cyclic_traverse(node); - tr_state->traversing_mode = TRAVERSE_GET_BOUNDS; - tr_state->bounds.width = tr_state->bounds.height = 0; - gf_node_traverse(node, tr_state); - - local_bounds = bounds = tr_state->bounds; - /*compute bounds in final coordinate system - this ensures that the cache has the correct anti aliasing*/ - gf_mx2d_apply_rect(&backup, &bounds); - txrc = gf_rect_pixelize(&bounds); - if (txrc.width%2) txrc.width++; - if (txrc.height%2) txrc.height++; - bounds = gf_rect_ft(&txrc); - - tr_state->traversing_mode = TRAVERSE_SORT; - - gf_mx2d_copy(tr_state->transform, backup); - - if (!bounds.width || !bounds.height) { - return; - } - - /*create a context */ - ctx = drawable_init_context_svg(st->drawable, tr_state); - if (!ctx) return; - - /*setup texture */ - st->txh.height = txrc.height; - st->txh.width = txrc.width; - - st->txh.stride = txrc.width * 4; - st->txh.pixelformat = GF_PIXEL_ARGB; -#ifndef GPAC_DISABLE_3D - if (tr_state->visual->type_3d) st->txh.pixelformat = GF_PIXEL_RGBA; -#endif - st->txh.transparent = 1; - - if (st->txh.stride * st->txh.height > st->alloc_size) { - st->alloc_size = st->txh.stride * st->txh.height; - st->data = (u8*)gf_realloc(st->data, sizeof(u8) * st->alloc_size); - } - memset(st->data, 0x0, sizeof(char) * st->txh.stride * st->txh.height); - st->txh.data = st->data; - /*setup geometry (rectangle matching the bounds of the object) - Warning, we want to center the cached bitmap at the center of the screen (main visual)*/ - gf_path_reset(st->drawable->path); - - gf_path_add_rect_center(st->drawable->path, - bounds.x + bounds.width/2, - bounds.y - bounds.height/2, - bounds.width, - bounds.height); - - - old_surf = tr_state->visual->raster_surface; - offscreen_surface = tr_state->visual->compositor->rasterizer->surface_new(tr_state->visual->compositor->rasterizer, tr_state->visual->center_coords); - tr_state->visual->raster_surface = offscreen_surface; - - gf_mx2d_copy(backup, tr_state->transform); - gf_mx2d_init(tr_state->transform); - - /*attach the buffer to visual*/ - tr_state->visual->compositor->rasterizer->surface_attach_to_buffer(offscreen_surface, st->txh.data, - st->txh.width, - st->txh.height, - 0, - st->txh.stride, - st->txh.pixelformat); - - prev_flags = tr_state->immediate_draw; - tr_state->immediate_draw = 1; - tr_state->traversing_mode = TRAVERSE_SORT; - tr_state->in_svg_filter = 1; - - /*recompute the bounds with the final scaling used*/ - scale_x = gf_divfix(bounds.width, local_bounds.width); - scale_y = gf_divfix(bounds.height, local_bounds.height); - gf_mx2d_init(tr_state->transform); - gf_mx2d_add_scale(&tr_state->transform, scale_x, scale_y); - - rc = local_bounds; - gf_mx2d_apply_rect(&tr_state->transform, &rc); - - /*centered the bitmap on the visual*/ - if (tr_state->visual->center_coords) { - temp_x = -rc.x - rc.width/2; - temp_y = rc.height/2 - rc.y; - } else { - temp_x = -rc.x; - temp_y = rc.height - rc.y; - } - gf_mx2d_add_translation(&tr_state->transform, temp_x, temp_y); - - - rc1 = tr_state->visual->surf_rect; - rc2 = tr_state->visual->top_clipper; - tr_state->visual->surf_rect.width = st->txh.width; - tr_state->visual->surf_rect.height = st->txh.height; - if (tr_state->visual->center_coords) { - tr_state->visual->surf_rect.y = st->txh.height/2; - tr_state->visual->surf_rect.x = -1 * (s32) st->txh.width/2; - } else { - tr_state->visual->surf_rect.y = st->txh.height; - tr_state->visual->surf_rect.x = 0; - } - tr_state->visual->top_clipper = tr_state->visual->surf_rect; - - -#ifndef GPAC_DISABLE_3D - type_3d = tr_state->visual->type_3d; - tr_state->visual->type_3d=0; -#endif - - if (prev_flags) gf_node_allow_cyclic_traverse(node); - gf_node_traverse(node, tr_state); - - child_ctx = ctx->next; - while (child_ctx && child_ctx->drawable) { - drawable_reset_bounds(child_ctx->drawable, tr_state->visual); - child_ctx->drawable = NULL; - child_ctx = child_ctx->next; - } - tr_state->visual->cur_context = ctx; - - - /*restore state and destroy whatever needs to be cleaned*/ - tr_state->in_svg_filter = 0; - tr_state->immediate_draw = prev_flags; - tr_state->visual->compositor->rasterizer->surface_delete(offscreen_surface); - tr_state->visual->raster_surface = old_surf; - tr_state->traversing_mode = TRAVERSE_SORT; - tr_state->visual->surf_rect = rc1; - tr_state->visual->top_clipper = rc2; -#ifndef GPAC_DISABLE_3D - tr_state->visual->type_3d = type_3d ; -#endif - - /*update texture*/ - st->txh.transparent = 1; - st->txh.flags |= GF_SR_TEXTURE_NO_GL_FLIP; - gf_sc_texture_set_data(&st->txh); -#ifndef GPAC_DISABLE_3D - if (tr_state->visual->type_3d) - gf_sc_texture_push_image(&st->txh, 0, 0); - else -#endif - gf_sc_texture_push_image(&st->txh, 0, 1); - - ctx->flags |= CTX_NO_ANTIALIAS; - ctx->aspect.fill_color = 0; - ctx->aspect.line_color = 0xFF000000; - ctx->aspect.fill_texture = &st->txh; - ctx->flags |= CTX_TEXTURE_DIRTY; - - /*get the filter region*/ - bounds = local_bounds; - gf_svg_flatten_attributes((SVG_Element *)filter, &all_atts); - if (!all_atts.filterUnits || (*all_atts.filterUnits==SVG_GRADIENTUNITS_OBJECT)) { - Fixed v; - v = all_atts.x ? all_atts.x->value : INT2FIX(-10); - bounds.x += gf_mulfix(v, bounds.width); - v = all_atts.y ? all_atts.y->value : INT2FIX(-10); - bounds.y += gf_mulfix(v, bounds.height); - v = all_atts.width ? all_atts.width->value : INT2FIX(120); - bounds.width = gf_mulfix(v, bounds.width); - v = all_atts.height ? all_atts.height->value : INT2FIX(120); - bounds.height = gf_mulfix(v, bounds.height); - } else { - bounds.x = all_atts.x ? all_atts.x->value : 0; - bounds.y = all_atts.y ? all_atts.y->value : 0; - bounds.width = all_atts.width ? all_atts.x->value : bounds.width; - bounds.height = all_atts.x ? all_atts.x->value : 120; - } - gf_mx2d_apply_rect(&backup, &bounds); - - svg_filter_apply(filter, &st->txh, &bounds); - - -#ifndef GPAC_DISABLE_3D - if (tr_state->visual->type_3d) { - if (!st->drawable->mesh) { - st->drawable->mesh = new_mesh(); - mesh_from_path(st->drawable->mesh, st->drawable->path); - } - visual_3d_draw_from_context(tr_state->ctx, tr_state); - ctx->drawable = NULL; - return; - } -#endif - - /*we computed the texture in final screen coordinate, so use the identity matrix for the context*/ - gf_mx2d_init(tr_state->transform); - drawable_finalize_sort(ctx, tr_state, NULL); - gf_mx2d_copy(tr_state->transform, backup); -} - -static void svg_traverse_filter(GF_Node *node, void *rs, Bool is_destroy) -{ - GF_TraverseState *tr_state = (GF_TraverseState *)rs; - GF_FilterStack *st = gf_node_get_private(node); - if (is_destroy) { - drawable_del(st->drawable); - if (st->data) gf_free(st->data); - st->txh.data = NULL; - gf_sc_texture_release(&st->txh); - gf_sc_texture_destroy(&st->txh); - gf_free(st); - return; - } - - if (tr_state->traversing_mode==TRAVERSE_DRAW_2D) { - if (! tr_state->visual->DrawBitmap(tr_state->visual, tr_state, tr_state->ctx, NULL)) { - visual_2d_texture_path(tr_state->visual, st->drawable->path, tr_state->ctx, tr_state); - } - } -} - -void compositor_init_svg_filter(GF_Compositor *compositor, GF_Node *node) -{ - GF_FilterStack *stack; - GF_SAFEALLOC(stack, GF_FilterStack); - gf_node_set_private(node, stack); - gf_node_set_callback_function(node, svg_traverse_filter); - - - gf_sc_texture_setup(&stack->txh, compositor, node); - stack->drawable = drawable_new(); - /*draw the cache through traverse callback*/ - stack->drawable->flags |= DRAWABLE_USE_TRAVERSE_DRAW; - stack->drawable->node = node; - gf_sc_texture_allocate(&stack->txh); -} - -#endif - - +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean le Feuvre + * Copyright (c) 2010-200X ENST + * All rights reserved + * + * This file is part of GPAC / Scene Compositor 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 "visual_manager.h" + +#ifndef GPAC_DISABLE_SVG +#include "nodes_stacks.h" +#include "texturing.h" + +typedef struct +{ + GF_TextureHandler txh; + Drawable *drawable; + u8 *data; + u32 alloc_size; +} GF_FilterStack; + + + +void apply_feComponentTransfer(GF_Node *node, GF_TextureHandler *source, GF_Rect *region) +{ + GF_ChildNodeItem *l = ((GF_ParentNode*)node)->children; + while (l) { + SVG_Filter_TransferType type = SVG_FILTER_TRANSFER_IDENTITY; + u32 i, j; + GF_List *table = NULL; + Fixed slope = FIX_ONE; + Fixed intercept = 0; + Fixed amplitude = 1; + Fixed exponent = 1; + Fixed offset = 0; + u8 *ptr = NULL; + /*FIXME: unused u32 tag = gf_node_get_tag(l->node);*/ + GF_DOMAttribute *att = ((SVG_Element *)l->node)->attributes; + + while (att) { + switch (att->tag) { + case TAG_SVG_ATT_filter_transfer_type: type = *(u8*)att->data; break; + case TAG_SVG_ATT_filter_table_values: table = *(GF_List **)att->data; break; + case TAG_SVG_ATT_slope: slope = ((SVG_Number *)att->data)->value; break; + case TAG_SVG_ATT_filter_intercept: intercept = ((SVG_Number *)att->data)->value; break; + case TAG_SVG_ATT_filter_amplitude: amplitude = ((SVG_Number *)att->data)->value; break; + case TAG_SVG_ATT_filter_exponent: exponent = ((SVG_Number *)att->data)->value; break; + case TAG_SVG_ATT_offset: offset = ((SVG_Number *)att->data)->value; break; + } + att = att->next; + } + if (type==SVG_FILTER_TRANSFER_IDENTITY) { + l = l->next; + continue; + } + switch (gf_node_get_tag(l->node)) { + case TAG_SVG_feFuncR: + if (source->pixelformat==GF_PIXEL_RGBA) ptr = source->data; + else ptr = source->data+2; + break; + case TAG_SVG_feFuncG: + if (source->pixelformat==GF_PIXEL_RGBA) ptr = source->data+1; + else ptr = source->data+1; + break; + case TAG_SVG_feFuncB: + if (source->pixelformat==GF_PIXEL_RGBA) ptr = source->data+2; + else ptr = source->data; + break; + case TAG_SVG_feFuncA: + if (source->pixelformat==GF_PIXEL_RGBA) ptr = source->data+3; + else ptr = source->data+3; + break; + } + + if ((type==SVG_FILTER_TRANSFER_LINEAR) && (intercept || (slope!=FIX_ONE)) ) { + intercept *= 255; + assert( ptr ); + for (i=0; iheight; i++) { + for (j=0; jwidth; j++) { + Fixed p = (*ptr) * slope + intercept; + ptr[0] = (u8) MIN(MAX(0, p), 255); + ptr += 4; + } + } + } else if (type==SVG_FILTER_TRANSFER_GAMMA) { + assert( ptr ); + for (i=0; iheight; i++) { + for (j=0; jwidth; j++) { + Fixed p = 255 * gf_mulfix(amplitude, FLT2FIX( pow( INT2FIX(*ptr)/255, FIX2FLT(exponent) ) ) ) + offset; + ptr[0] = (u8) MIN(MAX(0, p), 255); + ptr += 4; + } + } + } else if ((type==SVG_FILTER_TRANSFER_TABLE) && table && (gf_list_count(table)>=2) ) { + u32 count = gf_list_count(table); + u32 N = count-1; + assert( ptr ); + for (i=0; iheight; i++) { + for (j=0; jwidth; j++) { + SVG_Number *vk, *vk1; + Fixed p = INT2FIX(ptr[0]) / 255; + Fixed pN = p*N; + u32 k = FIX2INT(p*N); + if (k==N) k--; + vk = gf_list_get(table, k); + vk1 = gf_list_get(table, k+1); + p = 255 * ( vk->value + gf_mulfix( pN - INT2FIX(k), (vk1->value - vk->value)) ); + ptr[0] = (u8) MIN(MAX(0, p), 255); + ptr += 4; + } + } + } else if ((type==SVG_FILTER_TRANSFER_DISCRETE) && table && gf_list_count(table) ) { + u32 count = gf_list_count(table); + assert( ptr ); + for (i=0; iheight; i++) { + for (j=0; jwidth; j++) { + SVG_Number *vk; + Fixed p = INT2FIX(ptr[0]) / 255; + Fixed pN = p*count; + u32 k = 0; + while (kpN) break; + k++; + } + if (k) k--; + vk = gf_list_get(table, k); + p = 255 * vk->value; + ptr[0] = (u8) MIN(MAX(0, p), 255); + ptr += 4; + } + } + } + l = l->next; + } +} + +void svg_filter_apply(GF_Node *node, GF_TextureHandler *source, GF_Rect *region) +{ + GF_ChildNodeItem *l = ((GF_ParentNode*)node)->children; + + while (l) { + switch (gf_node_get_tag(l->node)) { + case TAG_SVG_feComponentTransfer: + apply_feComponentTransfer(l->node, source, region); + break; + } + l = l->next; + } +} + +/* + This is a crude draft implementation of filter. The main drawback is that we don't cache any data. + We should be able to check for changes in the sub-group or in the filter +*/ +void svg_draw_filter(GF_Node *filter, GF_Node *node, GF_TraverseState *tr_state) +{ + GF_IRect rc1, rc2; + +#ifndef GPAC_DISABLE_3D + u32 type_3d; +#endif + u32 prev_flags; + GF_IRect txrc; + Fixed scale_x, scale_y, temp_x, temp_y; + DrawableContext *ctx, *child_ctx; + GF_SURFACE offscreen_surface, old_surf; + GF_Rect bounds, local_bounds, rc; + GF_Matrix2D backup; + SVGAllAttributes all_atts; + GF_FilterStack *st = gf_node_get_private(filter); + assert(tr_state->traversing_mode==TRAVERSE_SORT); + + /*store the current transform matrix, create a new one for group_cache*/ + gf_mx2d_copy(backup, tr_state->transform); + gf_mx2d_init(tr_state->transform); + + gf_node_allow_cyclic_traverse(node); + tr_state->traversing_mode = TRAVERSE_GET_BOUNDS; + tr_state->bounds.width = tr_state->bounds.height = 0; + gf_node_traverse(node, tr_state); + + local_bounds = bounds = tr_state->bounds; + /*compute bounds in final coordinate system - this ensures that the cache has the correct anti aliasing*/ + gf_mx2d_apply_rect(&backup, &bounds); + txrc = gf_rect_pixelize(&bounds); + if (txrc.width%2) txrc.width++; + if (txrc.height%2) txrc.height++; + bounds = gf_rect_ft(&txrc); + + tr_state->traversing_mode = TRAVERSE_SORT; + + gf_mx2d_copy(tr_state->transform, backup); + + if (!bounds.width || !bounds.height) { + return; + } + + /*create a context */ + ctx = drawable_init_context_svg(st->drawable, tr_state); + if (!ctx) return; + + /*setup texture */ + st->txh.height = txrc.height; + st->txh.width = txrc.width; + + st->txh.stride = txrc.width * 4; + st->txh.pixelformat = GF_PIXEL_ARGB; +#ifndef GPAC_DISABLE_3D + if (tr_state->visual->type_3d) st->txh.pixelformat = GF_PIXEL_RGBA; +#endif + st->txh.transparent = 1; + + if (st->txh.stride * st->txh.height > st->alloc_size) { + st->alloc_size = st->txh.stride * st->txh.height; + st->data = (u8*)gf_realloc(st->data, sizeof(u8) * st->alloc_size); + } + memset(st->data, 0x0, sizeof(char) * st->txh.stride * st->txh.height); + st->txh.data = st->data; + /*setup geometry (rectangle matching the bounds of the object) + Warning, we want to center the cached bitmap at the center of the screen (main visual)*/ + gf_path_reset(st->drawable->path); + + gf_path_add_rect_center(st->drawable->path, + bounds.x + bounds.width/2, + bounds.y - bounds.height/2, + bounds.width, + bounds.height); + + + old_surf = tr_state->visual->raster_surface; + offscreen_surface = tr_state->visual->compositor->rasterizer->surface_new(tr_state->visual->compositor->rasterizer, tr_state->visual->center_coords); + tr_state->visual->raster_surface = offscreen_surface; + + gf_mx2d_copy(backup, tr_state->transform); + gf_mx2d_init(tr_state->transform); + + /*attach the buffer to visual*/ + tr_state->visual->compositor->rasterizer->surface_attach_to_buffer(offscreen_surface, st->txh.data, + st->txh.width, + st->txh.height, + 0, + st->txh.stride, + st->txh.pixelformat); + + prev_flags = tr_state->immediate_draw; + tr_state->immediate_draw = 1; + tr_state->traversing_mode = TRAVERSE_SORT; + tr_state->in_svg_filter = 1; + + /*recompute the bounds with the final scaling used*/ + scale_x = gf_divfix(bounds.width, local_bounds.width); + scale_y = gf_divfix(bounds.height, local_bounds.height); + gf_mx2d_init(tr_state->transform); + gf_mx2d_add_scale(&tr_state->transform, scale_x, scale_y); + + rc = local_bounds; + gf_mx2d_apply_rect(&tr_state->transform, &rc); + + /*centered the bitmap on the visual*/ + if (tr_state->visual->center_coords) { + temp_x = -rc.x - rc.width/2; + temp_y = rc.height/2 - rc.y; + } else { + temp_x = -rc.x; + temp_y = rc.height - rc.y; + } + gf_mx2d_add_translation(&tr_state->transform, temp_x, temp_y); + + + rc1 = tr_state->visual->surf_rect; + rc2 = tr_state->visual->top_clipper; + tr_state->visual->surf_rect.width = st->txh.width; + tr_state->visual->surf_rect.height = st->txh.height; + if (tr_state->visual->center_coords) { + tr_state->visual->surf_rect.y = st->txh.height/2; + tr_state->visual->surf_rect.x = -1 * (s32) st->txh.width/2; + } else { + tr_state->visual->surf_rect.y = st->txh.height; + tr_state->visual->surf_rect.x = 0; + } + tr_state->visual->top_clipper = tr_state->visual->surf_rect; + + +#ifndef GPAC_DISABLE_3D + type_3d = tr_state->visual->type_3d; + tr_state->visual->type_3d=0; +#endif + + if (prev_flags) gf_node_allow_cyclic_traverse(node); + gf_node_traverse(node, tr_state); + + child_ctx = ctx->next; + while (child_ctx && child_ctx->drawable) { + drawable_reset_bounds(child_ctx->drawable, tr_state->visual); + child_ctx->drawable = NULL; + child_ctx = child_ctx->next; + } + tr_state->visual->cur_context = ctx; + + + /*restore state and destroy whatever needs to be cleaned*/ + tr_state->in_svg_filter = 0; + tr_state->immediate_draw = prev_flags; + tr_state->visual->compositor->rasterizer->surface_delete(offscreen_surface); + tr_state->visual->raster_surface = old_surf; + tr_state->traversing_mode = TRAVERSE_SORT; + tr_state->visual->surf_rect = rc1; + tr_state->visual->top_clipper = rc2; +#ifndef GPAC_DISABLE_3D + tr_state->visual->type_3d = type_3d ; +#endif + + /*update texture*/ + st->txh.transparent = 1; + st->txh.flags |= GF_SR_TEXTURE_NO_GL_FLIP; + gf_sc_texture_set_data(&st->txh); +#ifndef GPAC_DISABLE_3D + if (tr_state->visual->type_3d) + gf_sc_texture_push_image(&st->txh, 0, 0); + else +#endif + gf_sc_texture_push_image(&st->txh, 0, 1); + + ctx->flags |= CTX_NO_ANTIALIAS; + ctx->aspect.fill_color = 0; + ctx->aspect.line_color = 0xFF000000; + ctx->aspect.fill_texture = &st->txh; + ctx->flags |= CTX_TEXTURE_DIRTY; + + /*get the filter region*/ + bounds = local_bounds; + gf_svg_flatten_attributes((SVG_Element *)filter, &all_atts); + if (!all_atts.filterUnits || (*all_atts.filterUnits==SVG_GRADIENTUNITS_OBJECT)) { + Fixed v; + v = all_atts.x ? all_atts.x->value : INT2FIX(-10); + bounds.x += gf_mulfix(v, bounds.width); + v = all_atts.y ? all_atts.y->value : INT2FIX(-10); + bounds.y += gf_mulfix(v, bounds.height); + v = all_atts.width ? all_atts.width->value : INT2FIX(120); + bounds.width = gf_mulfix(v, bounds.width); + v = all_atts.height ? all_atts.height->value : INT2FIX(120); + bounds.height = gf_mulfix(v, bounds.height); + } else { + bounds.x = all_atts.x ? all_atts.x->value : 0; + bounds.y = all_atts.y ? all_atts.y->value : 0; + bounds.width = all_atts.width ? all_atts.x->value : bounds.width; + bounds.height = all_atts.x ? all_atts.x->value : 120; + } + gf_mx2d_apply_rect(&backup, &bounds); + + svg_filter_apply(filter, &st->txh, &bounds); + + +#ifndef GPAC_DISABLE_3D + if (tr_state->visual->type_3d) { + if (!st->drawable->mesh) { + st->drawable->mesh = new_mesh(); + mesh_from_path(st->drawable->mesh, st->drawable->path); + } + visual_3d_draw_from_context(tr_state->ctx, tr_state); + ctx->drawable = NULL; + return; + } +#endif + + /*we computed the texture in final screen coordinate, so use the identity matrix for the context*/ + gf_mx2d_init(tr_state->transform); + drawable_finalize_sort(ctx, tr_state, NULL); + gf_mx2d_copy(tr_state->transform, backup); +} + +static void svg_traverse_filter(GF_Node *node, void *rs, Bool is_destroy) +{ + GF_TraverseState *tr_state = (GF_TraverseState *)rs; + GF_FilterStack *st = gf_node_get_private(node); + if (is_destroy) { + drawable_del(st->drawable); + if (st->data) gf_free(st->data); + st->txh.data = NULL; + gf_sc_texture_release(&st->txh); + gf_sc_texture_destroy(&st->txh); + gf_free(st); + return; + } + + if (tr_state->traversing_mode==TRAVERSE_DRAW_2D) { + if (! tr_state->visual->DrawBitmap(tr_state->visual, tr_state, tr_state->ctx, NULL)) { + visual_2d_texture_path(tr_state->visual, st->drawable->path, tr_state->ctx, tr_state); + } + } +} + +void compositor_init_svg_filter(GF_Compositor *compositor, GF_Node *node) +{ + GF_FilterStack *stack; + GF_SAFEALLOC(stack, GF_FilterStack); + gf_node_set_private(node, stack); + gf_node_set_callback_function(node, svg_traverse_filter); + + + gf_sc_texture_setup(&stack->txh, compositor, node); + stack->drawable = drawable_new(); + /*draw the cache through traverse callback*/ + stack->drawable->flags |= DRAWABLE_USE_TRAVERSE_DRAW; + stack->drawable->node = node; + gf_sc_texture_allocate(&stack->txh); +} + +#endif + + diff --git a/src/compositor/svg_media.c b/src/compositor/svg_media.c index e02bd7e..59f2732 100644 --- a/src/compositor/svg_media.c +++ b/src/compositor/svg_media.c @@ -208,6 +208,8 @@ static void SVG_Build_Bitmap_Graph(SVG_video_stack *stack, GF_TraverseState *tr_ gf_path_get_bounds(stack->graph->path, &new_rc); if (!gf_rect_equal(rc, new_rc)) drawable_mark_modified(stack->graph, tr_state); + else if (stack->txh.flags & GF_SR_TEXTURE_PRIVATE_MEDIA) + drawable_mark_modified(stack->graph, tr_state); gf_node_dirty_clear(stack->graph->node, GF_SG_SVG_GEOMETRY_DIRTY); } @@ -283,8 +285,8 @@ static void svg_traverse_bitmap(GF_Node *node, void *rs, Bool is_destroy) svg_audio_smil_evaluate_ex(NULL, 0, SMIL_TIMING_EVAL_REMOVE, stack->audio, stack->txh.owner); gf_node_unregister(stack->audio, NULL); stack->audio = NULL; - stack->audio_dirty = 1; } + stack->audio_dirty = 1; if (stack->txurl.count) svg_play_texture(stack, &all_atts); gf_node_dirty_clear(node, GF_SG_SVG_XLINK_HREF_DIRTY); @@ -470,17 +472,19 @@ static void SVG_Update_video(GF_TextureHandler *txh) } } - if (!stack->audio && (gf_mo_has_audio(stack->txh.stream) || stack->audio_dirty)) { - GF_FieldInfo att_vid, att_aud; - stack->audio = gf_node_new(gf_node_get_graph(stack->txh.owner), TAG_SVG_audio); - gf_node_register(stack->audio, NULL); - if (gf_node_get_attribute_by_tag(stack->txh.owner, TAG_XLINK_ATT_href, 0, 0, &att_vid)==GF_OK) { - gf_node_get_attribute_by_tag(stack->audio, TAG_XLINK_ATT_href, 1, 0, &att_aud); - gf_svg_attributes_copy(&att_aud, &att_vid, 0); - } - /*BYPASS SMIL TIMING MODULE!!*/ - compositor_init_svg_audio(stack->txh.compositor, stack->audio, 1); + if (!stack->audio && stack->audio_dirty) { stack->audio_dirty = 0; + if (gf_mo_has_audio(stack->txh.stream)) { + GF_FieldInfo att_vid, att_aud; + stack->audio = gf_node_new(gf_node_get_graph(stack->txh.owner), TAG_SVG_audio); + gf_node_register(stack->audio, NULL); + if (gf_node_get_attribute_by_tag(stack->txh.owner, TAG_XLINK_ATT_href, 0, 0, &att_vid)==GF_OK) { + gf_node_get_attribute_by_tag(stack->audio, TAG_XLINK_ATT_href, 1, 0, &att_aud); + gf_svg_attributes_copy(&att_aud, &att_vid, 0); + } + /*BYPASS SMIL TIMING MODULE!!*/ + compositor_init_svg_audio(stack->txh.compositor, stack->audio, 1); + } } /*we have no choice but retraversing the graph until we're inactive since the movie framerate and @@ -564,7 +568,7 @@ void svg_pause_video(GF_Node *n, Bool pause) typedef struct { GF_AudioInput input; - Bool is_active; + Bool is_active, is_error; MFURL aurl; } SVG_audio_stack; @@ -580,7 +584,7 @@ static void svg_audio_smil_evaluate_ex(SMIL_Timing_RTI *rti, Fixed normalized_sc switch (status) { case SMIL_TIMING_EVAL_UPDATE: - if (!stack->is_active) { + if (!stack->is_active && !stack->is_error) { if (stack->aurl.count) { SVGAllAttributes atts; gf_svg_flatten_attributes((SVG_Element*) (video ? video : audio), &atts); @@ -591,6 +595,8 @@ static void svg_audio_smil_evaluate_ex(SMIL_Timing_RTI *rti, Fixed normalized_sc { gf_mo_set_speed(stack->input.stream, FIX_ONE); stack->is_active = 1; + } else { + stack->is_error = 1; } } } @@ -663,6 +669,8 @@ static void svg_traverse_audio_ex(GF_Node *node, void *rs, Bool is_destroy, SVGP if (stack->is_active) gf_sc_audio_stop(&stack->input); + stack->is_error = 0; + gf_node_dirty_clear(node, GF_SG_SVG_XLINK_HREF_DIRTY); gf_term_get_mfurl_from_xlink(node, &(stack->aurl)); diff --git a/src/compositor/texturing_gl.c b/src/compositor/texturing_gl.c index cee6fa3..300bb44 100644 --- a/src/compositor/texturing_gl.c +++ b/src/compositor/texturing_gl.c @@ -248,7 +248,7 @@ Bool tx_can_use_rect_ext(GF_Compositor *compositor, GF_TextureHandler *txh) static Bool tx_setup_format(GF_TextureHandler *txh) { - Bool is_pow2, use_rect; + Bool is_pow2, use_rect, flip; GF_Compositor *compositor = (GF_Compositor *)txh->compositor; /*in case the ID has been lost, resetup*/ @@ -265,6 +265,7 @@ static Bool tx_setup_format(GF_TextureHandler *txh) txh->tx_io->rescale_width = gf_get_next_pow2(txh->width); txh->tx_io->rescale_height = gf_get_next_pow2(txh->height); + flip = (txh->tx_io->flags & TX_IS_FLIPPED); is_pow2 = ((txh->tx_io->rescale_width==txh->width) && (txh->tx_io->rescale_height==txh->height)) ? 1 : 0; txh->tx_io->flags = TX_IS_POW2; txh->tx_io->gl_type = GL_TEXTURE_2D; @@ -322,9 +323,29 @@ static Bool tx_setup_format(GF_TextureHandler *txh) txh->tx_io->nb_comp = 3; } break; + case GF_PIXEL_YUY2: + if (!use_rect && compositor->emul_pow2) txh->tx_io->flags = TX_EMULE_POW2; + txh->tx_io->gl_format = GL_RGB; + txh->tx_io->nb_comp = 3; + break; + + case GF_PIXEL_YUVD: + if (!use_rect && compositor->emul_pow2) txh->tx_io->flags = TX_EMULE_POW2; + txh->tx_io->gl_format = GL_RGB; + txh->tx_io->nb_comp = 3; + break; + case GF_PIXEL_RGBD: + case GF_PIXEL_RGB_24_DEPTH: + if (!use_rect && compositor->emul_pow2) txh->tx_io->flags = TX_EMULE_POW2; + txh->tx_io->gl_format = GL_RGB; + txh->tx_io->nb_comp = 3; + break; default: return 0; } + + if (flip) txh->tx_io->flags |= TX_IS_FLIPPED; + /*note we don't free the data if existing, since this only happen when re-setting up after context loss (same size)*/ if ((txh->tx_io->flags == TX_MUST_SCALE) & !txh->tx_io->scale_data) { txh->tx_io->scale_data = (char*)gf_malloc(sizeof(char) * txh->tx_io->nb_comp*txh->tx_io->rescale_width*txh->tx_io->rescale_height); @@ -423,18 +444,27 @@ hence is never flipped. Otherwise all textures attached to stream are flipped in Bool gf_sc_texture_convert(GF_TextureHandler *txh) { GF_VideoSurface src, dst; - u32 out_stride, i, bpp; - Bool flip; + u32 out_stride, i, j, bpp; GF_Compositor *compositor = (GF_Compositor *)txh->compositor; + if (!txh->needs_refresh) return 1; + switch (txh->pixelformat) { case GF_PIXEL_ARGB: if (!compositor->gl_caps.bgra_texture) return 0; + goto common; + + case GF_PIXEL_RGBD: + if ((txh->compositor->depth_gl_type==GF_SC_DEPTH_GL_NONE) || (txh->compositor->depth_gl_type==GF_SC_DEPTH_GL_VBO)) { + bpp = 4; + break; + } case GF_PIXEL_GREYSCALE: case GF_PIXEL_ALPHAGREY: case GF_PIXEL_RGB_24: case GF_PIXEL_RGB_32: case GF_PIXEL_RGBA: +common: txh->tx_io->conv_format = txh->pixelformat; txh->tx_io->flags |= TX_NEEDS_HW_LOAD; @@ -445,8 +475,9 @@ Bool gf_sc_texture_convert(GF_TextureHandler *txh) txh->tx_io->conv_data = gf_malloc(sizeof(char)*txh->stride*txh->height); txh->tx_io->conv_format = txh->pixelformat; } - - /*if texture is using RECT extension, flip image manually because +assert(txh->tx_io->conv_data ); +assert(txh->data ); +/*if texture is using RECT extension, flip image manually because texture transforms are not supported in this case ...*/ for (i=0; iheight; i++) { memcpy(txh->tx_io->conv_data + (txh->height - 1 - i) * txh->stride, txh->data + i*txh->stride, txh->stride); @@ -463,6 +494,9 @@ Bool gf_sc_texture_convert(GF_TextureHandler *txh) } bpp = 3; break; + case GF_PIXEL_YUY2: + bpp = 3; + break; case GF_PIXEL_YUVD: bpp = 4; break; @@ -481,6 +515,7 @@ Bool gf_sc_texture_convert(GF_TextureHandler *txh) txh->tx_io->conv_hscale = INT2FIX(txh->height) / txh->tx_io->conv_h; } else { txh->tx_io->conv_data = (char*)gf_malloc(sizeof(char) * bpp * txh->width * txh->height); + memset(txh->tx_io->conv_data, 0, sizeof(char) * bpp * txh->width * txh->height); } } out_stride = bpp * ((txh->tx_io->flags & TX_EMULE_POW2) ? txh->tx_io->conv_w : txh->width); @@ -497,23 +532,56 @@ Bool gf_sc_texture_convert(GF_TextureHandler *txh) dst.pitch_x = 0; dst.pitch_y = out_stride; - flip = 1; + dst.video_buffer = txh->tx_io->conv_data; switch (txh->pixelformat) { + case GF_PIXEL_YUY2: case GF_PIXEL_YV12: txh->tx_io->conv_format = dst.pixel_format = GF_PIXEL_RGB_24; + /*stretch and flip*/ + gf_stretch_bits(&dst, &src, NULL, NULL, 0xFF, 1, NULL, NULL); + txh->flags |= GF_SR_TEXTURE_NO_GL_FLIP; break; case GF_PIXEL_YUVD: - txh->tx_io->conv_format = GF_PIXEL_RGBD; - dst.pixel_format = GF_PIXEL_RGBD; - flip = 0; + if ((txh->compositor->depth_gl_type==GF_SC_DEPTH_GL_NONE) || (txh->compositor->depth_gl_type==GF_SC_DEPTH_GL_VBO)) { + src.pixel_format = GF_PIXEL_YV12; + txh->tx_io->conv_format = GF_PIXEL_RGB_24_DEPTH; + dst.pixel_format = GF_PIXEL_RGB_24; + dst.pitch_y = 3*txh->width; + /*stretch YUV->RGB*/ + gf_stretch_bits(&dst, &src, NULL, NULL, 0xFF, 1, NULL, NULL); + /*copy over Depth plane*/ + memcpy(dst.video_buffer + 3*txh->width*txh->height, txh->data + 3*txh->stride*txh->height/2, txh->width*txh->height); + } else { + txh->tx_io->conv_format = GF_PIXEL_RGBD; + dst.pixel_format = GF_PIXEL_RGBD; + /*stretch*/ + gf_stretch_bits(&dst, &src, NULL, NULL, 0xFF, 0, NULL, NULL); + } + txh->flags |= GF_SR_TEXTURE_NO_GL_FLIP; + break; + case GF_PIXEL_RGBD: + if ((txh->compositor->depth_gl_type==GF_SC_DEPTH_GL_NONE) || (txh->compositor->depth_gl_type==GF_SC_DEPTH_GL_VBO)) { + dst.pitch_y = 3*txh->width; + txh->tx_io->conv_format = GF_PIXEL_RGB_24_DEPTH; + dst.pixel_format = GF_PIXEL_RGB_24; + + for (j=0; jheight; j++) { + u8 *src = txh->data + (txh->height-j-1)*txh->stride; + u8 *dst_p = txh->tx_io->conv_data + j*3*txh->width; + u8 *dst_d = txh->tx_io->conv_data + txh->height*3*txh->width + j*txh->width; + + for (i=0; iwidth; i++) { + *dst_p++ = src[i*4]; + *dst_p++ = src[i*4 + 1]; + *dst_p++ = src[i*4 + 2]; + *dst_d++ = src[i*4 + 3]; + } + } + txh->flags |= GF_SR_TEXTURE_NO_GL_FLIP; + } break; } - dst.video_buffer = txh->tx_io->conv_data; - - /*stretch and flip*/ - gf_stretch_bits(&dst, &src, NULL, NULL, 0xFF, flip, NULL, NULL); txh->tx_io->flags |= TX_NEEDS_HW_LOAD; - txh->tx_io->flags |= TX_IS_FLIPPED; return 1; } @@ -555,19 +623,25 @@ Bool gf_sc_texture_push_image(GF_TextureHandler *txh, Bool generate_mipmaps, Boo /*in case the ID has been lost, resetup*/ if (!txh->tx_io->id) { glGenTextures(1, &txh->tx_io->id); + /*force setup of image*/ + txh->needs_refresh = 1; tx_setup_format(txh); first_load = 1; GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Texturing] Allocating OpenGL texture %d\n", txh->tx_io->id)); } if (!txh->tx_io->gl_type) return 0; - if (txh->tx_io->flags & TX_EMULE_FIRST_LOAD) { - txh->tx_io->flags &= ~TX_EMULE_FIRST_LOAD; - first_load = 1; - } + /*if data not yet ready don't push the texture*/ + if (txh->data) { + + if (txh->tx_io->flags & TX_EMULE_FIRST_LOAD) { + txh->tx_io->flags &= ~TX_EMULE_FIRST_LOAD; + first_load = 1; + } - /*convert image*/ - gf_sc_texture_convert(txh); + /*convert image*/ + gf_sc_texture_convert(txh); + } tx_bind(txh); diff --git a/src/compositor/visual_manager.c b/src/compositor/visual_manager.c index c4d09d3..68509e6 100644 --- a/src/compositor/visual_manager.c +++ b/src/compositor/visual_manager.c @@ -144,7 +144,11 @@ void visual_clean_contexts(GF_VisualManager *visual) ctx->drawable->flags &= ~DRAWABLE_REGISTERED_WITH_VISUAL; if (is_root_visual && (ctx->flags & CTX_HAS_APPEARANCE)) gf_node_dirty_reset(ctx->appear, 0); - + +#ifndef GPAC_DISABLE_3D + /*this may happen when switching a visual from 2D to 3D - discard context*/ + if (visual->type_3d) ctx->drawable=NULL; +#endif ctx = ctx->next; } diff --git a/src/compositor/visual_manager.h b/src/compositor/visual_manager.h index b0bf32b..5cfd8a3 100644 --- a/src/compositor/visual_manager.h +++ b/src/compositor/visual_manager.h @@ -37,17 +37,20 @@ enum { GF_3D_STEREO_NONE = 0, - GF_3D_STEREO_TOP = 1, - GF_3D_STEREO_SIDE = 2, + GF_3D_STEREO_TOP, + GF_3D_STEREO_SIDE, /*all modes above GF_3D_STEREO_SIDE require shaders*/ + /*custom interleaving using GLSL shaders*/ + GF_3D_STEREO_CUSTOM, + /*some built-in interleaving modes*/ /*each pixel correspond to a different view*/ - GF_3D_STEREO_COLUMNS = 3, - GF_3D_STEREO_ROWS = 4, + GF_3D_STEREO_COLUMNS, + GF_3D_STEREO_ROWS, /*special case of sub-pixel interleaving for 2 views*/ - GF_3D_STEREO_ANAGLYPH = 5, - /*custom interleaving using GLSL shaders*/ - GF_3D_STEREO_CUSTOM = 6, + GF_3D_STEREO_ANAGLYPH, + /*SpatialView 19'' 5views interleaving*/ + GF_3D_STEREO_5VSP19, }; enum @@ -151,6 +154,12 @@ struct _visual_manager * Visual Manager part for 3D drawing */ +#if defined( _LP64 ) && defined(CONFIG_DARWIN_GL) +#define GF_SHADERID u64 +#else +#define GF_SHADERID u32 +#endif + #ifndef GPAC_DISABLE_VRML /*navigation stack*/ GF_List *navigation_stack; @@ -178,9 +187,9 @@ struct _visual_manager u32 *gl_textures; u32 auto_stereo_width, auto_stereo_height; GF_Mesh *autostereo_mesh; - u32 glsl_program; - u32 glsl_vertex; - u32 glsl_fragment; + GF_SHADERID glsl_program; + GF_SHADERID glsl_vertex; + GF_SHADERID glsl_fragment; #endif #ifdef GF_SR_USE_DEPTH diff --git a/src/compositor/visual_manager_2d.c b/src/compositor/visual_manager_2d.c index cf1395a..b1e0302 100644 --- a/src/compositor/visual_manager_2d.c +++ b/src/compositor/visual_manager_2d.c @@ -130,6 +130,7 @@ void visual_2d_remove_last_context(GF_VisualManager *visual) void visual_2d_drawable_delete(GF_VisualManager *visual, struct _drawable *drawable) { + DrawableContext *ctx; /*remove drawable from visual list*/ struct _drawable_store *it = visual->prev_nodes; struct _drawable_store *prev = NULL; @@ -145,6 +146,16 @@ void visual_2d_drawable_delete(GF_VisualManager *visual, struct _drawable *drawa gf_free(it); break; } + + ctx = visual->context; + while (ctx && ctx->drawable) { + /*remove visual registration flag*/ + if (ctx->drawable == drawable) { + ctx->flags = 0; + ctx->drawable = NULL; + } + ctx = ctx->next; + } if (drawable->flags & DRAWABLE_IS_OVERLAY) { visual->compositor->video_out->Blit(visual->compositor->video_out, NULL, NULL, NULL, 1); } diff --git a/src/compositor/visual_manager_2d_draw.c b/src/compositor/visual_manager_2d_draw.c index 2ec80b6..9bc86d3 100644 --- a/src/compositor/visual_manager_2d_draw.c +++ b/src/compositor/visual_manager_2d_draw.c @@ -358,22 +358,25 @@ void visual_2d_texture_path_extended(GF_VisualManager *visual, GF_Path *path, GF if (txh->flags & GF_SR_TEXTURE_PRIVATE_MEDIA) { GF_Window src, dst; - - - /*no aa*/ -// visual_2d_set_options(visual->compositor, visual->raster_surface, 0, 1); - - /*set matrix*/ -// raster->surface_set_matrix(visual->raster_surface, &ctx->transform); - - /*push path*/ -// raster->surface_set_path(visual->raster_surface, ctx->drawable->path); - /*using NULL will clear the clip rect with color 0x00000000*/ visual_2d_fill_path(visual, ctx, NULL, tr_state); -// raster->surface_set_path(visual->raster_surface, NULL); - if (compositor_texture_rectangles(visual, txh, &ctx->bi->clip, &ctx->bi->unclip, &src, &dst, NULL, NULL)) - gf_mo_set_position(txh->stream, &src, &dst); + /*if texture not ready, update the size before computing output rectangles */ + if (!txh->width || !txh->height) { + gf_mo_get_visual_info(txh->stream, &txh->width, &txh->height, &txh->stride, &txh->pixel_ar, &txh->pixelformat); + /*in case the node is an MPEG-4 bitmap, force stack rebuild at next frame */ + gf_node_dirty_set(ctx->drawable->node, GF_SG_NODE_DIRTY, 1); + } + + if (compositor_texture_rectangles(visual, txh, &ctx->bi->clip, &ctx->bi->unclip, &src, &dst, NULL, NULL)) { + if (txh->stream && gf_mo_set_position(txh->stream, &src, &dst)) { + gf_mo_get_visual_info(txh->stream, &txh->width, &txh->height, &txh->stride, &txh->pixel_ar, &txh->pixelformat); + /*force dirty flag to get called again*/ + gf_node_dirty_set(ctx->drawable->node, GF_SG_NODE_DIRTY, 1); + gf_sc_next_frame_state(visual->compositor, GF_SC_DRAW_FRAME); + } + } + + return; } diff --git a/src/compositor/visual_manager_3d.c b/src/compositor/visual_manager_3d.c index f54297b..9f537ef 100644 --- a/src/compositor/visual_manager_3d.c +++ b/src/compositor/visual_manager_3d.c @@ -295,7 +295,7 @@ void visual_3d_viewpoint_change(GF_TraverseState *tr_state, GF_Node *vp, Bool an gf_sc_invalidate(tr_state->visual->compositor, NULL); } -void visual_3d_setup_projection(GF_TraverseState *tr_state) +void visual_3d_setup_projection(GF_TraverseState *tr_state, Bool is_layer) { #ifndef GPAC_DISABLE_VRML GF_Node *bindable; @@ -340,7 +340,7 @@ void visual_3d_setup_projection(GF_TraverseState *tr_state) camera_stop_anim(tr_state->camera); camera_reset_viewpoint(tr_state->camera, 0); /*scene not yet ready, force a recompute of world bounds at next frame*/ - if (gf_sc_fit_world_to_screen(tr_state->visual->compositor) == 0) { + if (!is_layer && gf_sc_fit_world_to_screen(tr_state->visual->compositor) == 0) { tr_state->camera->had_viewpoint = 2; } } @@ -464,6 +464,7 @@ void visual_3d_init_draw(GF_TraverseState *tr_state, u32 layer_type) #ifndef GPAC_DISABLE_VRML GF_Node *bindable; #endif + Bool off_axis_background = (tr_state->camera->is_3D && (tr_state->visual->camera_layout==GF_3D_CAMERA_OFFAXIS)) ? 1 : 0; /*if not in layer, traverse navigation node FIXME: we should update the nav info according to the world transform at the current viewpoint (vrml)*/ @@ -495,8 +496,9 @@ void visual_3d_init_draw(GF_TraverseState *tr_state, u32 layer_type) } #ifdef GF_SR_USE_DEPTH - if (tr_state->visual->compositor->display_depth) +/* if (tr_state->visual->compositor->display_depth) tr_state->camera->navigate_mode = GF_NAVIGATE_NONE; +*/ #endif } else { tr_state->camera->navigate_mode = GF_NAVIGATE_NONE; @@ -535,12 +537,12 @@ void visual_3d_init_draw(GF_TraverseState *tr_state, u32 layer_type) visual_3d_set_viewport(tr_state->visual, tr_state->camera->vp); visual_3d_set_scissor(tr_state->visual, &tr_state->camera->vp); - if (tr_state->visual->camera_layout==GF_3D_CAMERA_OFFAXIS) { + if (off_axis_background) { visual_3d_draw_background_on_axis(tr_state, layer_type); } /*setup projection*/ - visual_3d_setup_projection(tr_state); + visual_3d_setup_projection(tr_state, layer_type); tr_state->camera->vp = orig_vp; } else if (tr_state->visual->autostereo_type==GF_3D_STEREO_TOP) { @@ -549,35 +551,39 @@ void visual_3d_init_draw(GF_TraverseState *tr_state, u32 layer_type) tr_state->camera->vp.height /= tr_state->visual->nb_views; tr_state->camera->vp.y += tr_state->visual->current_view * tr_state->camera->vp.height; - tr_state->camera->vp.y = orig_vp.height - tr_state->camera->vp.height - tr_state->camera->vp.y; +// tr_state->camera->vp.y = orig_vp.height - tr_state->camera->vp.height - tr_state->camera->vp.y; + if (tr_state->visual->compositor->visual==tr_state->visual) + tr_state->camera->vp.y = tr_state->visual->compositor->output_height - tr_state->camera->vp.y - tr_state->camera->vp.height; + else + tr_state->camera->vp.y = tr_state->visual->height - tr_state->camera->vp.y - tr_state->camera->vp.height; visual_3d_set_viewport(tr_state->visual, tr_state->camera->vp); visual_3d_set_scissor(tr_state->visual, &tr_state->camera->vp); - if (tr_state->visual->camera_layout==GF_3D_CAMERA_OFFAXIS) { + if (off_axis_background) { visual_3d_draw_background_on_axis(tr_state, layer_type); } /*setup projection*/ - visual_3d_setup_projection(tr_state); + visual_3d_setup_projection(tr_state, layer_type); tr_state->camera->vp = orig_vp; } else { visual_3d_set_viewport(tr_state->visual, tr_state->camera->vp); - if (tr_state->visual->camera_layout==GF_3D_CAMERA_OFFAXIS) { + if (off_axis_background) { visual_3d_draw_background_on_axis(tr_state, layer_type); } /*setup projection*/ - visual_3d_setup_projection(tr_state); + visual_3d_setup_projection(tr_state, layer_type); if (tr_state->visual->autostereo_type) { visual_3d_clear_depth(tr_state->visual); } } /*regular background draw*/ - if (tr_state->visual->camera_layout != GF_3D_CAMERA_OFFAXIS) { + if (!tr_state->camera->is_3D || tr_state->visual->camera_layout != GF_3D_CAMERA_OFFAXIS) { visual_3d_draw_background(tr_state, layer_type); } @@ -1011,7 +1017,7 @@ void visual_3d_check_collisions(GF_TraverseState *tr_state, GF_ChildNodeItem *no GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Collision] no collision found\n")); } - if (tr_state->camera->flags & CAM_IS_DIRTY) visual_3d_setup_projection(tr_state); + if (tr_state->camera->flags & CAM_IS_DIRTY) visual_3d_setup_projection(tr_state, 0); } /*uncomment to disable frustum cull*/ @@ -1059,12 +1065,14 @@ Bool visual_3d_node_cull(GF_TraverseState *tr_state, GF_BBox *bbox, Bool skip_ne return 1; } /*first check: sphere vs frustum sphere intersection, this will discard far objects quite fast*/ - gf_vec_diff(cdiff, cam->center, b.center); - rad = b.radius + cam->radius; - if (gf_vec_len(cdiff) > rad) { - tr_state->cull_flag = CULL_OUTSIDE; - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Culling] Node out (sphere-sphere test)\n")); - return 0; + if (tr_state->camera->is_3D) { + gf_vec_diff(cdiff, cam->center, b.center); + rad = b.radius + cam->radius; + if (gf_vec_len(cdiff) > rad) { + tr_state->cull_flag = CULL_OUTSIDE; + GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Culling] Node out (sphere-sphere test)\n")); + return 0; + } } /*second check: sphere vs frustum planes intersection, if any intersection is detected switch @@ -1129,7 +1137,7 @@ void visual_3d_pick_node(GF_VisualManager *visual, GF_TraverseState *tr_state, G SFVec4f res; visual_3d_setup_traversing_state(visual, tr_state); - visual_3d_setup_projection(tr_state); + visual_3d_setup_projection(tr_state, 0); x = INT2FIX(ev->mouse.x); y = INT2FIX(ev->mouse.y); diff --git a/src/compositor/visual_manager_3d.h b/src/compositor/visual_manager_3d.h index 0e5f60c..545a248 100644 --- a/src/compositor/visual_manager_3d.h +++ b/src/compositor/visual_manager_3d.h @@ -98,7 +98,7 @@ void visual_3d_check_collisions(GF_TraverseState *tr_state, GF_ChildNodeItem *no */ void visual_3d_init_draw(GF_TraverseState *tr_state, u32 layer_type); /*setup projection - exported for Layer3D */ -void visual_3d_setup_projection(GF_TraverseState *tr_state); +void visual_3d_setup_projection(GF_TraverseState *tr_state, Bool is_layer); /*base 3D drawable*/ diff --git a/src/compositor/visual_manager_3d_gl.c b/src/compositor/visual_manager_3d_gl.c index 88d6dd8..1269908 100644 --- a/src/compositor/visual_manager_3d_gl.c +++ b/src/compositor/visual_manager_3d_gl.c @@ -28,6 +28,7 @@ #ifndef GPAC_DISABLE_3D #include +#include #include "gl_inc.h" #if (defined(WIN32) || defined(_WIN32_WCE)) && !defined(__GNUC__) @@ -80,6 +81,7 @@ GLDECL_STATIC(glGenBuffers); GLDECL_STATIC(glDeleteBuffers); GLDECL_STATIC(glBindBuffer); GLDECL_STATIC(glBufferData); +GLDECL_STATIC(glBufferSubData); #endif //LOAD_GL_1_3 @@ -135,7 +137,7 @@ GLDECL_STATIC(glBlendEquation); #endif //LOAD_GL_2_0 -void gf_sc_load_opengl_extensions(GF_Compositor *compositor) +void gf_sc_load_opengl_extensions(GF_Compositor *compositor, Bool has_gl_context) { Bool has_shaders = 0; #ifdef GPAC_USE_TINYGL @@ -185,7 +187,7 @@ void gf_sc_load_opengl_extensions(GF_Compositor *compositor) } #endif - if (!compositor->visual->type_3d) return; + if (!has_gl_context) return; /*we have a GL context, get proc addresses*/ @@ -199,6 +201,7 @@ void gf_sc_load_opengl_extensions(GF_Compositor *compositor) GET_GLFUN(glDeleteBuffers); GET_GLFUN(glBindBuffer); GET_GLFUN(glBufferData); + GET_GLFUN(glBufferSubData); } #endif @@ -289,6 +292,7 @@ static char *default_glsl_vertex = "\ gl_TexCoord[0] = gl_MultiTexCoord0;\ }"; +#ifdef GPAC_UNUSED_FUNC static char *default_glsl_lighting = "\ varying vec3 gfNormal;\ varying vec3 gfView;\ @@ -304,6 +308,7 @@ static char *default_glsl_lighting = "\ Ispec = clamp(Ispec, 0.0, 1.0);\ gl_FragColor = gl_FrontLightModelProduct.sceneColor + Iamb + Idiff + Ispec;\ }"; +#endif /*GPAC_UNUSED_FUNC*/ static char *glsl_view_anaglyph = "\ uniform sampler2D gfView1;\ @@ -317,6 +322,7 @@ static char *glsl_view_anaglyph = "\ gl_FragColor.b = col2.b;\ }"; +#ifdef GPAC_UNUSED_FUNC static char *glsl_view_anaglyph_optimize = "\ uniform sampler2D gfView1;\ uniform sampler2D gfView2;\ @@ -329,6 +335,7 @@ static char *glsl_view_anaglyph_optimize = "\ gl_FragColor.g = col2.g;\ gl_FragColor.b = col2.b;\ }"; +#endif /*GPAC_UNUSED_FUNC*/ static char *glsl_view_columns = "\ uniform sampler2D gfView1;\ @@ -352,8 +359,33 @@ static char *glsl_view_rows = "\ gl_FragColor = texture2D(gfView2, gl_TexCoord[0].st); \ }"; +static char *glsl_view_5VSP19 = "\ + uniform sampler2D gfView1;\ + uniform sampler2D gfView2;\ + uniform sampler2D gfView3;\ + uniform sampler2D gfView4;\ + uniform sampler2D gfView5;\ + void main(void) {\ + vec4 color[5];\ + color[0] = texture2D(gfView5, gl_TexCoord[0].st);\ + color[1] = texture2D(gfView4, gl_TexCoord[0].st);\ + color[2] = texture2D(gfView3, gl_TexCoord[0].st);\ + color[3] = texture2D(gfView2, gl_TexCoord[0].st);\ + color[4] = texture2D(gfView1, gl_TexCoord[0].st);\ + float pitch = 5.0 + 1.0 - mod(gl_FragCoord.y , 5.0);\ + int col = int( mod(pitch + 3.0 * (gl_FragCoord.x), 5.0 ) );\ + int Vr = int(col);\ + int Vg = int(col) + 1;\ + int Vb = int(col) + 2;\ + if (Vg >= 5) Vg -= 5;\ + if (Vb >= 5) Vb -= 5;\ + gl_FragColor.r = color[Vr].r;\ + gl_FragColor.g = color[Vg].g;\ + gl_FragColor.b = color[Vb].b;\ + }"; -Bool visual_3d_compile_shader(u32 shader_id, const char *name, const char *source) + +Bool visual_3d_compile_shader(GF_SHADERID shader_id, const char *name, const char *source) { GLint blen = 0; GLsizei slen = 0; @@ -380,7 +412,11 @@ Bool visual_3d_compile_shader(u32 shader_id, const char *name, const char *sourc void visual_3d_init_shaders(GF_VisualManager *visual) { +/* This test creates a compilation warning under MacOS since always defined, should now compile with -Wall -Werror */ +#if (defined(GL_VERSION_2_0) && defined(GL_GLEXT_PROTOTYPES)) || defined(CONFIG_DARWIN_GL) +#else if (!glCreateProgram) return; +#endif /* for Linux w/ OpenGL 2 + CONFIG_DARWIN_GL ... */ if (visual->glsl_program) return; @@ -402,6 +438,10 @@ void visual_3d_init_shaders(GF_VisualManager *visual) visual->glsl_fragment = glCreateShader(GL_FRAGMENT_SHADER); visual_3d_compile_shader(visual->glsl_fragment, "fragment", glsl_view_anaglyph); break; + case GF_3D_STEREO_5VSP19: + visual->glsl_fragment = glCreateShader(GL_FRAGMENT_SHADER); + visual_3d_compile_shader(visual->glsl_fragment, "fragment", glsl_view_5VSP19); + break; case GF_3D_STEREO_CUSTOM: { const char *sOpt = gf_cfg_get_key(visual->compositor->user->config, "Compositor", "InterleaverShader"); @@ -496,7 +536,7 @@ GF_Err visual_3d_init_autostereo(GF_VisualManager *visual) mesh_new_rectangle(visual->autostereo_mesh, s, NULL, 0); // mesh_new_ellipse(visual->autostereo_mesh, s.x, s.y, 0); - fprintf(stdout, "AutoStereo initialized - width %d height %d\n",visual->auto_stereo_width, visual->auto_stereo_height); + GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual3D] AutoStereo initialized - width %d height %d\n", visual->auto_stereo_width, visual->auto_stereo_height) ); visual_3d_init_shaders(visual); #endif // !defined(GPAC_USE_TINYGL) && !defined(GPAC_USE_OGL_ES) @@ -826,22 +866,25 @@ void VS3D_DrawMeshIntern(GF_TraverseState *tr_state, GF_Mesh *mesh) Float fix_scale = 1.0f; fix_scale /= FIX_ONE; #endif - + has_col = has_tx = has_norm = 0; - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[V3D] Drawing mesh 0x%08x\n", mesh)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[V3D] Drawing mesh %p\n", mesh)); if ((compositor->reset_graphics==2) && mesh->vbo) { /*we lost OpenGL context at previous frame, recreate VBO*/ mesh->vbo = 0; } - if (!mesh->vbo && compositor->gl_caps.vbo) { + /*rebuild VBO for large ojects only (we basically filter quads out)*/ + if ((mesh->v_count>4) && !mesh->vbo && compositor->gl_caps.vbo) { glGenBuffers(1, &mesh->vbo); if (mesh->vbo) { glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo); - glBufferData(GL_ARRAY_BUFFER, mesh->v_count * sizeof(GF_Vertex) , mesh->vertices, GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, mesh->v_count * sizeof(GF_Vertex) , mesh->vertices, (mesh->vbo_dynamic) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); + mesh->vbo_dirty = 0; } } + if (mesh->vbo) { base_address = NULL; glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo); @@ -849,6 +892,11 @@ void VS3D_DrawMeshIntern(GF_TraverseState *tr_state, GF_Mesh *mesh) base_address = & mesh->vertices[0].pos; } + if (mesh->vbo_dirty) { + glBufferSubData(GL_ARRAY_BUFFER, 0, mesh->v_count * sizeof(GF_Vertex) , mesh->vertices); + mesh->vbo_dirty = 0; + } + glEnableClientState(GL_VERTEX_ARRAY); #if defined(GPAC_USE_OGL_ES) glVertexPointer(3, GL_FIXED, sizeof(GF_Vertex), base_address); @@ -2219,24 +2267,62 @@ GF_Err compositor_3d_release_screen_buffer(GF_Compositor *compositor, GF_VideoSu return GF_OK; } +GF_Err compositor_3d_get_offscreen_buffer(GF_Compositor *compositor, GF_VideoSurface *fb, u32 view_idx, u32 depth_dump_mode) +{ +#if !defined(GPAC_USE_OGL_ES) && !defined(GPAC_USE_TINYGL) + char *tmp; + u32 hy, i; + /*not implemented yet*/ + if (depth_dump_mode) return GF_NOT_SUPPORTED; + + if (view_idx>=compositor->visual->nb_views) return GF_BAD_PARAM; + fb->width = compositor->visual->auto_stereo_width; + fb->height = compositor->visual->auto_stereo_height; + fb->pixel_format = GF_PIXEL_RGB_24; + fb->pitch_y = 3*fb->width; + fb->video_buffer = gf_malloc(sizeof(char)*3*fb->width*fb->height); + if (!fb->video_buffer) return GF_OUT_OF_MEM; + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, compositor->visual->gl_textures[view_idx]); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, fb->video_buffer); + glDisable(GL_TEXTURE_2D); + + /*flip image (openGL always handle image data bottom to top) */ + tmp = (char*)gf_malloc(sizeof(char)*fb->pitch_y); + hy = fb->height/2; + for (i=0; ivideo_buffer+ i*fb->pitch_y, fb->pitch_y); + memcpy(fb->video_buffer + i*fb->pitch_y, fb->video_buffer + (fb->height - 1 - i) * fb->pitch_y, fb->pitch_y); + memcpy(fb->video_buffer + (fb->height - 1 - i) * fb->pitch_y, tmp, fb->pitch_y); + } + gf_free(tmp); + return GF_OK; +#else + return GF_NOT_SUPPORTED; +#endif +} + void visual_3d_point_sprite(GF_VisualManager *visual, Drawable *stack, GF_TextureHandler *txh, GF_TraverseState *tr_state) { #if !defined(GPAC_USE_OGL_ES) && !defined(GPAC_USE_TINYGL) u32 w, h; u32 pixel_format, stride; u8 *data; - Float r, g, b, x, y; + Float r, g, b; + Fixed x, y; Float inc, scale; Bool in_strip; Float delta = 0; Bool first_pass = 2; - if ((visual->compositor->depth_gl_type==1) && visual->compositor->gl_caps.point_sprite) { + if ((visual->compositor->depth_gl_type==GF_SC_DEPTH_GL_POINTS) && visual->compositor->gl_caps.point_sprite) { Float z; static GLfloat none[3] = { 1.0f, 0, 0 }; data = gf_sc_texture_get_data(txh, &pixel_format); if (!data) return; + if (pixel_format!=GF_PIXEL_RGBD) return; stride = txh->stride; if (txh->pixelformat==GF_PIXEL_YUVD) stride *= 4; @@ -2248,7 +2334,7 @@ void visual_3d_point_sprite(GF_VisualManager *visual, Drawable *stack, GF_Textur glEnable(GL_POINT_SMOOTH); glDisable(GL_LIGHTING); - scale = visual->compositor->depth_gl_scale; + scale = FIX2FLT(visual->compositor->depth_gl_scale); inc = 1; if (!tr_state->pixel_metrics) inc /= tr_state->min_hsize; x = 0; @@ -2278,104 +2364,166 @@ void visual_3d_point_sprite(GF_VisualManager *visual, Drawable *stack, GF_Textur return; } - delta = visual->compositor->depth_gl_strips_filter; - if (!delta) first_pass = 2; - else first_pass = 1; + if (visual->compositor->depth_gl_type==GF_SC_DEPTH_GL_STRIPS) { + delta = visual->compositor->depth_gl_strips_filter; + if (!delta) first_pass = 2; + else first_pass = 1; - data = gf_sc_texture_get_data(txh, &pixel_format); - if (!data) return; - stride = txh->stride; - if (txh->pixelformat==GF_PIXEL_YUVD) stride *= 4; + data = gf_sc_texture_get_data(txh, &pixel_format); + if (!data) return; + if (pixel_format!=GF_PIXEL_RGBD) return; + stride = txh->stride; + if (txh->pixelformat==GF_PIXEL_YUVD) stride *= 4; - glDepthMask(GL_FALSE); - glDisable(GL_TEXTURE_2D); - glDisable(GL_LIGHTING); - glDisable(GL_BLEND); - glDisable(GL_CULL_FACE); - glDisable(GL_POINT_SMOOTH); - glDisable(GL_FOG); + glDepthMask(GL_FALSE); + glDisable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + glDisable(GL_BLEND); + glDisable(GL_CULL_FACE); + glDisable(GL_POINT_SMOOTH); + glDisable(GL_FOG); restart: - scale = 50; - inc = 1; - if (!tr_state->pixel_metrics) inc /= tr_state->min_hsize; - x = 0; - y = 1; y*=txh->height/2; - if (!tr_state->pixel_metrics) y /= tr_state->min_hsize; - - in_strip = 0; - for (h=0; hheight - 1; h++) { - char *src = data + h*stride; - x = -1; x *= txh->width/2; - if (!tr_state->pixel_metrics) x /= tr_state->min_hsize; - - for (w=0; wwidth; w++) { - u8 *p1 = src + w*4; - u8 *p2 = src + w*4 + stride; - Float z1 = p1[3]; - Float z2 = p2[3]; - if (first_pass==1) { - if ((z1>delta) || (z2>delta)) - { - if (0 && in_strip) { - glEnd(); - in_strip = 0; + scale = FIX2FLT(visual->compositor->depth_gl_scale); + inc = 1; + if (!tr_state->pixel_metrics) inc /= tr_state->min_hsize; + x = 0; + y = 1; y*=txh->height/2; + if (!tr_state->pixel_metrics) y /= tr_state->min_hsize; + + in_strip = 0; + for (h=0; hheight - 1; h++) { + char *src = data + h*stride; + x = -1; x *= txh->width/2; + if (!tr_state->pixel_metrics) x /= tr_state->min_hsize; + + for (w=0; wwidth; w++) { + u8 *p1 = src + w*4; + u8 *p2 = src + w*4 + stride; + Float z1 = p1[3]; + Float z2 = p2[3]; + if (first_pass==1) { + if ((z1>delta) || (z2>delta)) + { + if (0 && in_strip) { + glEnd(); + in_strip = 0; + } + x += inc; + continue; } - x += inc; - continue; - } - } else if (first_pass==0) { - if ((z1<=delta) || (z2<=delta)) - { - if (in_strip) { - glEnd(); - in_strip = 0; + } else if (first_pass==0) { + if ((z1<=delta) || (z2<=delta)) + { + if (in_strip) { + glEnd(); + in_strip = 0; + } + x += inc; + continue; } - x += inc; - continue; } + z1 = z1 / 255; + z2 = z2 / 255; + + r = p1[0]; + r /= 255; + g = p1[1]; + g /= 255; + b = p1[2]; + b /= 255; + + if (!in_strip) { + glBegin(GL_TRIANGLE_STRIP); + in_strip = 1; + } + + glColor3f(r, g, b); + glVertex3f(x, y, z1*scale); + + r = p2[0]; + r /= 255; + g = p2[1]; + g /= 255; + b = p2[2]; + b /= 255; + + glColor3f(r, g, b); + glVertex3f(x, y-inc, z2*scale); + + x += inc; } - z1 = z1 / 255; - z2 = z2 / 255; - - r = p1[0]; - r /= 255; - g = p1[1]; - g /= 255; - b = p1[2]; - b /= 255; - - if (!in_strip) { - glBegin(GL_TRIANGLE_STRIP); - in_strip = 1; + if (in_strip) { + glEnd(); + in_strip = 0; } + y -= inc; + } + + if (first_pass==1) { + first_pass = 0; + goto restart; + } + return; + } - glColor3f(r, g, b); - glVertex3f(x, y, z1*scale); + glColor3f(1.0, 0.0, 0.0); + /*render using vertex array*/ + if (!stack->mesh) { + stack->mesh = new_mesh(); + stack->mesh->vbo_dynamic = 1; + inc = 1; + if (!tr_state->pixel_metrics) inc /= tr_state->min_hsize; + x = 0; + y = 1; y*=txh->height/2; + if (!tr_state->pixel_metrics) y /= tr_state->min_hsize; - r = p2[0]; - r /= 255; - g = p2[1]; - g /= 255; - b = p2[2]; - b /= 255; + for (h=0; hheight; h++) { + u32 idx_offset = h ? ((h-1)*txh->width) : 0; + x = -1; x *= txh->width/2; + if (!tr_state->pixel_metrics) x /= tr_state->min_hsize; - glColor3f(r, g, b); - glVertex3f(x, y-inc, z2*scale); + for (w=0; wwidth; w++) { + mesh_set_vertex(stack->mesh, x, y, 0, 0, 0, -FIX_ONE, INT2FIX(w) / (txh->width-1), INT2FIX(txh->height - h -1) / (txh->height-1) ); + x += inc; - x += inc; - } - if (in_strip) { - glEnd(); - in_strip = 0; + /*set triangle*/ + if (h && w) { + u32 first_idx = idx_offset + w - 1; + mesh_set_triangle(stack->mesh, first_idx, first_idx+1, txh->width + first_idx +1); + mesh_set_triangle(stack->mesh, first_idx, txh->width + first_idx, txh->width + first_idx +1); + } + } + y -= inc; } - y -= inc; + /*force recompute of Z*/ + txh->needs_refresh = 1; } - if (first_pass==1) { - first_pass = 0; - goto restart; + /*texture has been updated, recompute Z*/ + if (txh->needs_refresh) { + Fixed f_scale = FLT2FIX(visual->compositor->depth_gl_scale); + txh->needs_refresh = 0; + + data = gf_sc_texture_get_data(txh, &pixel_format); + if (!data) return; + if (pixel_format!=GF_PIXEL_RGB_24_DEPTH) return; + data += txh->height*txh->width*3; + + for (h=0; hheight; h++) { + char *src = data + h * txh->width; + for (w=0; wwidth; w++) { + u8 d = src[w]; + Fixed z = INT2FIX(d); + z = gf_mulfix(z / 255, f_scale); + stack->mesh->vertices[w + h*txh->width].pos.z = z; + } + } + stack->mesh->vbo_dirty = 1; } + tr_state->mesh_num_textures = gf_sc_texture_enable(txh, ((M_Appearance *)tr_state->appear)->textureTransform); + VS3D_DrawMeshIntern(tr_state, stack->mesh); + visual_3d_disable_texture(tr_state); #endif //GPAC_USE_OGL_ES diff --git a/src/export.cpp b/src/export.cpp index 537e041..a6dd179 100644 --- a/src/export.cpp +++ b/src/export.cpp @@ -57,6 +57,7 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_log_get_level) ) #pragma comment (linker, EXPORT_SYMBOL(gf_log_set_level) ) #pragma comment (linker, EXPORT_SYMBOL(gf_log_set_tools) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_log_set_strict_error) ) #pragma comment (linker, EXPORT_SYMBOL(gf_log_set_callback) ) #pragma comment (linker, EXPORT_SYMBOL(gf_log_parse_level) ) #pragma comment (linker, EXPORT_SYMBOL(gf_log_parse_tools) ) @@ -105,7 +106,6 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_ringbuffer_new) ) #pragma comment (linker, EXPORT_SYMBOL(gf_ringbuffer_read) ) #pragma comment (linker, EXPORT_SYMBOL(gf_ringbuffer_write) ) -#pragma comment (linker, EXPORT_SYMBOL(gf_global_resource_lock) ) #pragma comment (linker, EXPORT_SYMBOL(gf_ringbuffer_available_for_read ) ) #pragma comment (linker, EXPORT_SYMBOL(gf_ringbuffer_del) ) @@ -224,6 +224,7 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_token_get_line) ) #pragma comment (linker, EXPORT_SYMBOL(gf_token_find) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cfg_init) ) #pragma comment (linker, EXPORT_SYMBOL(gf_cfg_new) ) #pragma comment (linker, EXPORT_SYMBOL(gf_cfg_del) ) #pragma comment (linker, EXPORT_SYMBOL(gf_cfg_remove) ) @@ -237,6 +238,7 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_cfg_get_key_name) ) #pragma comment (linker, EXPORT_SYMBOL(gf_cfg_insert_key) ) #pragma comment (linker, EXPORT_SYMBOL(gf_cfg_del_section) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cfg_get_filename) ) #pragma comment (linker, EXPORT_SYMBOL(gf_modules_new) ) @@ -267,12 +269,13 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_get_stats) ) #pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_fetch_data) ) #pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_last_error) ) -#pragma comment (linker, EXPORT_SYMBOL(gf_dm_setup_from_url) ) #pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_get_resource_name) ) #pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_reset) ) #pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_mime_type) ) #pragma comment (linker, EXPORT_SYMBOL(gf_dm_new) ) #pragma comment (linker, EXPORT_SYMBOL(gf_dm_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dm_set_data_rate) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dm_get_data_rate) ) #pragma comment (linker, EXPORT_SYMBOL(gf_cache_get_url) ) #pragma comment (linker, EXPORT_SYMBOL(gf_cache_get_cache_filename) ) #pragma comment (linker, EXPORT_SYMBOL(gf_cache_create_entry) ) @@ -290,6 +293,10 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_dm_url_info_init) ) #pragma comment (linker, EXPORT_SYMBOL(gf_dm_is_thread_dead) ) #pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_abort) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_set_range) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_setup_from_url) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dm_get_file_memory) ) + #pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_can_be_cached_on_disk) ) #pragma comment (linker, EXPORT_SYMBOL(gf_dm_wget) ) @@ -540,7 +547,11 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_isom_delete) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_mode) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_file_size) ) - +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_timed_meta_data_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_box_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_box_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_box_write) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_box_size) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_open_progressive) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_missing_bytes) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_is_fragmented) ) @@ -579,6 +590,8 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_sample_for_movie_time) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_sample_dts) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_sample_duration) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_sample_size) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_sample_sync) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_edit_segment_count) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_edit_segment) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_copyright_count) ) @@ -594,6 +607,7 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_decoder_config) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_reference_count) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_reference) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_has_track_reference) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_filename) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_brand_info) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_alternate_brand) ) @@ -646,6 +660,8 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_next_alternate_group_id) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_meta_primary_item_id) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_is_JPEG2000) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_rvc_config) ) + # ifndef GPAC_DISABLE_ISOM_DUMP #pragma comment (linker, EXPORT_SYMBOL(gf_isom_dump) ) @@ -781,6 +797,7 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_isom_estimate_size) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_meta_type) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_add_meta_item) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_add_meta_item_memory) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_remove_meta_item) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_meta_primary_item) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_meta_xml) ) @@ -797,6 +814,7 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_alternate_group_id) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_new_dims_description) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_update_dims_description) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_rvc_config) ) #ifndef GPAC_DISABLE_ISOM_HINTING #pragma comment (linker, EXPORT_SYMBOL(gf_isom_setup_hint_track) ) #pragma comment (linker, EXPORT_SYMBOL(gf_isom_new_hint_description) ) @@ -869,6 +887,7 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_term_on_command) ) #pragma comment (linker, EXPORT_SYMBOL(gf_term_on_sl_packet) ) #pragma comment (linker, EXPORT_SYMBOL(gf_term_get_service_url) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_on_service_event) ) #pragma comment (linker, EXPORT_SYMBOL(gf_term_add_media) ) #pragma comment (linker, EXPORT_SYMBOL(gf_term_get_service_interface) ) #pragma comment (linker, EXPORT_SYMBOL(gf_term_register_mime_type) ) @@ -880,12 +899,15 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_term_process_step) ) #pragma comment (linker, EXPORT_SYMBOL(gf_term_get_screen_buffer) ) #pragma comment (linker, EXPORT_SYMBOL(gf_term_release_screen_buffer) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_offscreen_buffer) ) #pragma comment (linker, EXPORT_SYMBOL(gf_term_process_shortcut) ) #pragma comment (linker, EXPORT_SYMBOL(gf_term_set_speed) ) #pragma comment (linker, EXPORT_SYMBOL(gf_term_relocate_url) ) #pragma comment (linker, EXPORT_SYMBOL(gf_term_add_event_filter) ) #pragma comment (linker, EXPORT_SYMBOL(gf_term_remove_event_filter) ) #pragma comment (linker, EXPORT_SYMBOL(gf_term_lock_media_queue) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_current_service_id) ) + /*ietf.h exports*/ #ifndef GPAC_DISABLE_STREAMING @@ -1017,6 +1039,7 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_media_change_par) ) #pragma comment (linker, EXPORT_SYMBOL(gf_media_change_pl) ) #pragma comment (linker, EXPORT_SYMBOL(gf_media_fragment_file) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_media_avc_rewrite_samples) ) #endif /*GPAC_DISABLE_MEDIA_IMPORT*/ @@ -1213,6 +1236,7 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_node_get_graph) ) #pragma comment (linker, EXPORT_SYMBOL(gf_node_init) ) #pragma comment (linker, EXPORT_SYMBOL(gf_node_get_scene_time) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_in_table_by_tag) ) #pragma comment (linker, EXPORT_SYMBOL(gf_sg_new) ) #pragma comment (linker, EXPORT_SYMBOL(gf_sg_new_subscene) ) #pragma comment (linker, EXPORT_SYMBOL(gf_sg_set_scene_time_callback) ) @@ -1527,19 +1551,24 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_mux_program_add) ) #pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_program_stream_add) ) #pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_program_stream_update_ts_scale) ) -#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_program_stream_update_sl_config) ) #pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_mux_update_config) ) #pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_mux_process) ) #pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_get_sys_clock) ) #pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_get_ts_clock) ) -#endif /*GPAC_DISABLE_MPEG2TS_MUX*/ +#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_mux_use_single_au_pes_mode) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_mux_set_initial_pcr) ) +#endif /*GPAC_DISABLE_MPEG2TS_MUX*/ /* M3U8 & MPD related functions */ #pragma comment (linker, EXPORT_SYMBOL(gf_mpd_new) ) #pragma comment (linker, EXPORT_SYMBOL(gf_mpd_init_from_dom) ) #pragma comment (linker, EXPORT_SYMBOL(gf_mpd_del) ) #pragma comment (linker, EXPORT_SYMBOL(gf_m3u8_to_mpd) ) +#pragma comment (linker, EXPORT_SYMBOL(TSDemux_Demux_Setup)) +#pragma comment (linker, EXPORT_SYMBOL(TSDemux_DemuxPlay) ) +#pragma comment (linker, EXPORT_SYMBOL(TSDemux_CloseDemux) ) + #endif /*GPAC_DISABLE_MPEG2TS*/ /*laser.h exports*/ @@ -1564,6 +1593,10 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_font_manager_create_span) ) #pragma comment (linker, EXPORT_SYMBOL(gf_font_manager_refresh_span_bounds) ) +/*download.h exports*/ + #pragma comment (linker, EXPORT_SYMBOL(gf_dm_wget) ) + #pragma comment (linker, EXPORT_SYMBOL(gf_dm_wget_with_cache) ) + /* dvb_mpe.h */ #ifdef GPAC_ENST_PRIVATE #pragma comment (linker, EXPORT_SYMBOL(gf_dvb_mpe_section_del) ) @@ -1572,3 +1605,10 @@ #pragma comment (linker, EXPORT_SYMBOL(gf_dvb_mpe_shutdown) ) #pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_print_mpe_info) ) #endif + +/* carousel.h */ +#pragma comment (linker, EXPORT_SYMBOL(on_ait_section) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_process_ait) ) + + + diff --git a/src/ietf/rtcp.c b/src/ietf/rtcp.c index d52bdab..fa6044a 100644 --- a/src/ietf/rtcp.c +++ b/src/ietf/rtcp.c @@ -83,13 +83,13 @@ GF_Err gf_rtp_decode_rtcp(GF_RTPChannel *ch, char *pck, u32 pck_size, Bool *has_ } //substract this RTCP pck size pck_size -= (rtcp_hdr.Length + 1) * 4; - //all RTCP are Compounds (>1 pck), the first SHALL be SR or RR without padding + //in all RTCP Compounds (>1 pck), the first RTCP report SHALL be SR or RR without padding if (first) { if ( ( (rtcp_hdr.PayloadType!=200) && (rtcp_hdr.PayloadType!=201) ) || rtcp_hdr.Padding - || !pck_size - ) { + ) { gf_bs_del(bs); + GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("[RTCP] Corrupted RTCP packet: payload type %d (200 or 2001 expected) - Padding %d (0 expected)\n", rtcp_hdr.PayloadType, rtcp_hdr.Padding)); return GF_CORRUPTED_DATA; } first = 0; diff --git a/src/ietf/rtp_depacketizer.c b/src/ietf/rtp_depacketizer.c index f544eba..1d952f5 100644 --- a/src/ietf/rtp_depacketizer.c +++ b/src/ietf/rtp_depacketizer.c @@ -1009,10 +1009,9 @@ static GF_Err payt_set_param(GF_RTPDepacketizer *rtp, char *param_name, char *pa rtp->flags |= GF_RTP_ISMA_HAS_KEY_IDX; else rtp->flags &= ~GF_RTP_ISMA_HAS_KEY_IDX; - } - else if (!stricmp(param_name, "ISMACrypKey")) + } else if (!stricmp(param_name, "ISMACrypKey")) { rtp->key = gf_strdup(param_val); - + } return GF_OK; } @@ -1026,6 +1025,7 @@ static GF_Err gf_rtp_payt_setup(GF_RTPDepacketizer *rtp, GF_RTPMap *map, GF_SDPM if (!stricmp(map->payload_name, "enc-mpeg4-generic")) rtp->flags |= GF_RTP_HAS_ISMACRYP; + /*then process all FMTPs*/ i=0; while ((fmtp = (GF_SDP_FMTP*)gf_list_enum(media->FMTP, &i))) { @@ -1207,7 +1207,7 @@ static GF_Err gf_rtp_payt_setup(GF_RTPDepacketizer *rtp, GF_RTPMap *map, GF_SDPM while ((att = (GF_X_Attribute *)gf_list_enum(media->Attributes, &j))) { if (stricmp(att->Name, "cliprect")) continue; /*only get the display area*/ - sscanf(att->Value, "%ud,%ud,%ud,%ud", &y, &x, &h, &w); + sscanf(att->Value, "%u,%u,%u,%u", &y, &x, &h, &w); } rtp->sl_map.StreamType = GF_STREAM_VISUAL; diff --git a/src/ietf/rtp_streamer.c b/src/ietf/rtp_streamer.c index 2de89cb..c111b30 100644 --- a/src/ietf/rtp_streamer.c +++ b/src/ietf/rtp_streamer.c @@ -714,9 +714,9 @@ GF_Err gf_rtp_streamer_send_au(GF_RTPStreamer *rtp, char *data, u32 size, u64 ct return gf_rtp_streamer_send_data(rtp, data, size, size, cts, dts, is_rap, 1, 1, 0, 0, 0); } -GF_Err gf_rtp_streamer_send_au_with_sn(GF_RTPStreamer *rtp, char *data, u32 size, u64 cts, u64 dts, Bool is_rap, Bool inc_au_sn) +GF_Err gf_rtp_streamer_send_au_with_sn(GF_RTPStreamer *rtp, char *data, u32 size, u64 cts, u64 dts, Bool is_rap, u32 inc_au_sn) { - if (inc_au_sn) rtp->packetizer->sl_header.AU_sequenceNumber++; + if (inc_au_sn) rtp->packetizer->sl_header.AU_sequenceNumber += inc_au_sn; return gf_rtp_streamer_send_data(rtp, data, size, size, cts, dts, is_rap, 1, 1, rtp->packetizer->sl_header.AU_sequenceNumber, 0, 0); } diff --git a/src/ietf/rtsp_command.c b/src/ietf/rtsp_command.c index e9af5a0..ef1c9d7 100644 --- a/src/ietf/rtsp_command.c +++ b/src/ietf/rtsp_command.c @@ -403,13 +403,13 @@ void gf_rtsp_set_command_value(GF_RTSPCommand *com, char *Header, char *Value) else if (!stricmp(Header, "Accept-Encoding")) com->Accept_Encoding = gf_strdup(Value); else if (!stricmp(Header, "Accept-Language")) com->Accept_Language = gf_strdup(Value); else if (!stricmp(Header, "Authorization")) com->Authorization = gf_strdup(Value); - else if (!stricmp(Header, "Bandwidth")) sscanf(Value, "%ud", &com->Bandwidth); - else if (!stricmp(Header, "Blocksize")) sscanf(Value, "%ud", &com->Blocksize); + else if (!stricmp(Header, "Bandwidth")) sscanf(Value, "%u", &com->Bandwidth); + else if (!stricmp(Header, "Blocksize")) sscanf(Value, "%u", &com->Blocksize); else if (!stricmp(Header, "Cache-Control")) com->Cache_Control = gf_strdup(Value); else if (!stricmp(Header, "Conference")) com->Conference = gf_strdup(Value); else if (!stricmp(Header, "Connection")) com->Connection = gf_strdup(Value); - else if (!stricmp(Header, "Content-Length")) sscanf(Value, "%ud", &com->Content_Length); - else if (!stricmp(Header, "CSeq")) sscanf(Value, "%ud", &com->CSeq); + else if (!stricmp(Header, "Content-Length")) sscanf(Value, "%u", &com->Content_Length); + else if (!stricmp(Header, "CSeq")) sscanf(Value, "%u", &com->CSeq); else if (!stricmp(Header, "From")) com->From = gf_strdup(Value); else if (!stricmp(Header, "Proxy_Authorization")) com->Proxy_Authorization = gf_strdup(Value); else if (!stricmp(Header, "Proxy_Require")) com->Proxy_Require = gf_strdup(Value); diff --git a/src/ietf/rtsp_common.c b/src/ietf/rtsp_common.c index dc96c70..61628f1 100644 --- a/src/ietf/rtsp_common.c +++ b/src/ietf/rtsp_common.c @@ -185,20 +185,18 @@ GF_RTSPTransport *gf_rtsp_transport_parse(char *buffer) else if (!stricmp(param_name, "interleaved")) { u32 rID, rcID; tmp->IsInterleaved = 1; - /*do not use %ud here, broken on Win32 (sscanf returns 1)*/ - if (sscanf(param_val, "%d-%d", &rID, &rcID) == 1) { - sscanf(param_val, "%ud", &rID); + if (sscanf(param_val, "%u-%u", &rID, &rcID) == 1) { + sscanf(param_val, "%u", &rID); tmp->rtcpID = tmp->rtpID = (u8) rID; } else { tmp->rtpID = (u8) rID; tmp->rtcpID = (u8) rcID; } } - else if (!stricmp(param_name, "layers")) sscanf(param_val, "%ud", &tmp->MulticastLayers); + else if (!stricmp(param_name, "layers")) sscanf(param_val, "%u", &tmp->MulticastLayers); else if (!stricmp(param_name, "ttl")) sscanf(param_val, "%c ", &tmp->TTL); - /*do not use %hud here, broken on Win32 (sscanf returns 1)*/ else if (!stricmp(param_name, "port")) { - sscanf(param_val, "%d-%d", &v1, &v2); + sscanf(param_val, "%u-%u", &v1, &v2); tmp->port_first = (u16) v1; tmp->port_last = (u16) v2; } diff --git a/src/ietf/rtsp_response.c b/src/ietf/rtsp_response.c index 2629a63..c4d0136 100644 --- a/src/ietf/rtsp_response.c +++ b/src/ietf/rtsp_response.c @@ -204,18 +204,18 @@ void gf_rtsp_set_response_value(GF_RTSPResponse *rsp, char *Header, char *Value) else if (!stricmp(Header, "Accept-Language")) rsp->Accept_Language = gf_strdup(Value); else if (!stricmp(Header, "Allow")) rsp->Allow = gf_strdup(Value); else if (!stricmp(Header, "Authorization")) rsp->Authorization = gf_strdup(Value); - else if (!stricmp(Header, "Bandwidth")) sscanf(Value, "%ud", &rsp->Bandwidth); - else if (!stricmp(Header, "Blocksize")) sscanf(Value, "%ud", &rsp->Blocksize); + else if (!stricmp(Header, "Bandwidth")) sscanf(Value, "%u", &rsp->Bandwidth); + else if (!stricmp(Header, "Blocksize")) sscanf(Value, "%u", &rsp->Blocksize); else if (!stricmp(Header, "Cache-Control")) rsp->Cache_Control = gf_strdup(Value); else if (!stricmp(Header, "Conference")) rsp->Conference = gf_strdup(Value); else if (!stricmp(Header, "Connection")) rsp->Connection = gf_strdup(Value); else if (!stricmp(Header, "Content-Base")) rsp->Content_Base = gf_strdup(Value); else if (!stricmp(Header, "Content-Encoding")) rsp->Content_Encoding = gf_strdup(Value); - else if (!stricmp(Header, "Content-Length")) sscanf(Value, "%ud", &rsp->Content_Length); + else if (!stricmp(Header, "Content-Length")) sscanf(Value, "%u", &rsp->Content_Length); else if (!stricmp(Header, "Content-Language")) rsp->Content_Language = gf_strdup(Value); else if (!stricmp(Header, "Content-Location")) rsp->Content_Location = gf_strdup(Value); else if (!stricmp(Header, "Content-Type")) rsp->Content_Type = gf_strdup(Value); - else if (!stricmp(Header, "CSeq")) sscanf(Value, "%ud", &rsp->CSeq); + else if (!stricmp(Header, "CSeq")) sscanf(Value, "%u", &rsp->CSeq); else if (!stricmp(Header, "Date")) rsp->Date = gf_strdup(Value); else if (!stricmp(Header, "Expires")) rsp->Expires = gf_strdup(Value); else if (!stricmp(Header, "From")) rsp->From = gf_strdup(Value); @@ -258,7 +258,7 @@ void gf_rtsp_set_response_value(GF_RTSPResponse *rsp, char *Header, char *Value) LinePos = gf_token_get(Value, LinePos, ";\r\n", LineBuffer, 400); //default rsp->SessionTimeOut = 60; - sscanf(LineBuffer, "timeout=%ud", &rsp->SessionTimeOut); + sscanf(LineBuffer, "timeout=%u", &rsp->SessionTimeOut); } } @@ -284,7 +284,7 @@ void gf_rtsp_set_response_value(GF_RTSPResponse *rsp, char *Header, char *Value) strcpy(param_name, buf); } if (!stricmp(param_name, "url")) info->url = gf_strdup(param_val); - else if (!stricmp(param_name, "seq")) sscanf(param_val, "%ud", &info->seq); + else if (!stricmp(param_name, "seq")) sscanf(param_val, "%u", &info->seq); else if (!stricmp(param_name, "rtptime")) { sscanf(param_val, "%i", &s_val); info->rtp_time = (s_val>0) ? s_val : 0; diff --git a/src/ietf/sdp.c b/src/ietf/sdp.c index b9c573f..c0eb06d 100644 --- a/src/ietf/sdp.c +++ b/src/ietf/sdp.c @@ -825,7 +825,7 @@ GF_Err gf_sdp_info_check(GF_SDPInfo *sdp) if (sig < 0) { \ sprintf(temp, "%d", d); \ } else { \ - sprintf(temp, "%ud", d); \ + sprintf(temp, "%u", d); \ } \ SDP_WRITE_ALLOC_STR_WITHOUT_CHECK(temp, spa); diff --git a/src/isomedia/box_code_base.c b/src/isomedia/box_code_base.c index 90e4a32..89fb162 100644 --- a/src/isomedia/box_code_base.c +++ b/src/isomedia/box_code_base.c @@ -704,7 +704,6 @@ void dinf_del(GF_Box *s) } - GF_Err dinf_AddBox(GF_Box *s, GF_Box *a) { GF_DataInformationBox *ptr = (GF_DataInformationBox *)s; @@ -714,6 +713,7 @@ GF_Err dinf_AddBox(GF_Box *s, GF_Box *a) ptr->dref = (GF_DataReferenceBox *)a; return GF_OK; } + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type))); gf_isom_box_del(a); return GF_OK; } @@ -865,8 +865,9 @@ GF_Err edts_AddBox(GF_Box *s, GF_Box *a) ptr->editList = (GF_EditListBox *)a; return GF_OK; } + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type))); gf_isom_box_del(a); - return GF_OK; + return GF_OK; } @@ -2896,8 +2897,9 @@ GF_Err mdia_AddBox(GF_Box *s, GF_Box *a) ptr->information = (GF_MediaInformationBox *)a; return GF_OK; } + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type))); gf_isom_box_del(a); - return GF_OK; + return GF_OK; } @@ -3170,7 +3172,9 @@ GF_Err moof_AddBox(GF_Box *s, GF_Box *a) case GF_ISOM_BOX_TYPE_TRAF: return gf_list_add(ptr->TrackList, a); default: - return GF_ISOM_INVALID_FILE; + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type))); + gf_isom_box_del(a); + return GF_OK; } } @@ -3451,6 +3455,7 @@ GF_Err mp4a_AddBox(GF_Box *s, GF_Box *a) } break; default: + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type))); gf_isom_box_del(a); break; } @@ -3571,6 +3576,7 @@ GF_Err mp4s_AddBox(GF_Box *s, GF_Box *a) ptr->protection_info = (GF_ProtectionInfoBox*)a; break; default: + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type))); gf_isom_box_del(a); break; } @@ -3659,6 +3665,7 @@ void mp4v_del(GF_Box *s) if (ptr->emul_esd) gf_odf_desc_del((GF_Descriptor *)ptr->emul_esd); if (ptr->pasp) gf_isom_box_del((GF_Box *)ptr->pasp); + if (ptr->rvcc) gf_isom_box_del((GF_Box *)ptr->rvcc); if (ptr->protection_info) gf_isom_box_del((GF_Box *)ptr->protection_info); gf_free(ptr); @@ -3700,7 +3707,12 @@ GF_Err mp4v_AddBox(GF_Box *s, GF_Box *a) if (ptr->pasp) return GF_ISOM_INVALID_FILE; ptr->pasp = (GF_PixelAspectRatioBox *)a; break; + case GF_ISOM_BOX_TYPE_RVCC: + if (ptr->rvcc) return GF_ISOM_INVALID_FILE; + ptr->rvcc = (GF_RVCConfigurationBox *)a; + break; default: + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type))); gf_isom_box_del(a); break; } @@ -3803,6 +3815,10 @@ GF_Err mp4v_Write(GF_Box *s, GF_BitStream *bs) e = gf_isom_box_write((GF_Box *)ptr->protection_info, bs); if (e) return e; } + if (ptr->rvcc) { + e = gf_isom_box_write((GF_Box *)ptr->rvcc, bs); + if (e) return e; + } return e; } @@ -3854,6 +3870,11 @@ GF_Err mp4v_Size(GF_Box *s) if (e) return e; ptr->size += ptr->pasp->size; } + if (ptr->rvcc) { + e = gf_isom_box_size((GF_Box *)ptr->rvcc); + if (e) return e; + ptr->size += ptr->rvcc->size; + } if (ptr->protection_info && (ptr->type == GF_ISOM_BOX_TYPE_ENCV)) { e = gf_isom_box_size((GF_Box *)ptr->protection_info); if (e) return e; @@ -3890,8 +3911,9 @@ GF_Err mvex_AddBox(GF_Box *s, GF_Box *a) ptr->mehd = (GF_MovieExtendsHeaderBox*)a; return GF_OK; } + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type))); gf_isom_box_del(a); - return GF_OK; + return GF_OK; } @@ -4542,9 +4564,10 @@ GF_Err stbl_AddBox(GF_SampleTableBox *ptr, GF_Box *a) ptr->SubSamples = (GF_SubSampleInformationBox *)a; break; - //what's this box ??? delete it default: + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type))); gf_isom_box_del(a); + break; } return GF_OK; } @@ -5979,6 +6002,7 @@ void traf_del(GF_Box *s) if (ptr->tfhd) gf_isom_box_del((GF_Box *) ptr->tfhd); if (ptr->sdtp) gf_isom_box_del((GF_Box *) ptr->sdtp); if (ptr->subs) gf_isom_box_del((GF_Box *) ptr->subs); + if (ptr->tfdt) gf_isom_box_del((GF_Box *) ptr->tfdt); gf_isom_box_array_del(ptr->TrackRuns); gf_free(ptr); } @@ -5998,16 +6022,18 @@ GF_Err traf_AddBox(GF_Box *s, GF_Box *a) if (ptr->sdtp) return GF_ISOM_INVALID_FILE; ptr->sdtp = (GF_SampleDependencyTypeBox *)a; return GF_OK; - case GF_ISOM_BOX_TYPE_TFAD: - if (ptr->tfad) return GF_ISOM_INVALID_FILE; - ptr->tfad = a; + case GF_ISOM_BOX_TYPE_TFDT: + if (ptr->tfdt) return GF_ISOM_INVALID_FILE; + ptr->tfdt = (GF_TFBaseMediaDecodeTimeBox*) a; return GF_OK; case GF_ISOM_BOX_TYPE_SUBS: if (ptr->subs) return GF_ISOM_INVALID_FILE; ptr->subs = (GF_SubSampleInformationBox *)a; return GF_OK; default: - return GF_ISOM_INVALID_FILE; + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type))); + gf_isom_box_del(a); + return GF_OK; } } @@ -6051,6 +6077,10 @@ GF_Err traf_Write(GF_Box *s, GF_BitStream *bs) e = gf_isom_box_write((GF_Box *) ptr->subs, bs); if (e) return e; } + if (ptr->tfdt) { + e = gf_isom_box_write((GF_Box *) ptr->tfdt, bs); + if (e) return e; + } e = gf_isom_box_array_write(s, ptr->TrackRuns, bs); if (e) return e; if (ptr->sdtp) { @@ -6081,6 +6111,11 @@ GF_Err traf_Size(GF_Box *s) if (e) return e; ptr->size += ptr->sdtp->size; } + if (ptr->tfdt) { + e = gf_isom_box_size((GF_Box *) ptr->tfdt); + if (e) return e; + ptr->size += ptr->tfdt->size; + } return gf_isom_box_array_size(s, ptr->TrackRuns); } @@ -6245,7 +6280,8 @@ GF_Err trak_AddBox(GF_Box *s, GF_Box *a) ((GF_MediaBox *)a)->mediaTrack = ptr; return GF_OK; default: - gf_list_add(ptr->boxes, a); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type))); + gf_isom_box_del(a); return GF_OK; } return GF_OK; @@ -6814,6 +6850,7 @@ GF_UserDataMap *udta_getEntry(GF_UserDataBox *ptr, u32 box_type, bin128 *uuid) { u32 i; GF_UserDataMap *map; + if (ptr == NULL) return NULL; i=0; while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) { if (map->boxType == box_type) { @@ -7253,6 +7290,7 @@ GF_Err metx_AddBox(GF_Box *s, GF_Box *a) ptr->bitrate = (GF_MPEG4BitRateBox *)a; break; default: + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type))); gf_isom_box_del(a); break; } @@ -7582,6 +7620,7 @@ GF_Err lsr1_AddBox(GF_Box *s, GF_Box *a) ptr->descr = (GF_MPEG4ExtensionDescriptorsBox *)a; break; default: + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[iso file] Warning box %s unknown type - discarding\n", gf_4cc_to_str(a->type))); gf_isom_box_del(a); break; } @@ -7696,7 +7735,7 @@ GF_Err sidx_Read(GF_Box *s,GF_BitStream *bs) ptr->refs = gf_malloc(sizeof(GF_SIDXReference)*ptr->nb_refs); for (i=0; inb_refs; i++) { ptr->refs[i].reference_type = gf_bs_read_int(bs, 1); - ptr->refs[i].reference_offset = gf_bs_read_int(bs, 31); + ptr->refs[i].reference_size = gf_bs_read_int(bs, 31); ptr->refs[i].subsegment_duration = gf_bs_read_u32(bs); ptr->refs[i].contains_RAP = gf_bs_read_int(bs, 1); ptr->refs[i].RAP_delta_time = gf_bs_read_int(bs, 31); @@ -7741,7 +7780,7 @@ GF_Err sidx_Write(GF_Box *s, GF_BitStream *bs) gf_bs_write_u16(bs, ptr->nb_refs); for (i=0; inb_refs; i++ ) { gf_bs_write_int(bs, ptr->refs[i].reference_type, 1); - gf_bs_write_int(bs, ptr->refs[i].reference_offset, 31); + gf_bs_write_int(bs, ptr->refs[i].reference_size, 31); gf_bs_write_u32(bs, ptr->refs[i].subsegment_duration); gf_bs_write_int(bs, ptr->refs[i].contains_RAP, 1); gf_bs_write_int(bs, ptr->refs[i].RAP_delta_time, 31); @@ -7908,4 +7947,135 @@ GF_Err subs_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } + +GF_Box *tfdt_New() +{ + GF_TFBaseMediaDecodeTimeBox *tmp; + GF_SAFEALLOC(tmp, GF_TFBaseMediaDecodeTimeBox); + tmp->type = GF_ISOM_BOX_TYPE_TFDT; + tmp->version = 0; + return (GF_Box *)tmp; +} + +void tfdt_del(GF_Box *s) +{ + gf_free(s); +} + +/*this is using chpl format according to some NeroRecode samples*/ +GF_Err tfdt_Read(GF_Box *s,GF_BitStream *bs) +{ + GF_Err e; + GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *)s; + e = gf_isom_full_box_read(s, bs); + if (e) return e; + + if (ptr->version==1) { + ptr->baseMediaDecodeTime = gf_bs_read_u64(bs); + ptr->size -= 8; + } else { + ptr->baseMediaDecodeTime = (u32) gf_bs_read_u32(bs); + ptr->size -= 4; + } + return GF_OK; +} + +#ifndef GPAC_DISABLE_ISOM_WRITE + +GF_Err tfdt_Write(GF_Box *s, GF_BitStream *bs) +{ + GF_Err e; + GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *) s; + e = gf_isom_full_box_write(s, bs); + if (e) return e; + + if (ptr->version==1) { + gf_bs_write_u64(bs, ptr->baseMediaDecodeTime); + } else { + gf_bs_write_u32(bs, (u32) ptr->baseMediaDecodeTime); + } + return GF_OK; +} + +GF_Err tfdt_Size(GF_Box *s) +{ + GF_Err e; + GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox *)s; + e = gf_isom_full_box_get_size(s); + if (e) return e; + if (ptr->baseMediaDecodeTime<=0xFFFFFFFF) { + ptr->version = 0; + ptr->size += 4; + } else { + ptr->version = 1; + ptr->size += 8; + } + return GF_OK; +} + +#endif /*GPAC_DISABLE_ISOM_WRITE*/ + + + + +GF_Box *rvcc_New() +{ + GF_RVCConfigurationBox *tmp; + GF_SAFEALLOC(tmp, GF_RVCConfigurationBox); + tmp->type = GF_ISOM_BOX_TYPE_RVCC; + return (GF_Box *)tmp; +} + +void rvcc_del(GF_Box *s) +{ + gf_free(s); +} + +/*this is using chpl format according to some NeroRecode samples*/ +GF_Err rvcc_Read(GF_Box *s,GF_BitStream *bs) +{ + GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox*)s; + ptr->predefined_rvc_config = gf_bs_read_u16(bs); + ptr->size -= 2; + if (!ptr->predefined_rvc_config) { + ptr->rvc_meta_idx = gf_bs_read_u16(bs); + ptr->size -= 2; + } + return GF_OK; +} + +#ifndef GPAC_DISABLE_ISOM_WRITE + +GF_Err rvcc_Write(GF_Box *s, GF_BitStream *bs) +{ + GF_Err e; + GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox*) s; + + e = gf_isom_box_write_header(s, bs); + if (e) return e; + + gf_bs_write_u16(bs, ptr->predefined_rvc_config); + if (!ptr->predefined_rvc_config) { + gf_bs_write_u16(bs, ptr->rvc_meta_idx); + } + return GF_OK; +} + +GF_Err rvcc_Size(GF_Box *s) +{ + GF_Err e; + GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox *)s; + e = gf_isom_box_get_size(s); + if (e) return e; + ptr->size += 2; + if (! ptr->predefined_rvc_config) ptr->size += 2; + return GF_OK; +} + +#endif /*GPAC_DISABLE_ISOM_WRITE*/ + + + + + #endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/box_dump.c b/src/isomedia/box_dump.c index 3e84a51..6e4cf18 100644 --- a/src/isomedia/box_dump.c +++ b/src/isomedia/box_dump.c @@ -254,10 +254,14 @@ GF_Err gf_box_dump(void *ptr, FILE * trace) return tfhd_dump(a, trace); case GF_ISOM_BOX_TYPE_TRUN: return trun_dump(a, trace); + case GF_ISOM_BOX_TYPE_TFDT: + return tfdt_dump(a, trace); #endif case GF_ISOM_BOX_TYPE_SUBS: return subs_dump(a, trace); + case GF_ISOM_BOX_TYPE_RVCC: + return rvcc_dump(a, trace); case GF_ISOM_BOX_TYPE_VOID: return void_dump(a, trace); @@ -902,6 +906,7 @@ GF_Err mp4v_dump(GF_Box *a, FILE * trace) gf_box_dump(p->protection_info, trace); } if (p->pasp) gf_box_dump(p->pasp, trace); + if (p->rvcc) gf_box_dump(p->rvcc, trace); DumpBox(a, trace); @@ -2241,8 +2246,9 @@ GF_Err traf_dump(GF_Box *a, FILE * trace) DumpBox(a, trace); if (p->tfhd) gf_box_dump(p->tfhd, trace); if (p->subs) gf_box_dump(p->subs, trace); - gf_box_array_dump(p->TrackRuns, trace); if (p->sdtp) gf_box_dump(p->sdtp, trace); + if (p->tfdt) gf_box_dump(p->tfdt, trace); + gf_box_array_dump(p->TrackRuns, trace); fprintf(trace, "\n"); return GF_OK; } @@ -3500,7 +3506,7 @@ GF_Err sidx_dump(GF_Box *a, FILE * trace) gf_full_box_dump(a, trace); for (i=0; inb_refs; i++) { - fprintf(trace, "\n", p->refs[i].reference_type, p->refs[i].reference_offset, p->refs[i].subsegment_duration, p->refs[i].contains_RAP, p->refs[i].RAP_delta_time); + fprintf(trace, "\n", p->refs[i].reference_type, p->refs[i].reference_size, p->refs[i].subsegment_duration, p->refs[i].contains_RAP, p->refs[i].RAP_delta_time); } fprintf(trace, "\n"); return GF_OK; @@ -3538,4 +3544,30 @@ GF_Err subs_dump(GF_Box *a, FILE * trace) return GF_OK; } + +GF_Err tfdt_dump(GF_Box *a, FILE * trace) +{ + GF_TFBaseMediaDecodeTimeBox *ptr = (GF_TFBaseMediaDecodeTimeBox*) a; + if (!a) return GF_BAD_PARAM; + + fprintf(trace, "\n", ptr->baseMediaDecodeTime); + DumpBox(a, trace); + gf_full_box_dump(a, trace); + fprintf(trace, "\n"); + return GF_OK; +} + +GF_Err rvcc_dump(GF_Box *a, FILE * trace) +{ + GF_RVCConfigurationBox *ptr = (GF_RVCConfigurationBox*) a; + if (!a) return GF_BAD_PARAM; + + fprintf(trace, "predefined_rvc_config); + if (! ptr->predefined_rvc_config) fprintf(trace, " rvc_meta_idx=\"%d\"", ptr->rvc_meta_idx); + fprintf(trace, ">\n"); + DumpBox(a, trace); + fprintf(trace, "\n"); + return GF_OK; +} + #endif /*GPAC_DISABLE_ISOM_DUMP*/ diff --git a/src/isomedia/box_funcs.c b/src/isomedia/box_funcs.c index ff1c600..1ffd065 100644 --- a/src/isomedia/box_funcs.c +++ b/src/isomedia/box_funcs.c @@ -530,7 +530,8 @@ GF_Box *gf_isom_box_new(u32 boxType) case GF_ISOM_BOX_TYPE_TMPO: case GF_ISOM_BOX_TYPE_CPIL: case GF_ISOM_BOX_TYPE_PGAP: - case GF_ISOM_BOX_TYPE_COVR: return ListItem_New(boxType); + case GF_ISOM_BOX_TYPE_COVR: + return ListItem_New(boxType); case GF_ISOM_BOX_TYPE_DATA: return data_New(); @@ -564,6 +565,8 @@ GF_Box *gf_isom_box_new(u32 boxType) case GF_ISOM_BOX_TYPE_SIDX: return sidx_New(); case GF_ISOM_BOX_TYPE_SUBS: return subs_New(); + case GF_ISOM_BOX_TYPE_TFDT: return tfdt_New(); + case GF_ISOM_BOX_TYPE_RVCC: return rvcc_New(); default: a = defa_New(); @@ -778,7 +781,9 @@ void gf_isom_box_del(GF_Box *a) case GF_ISOM_BOX_TYPE_TMPO: case GF_ISOM_BOX_TYPE_CPIL: case GF_ISOM_BOX_TYPE_PGAP: - case GF_ISOM_BOX_TYPE_COVR: ListItem_del(a); return; + case GF_ISOM_BOX_TYPE_COVR: + ListItem_del(a); + return; case GF_ISOM_BOX_TYPE_DATA: data_del(a); return; @@ -810,6 +815,8 @@ void gf_isom_box_del(GF_Box *a) case GF_ISOM_BOX_TYPE_SIDX: sidx_del(a); return; case GF_ISOM_BOX_TYPE_SUBS: subs_del(a); return; + case GF_ISOM_BOX_TYPE_TFDT: tfdt_del(a); return; + case GF_ISOM_BOX_TYPE_RVCC: rvcc_del(a); return; default: defa_del(a); @@ -1007,7 +1014,8 @@ GF_Err gf_isom_box_read(GF_Box *a, GF_BitStream *bs) case GF_ISOM_BOX_TYPE_TMPO: case GF_ISOM_BOX_TYPE_CPIL: case GF_ISOM_BOX_TYPE_PGAP: - case GF_ISOM_BOX_TYPE_COVR: return ListItem_Read(a, bs); + case GF_ISOM_BOX_TYPE_COVR: + return ListItem_Read(a, bs); case GF_ISOM_BOX_TYPE_DATA: return data_Read(a, bs); @@ -1038,6 +1046,8 @@ GF_Err gf_isom_box_read(GF_Box *a, GF_BitStream *bs) case GF_ISOM_BOX_TYPE_SIDX: return sidx_Read(a, bs); case GF_ISOM_BOX_TYPE_SUBS: return subs_Read(a, bs); + case GF_ISOM_BOX_TYPE_TFDT: return tfdt_Read(a, bs); + case GF_ISOM_BOX_TYPE_RVCC: return rvcc_Read(a, bs); default: return defa_Read(a, bs); @@ -1236,7 +1246,8 @@ GF_Err gf_isom_box_write(GF_Box *a, GF_BitStream *bs) case GF_ISOM_BOX_TYPE_TMPO: case GF_ISOM_BOX_TYPE_CPIL: case GF_ISOM_BOX_TYPE_PGAP: - case GF_ISOM_BOX_TYPE_COVR: return ListItem_Write(a, bs); + case GF_ISOM_BOX_TYPE_COVR: + return ListItem_Write(a, bs); case GF_ISOM_BOX_TYPE_DATA: return data_Write(a, bs); @@ -1267,6 +1278,8 @@ GF_Err gf_isom_box_write(GF_Box *a, GF_BitStream *bs) case GF_ISOM_BOX_TYPE_SIDX: return sidx_Write(a, bs); case GF_ISOM_BOX_TYPE_SUBS: return subs_Write(a, bs); + case GF_ISOM_BOX_TYPE_TFDT: return tfdt_Write(a, bs); + case GF_ISOM_BOX_TYPE_RVCC: return rvcc_Write(a, bs); default: return defa_Write(a, bs); @@ -1463,7 +1476,8 @@ GF_Err gf_isom_box_size(GF_Box *a) case GF_ISOM_BOX_TYPE_TMPO: case GF_ISOM_BOX_TYPE_CPIL: case GF_ISOM_BOX_TYPE_PGAP: - case GF_ISOM_BOX_TYPE_COVR: return ListItem_Size(a); + case GF_ISOM_BOX_TYPE_COVR: + return ListItem_Size(a); case GF_ISOM_BOX_TYPE_DATA: return data_Size(a); @@ -1494,6 +1508,8 @@ GF_Err gf_isom_box_size(GF_Box *a) case GF_ISOM_BOX_TYPE_SIDX: return sidx_Size(a); case GF_ISOM_BOX_TYPE_SUBS: return subs_Size(a); + case GF_ISOM_BOX_TYPE_TFDT: return tfdt_Size(a); + case GF_ISOM_BOX_TYPE_RVCC: return rvcc_Size(a); default: return defa_Size(a); } diff --git a/src/isomedia/data_map.c b/src/isomedia/data_map.c index 582d174..ed3e29b 100644 --- a/src/isomedia/data_map.c +++ b/src/isomedia/data_map.c @@ -290,7 +290,7 @@ GF_DataMap *gf_isom_fdm_new_temp(const char *sPath) gf_free(tmp); return NULL; } - tmp->bs = gf_bs_from_file(tmp->stream, GF_BITSTREAM_READ); + tmp->bs = gf_bs_from_file(tmp->stream, GF_BITSTREAM_WRITE); if (!tmp->bs) { fclose(tmp->stream); gf_free(tmp); @@ -331,6 +331,12 @@ GF_DataMap *gf_isom_fdm_new(const char *sPath, u8 mode) if (!tmp->stream) tmp->stream = gf_f64_open(sPath, "wb"); bs_mode = GF_BITSTREAM_WRITE; break; + ///we open the file in CAT mode, in case + case GF_ISOM_DATA_MAP_CAT: + if (!tmp->stream) tmp->stream = gf_f64_open(sPath, "a+b"); + if (tmp->stream) gf_f64_seek(tmp->stream, 0, SEEK_END); + bs_mode = GF_BITSTREAM_WRITE; + break; default: gf_free(tmp); return NULL; diff --git a/src/isomedia/hinting.c b/src/isomedia/hinting.c index 6106f53..942f3af 100644 --- a/src/isomedia/hinting.c +++ b/src/isomedia/hinting.c @@ -28,9 +28,9 @@ GF_Box *ghnt_New() { - GF_HintSampleEntryBox *tmp = (GF_HintSampleEntryBox *) gf_malloc(sizeof(GF_HintSampleEntryBox)); + GF_HintSampleEntryBox *tmp; + GF_SAFEALLOC(tmp, GF_HintSampleEntryBox); if (tmp == NULL) return NULL; - memset(tmp, 0, sizeof(GF_HintSampleEntryBox)); tmp->HintDataTable = gf_list_new(); if (!tmp->HintDataTable) { gf_free(tmp); @@ -336,10 +336,12 @@ GF_GenericDTE *New_EmptyDTE() GF_GenericDTE *New_ImmediateDTE() { - GF_ImmediateDTE *dte = (GF_ImmediateDTE *)gf_malloc(sizeof(GF_ImmediateDTE)); - dte->source = 1; - memset(dte->data, 0, 14); - dte->dataLength = 0; + GF_ImmediateDTE *dte; + GF_SAFEALLOC(dte, GF_ImmediateDTE); + if (dte) { + dte->source = 1; + dte->dataLength = 0; + } return (GF_GenericDTE *)dte; } @@ -570,12 +572,11 @@ GF_Err OffsetDTE(GF_GenericDTE *dte, u32 offset, u32 HintSampleNumber) GF_RTPPacket *gf_isom_hint_rtp_new() { - GF_RTPPacket *tmp = (GF_RTPPacket *)gf_malloc(sizeof(GF_RTPPacket)); + GF_RTPPacket *tmp; + GF_SAFEALLOC(tmp, GF_RTPPacket); + if (!tmp) return NULL; tmp->TLV = gf_list_new(); tmp->DataTable = gf_list_new(); - tmp->B_bit = tmp->M_bit = tmp->P_bit = tmp->payloadType = tmp->payloadType = tmp->R_bit = tmp->X_bit = 0; - tmp->relativeTransTime = 0; - tmp->SequenceNumber = 0; return tmp; } diff --git a/src/isomedia/isom_intern.c b/src/isomedia/isom_intern.c index b297410..ed99b23 100644 --- a/src/isomedia/isom_intern.c +++ b/src/isomedia/isom_intern.c @@ -33,6 +33,7 @@ GF_Err gf_isom_parse_root_box(GF_Box **outBox, GF_BitStream *bs, u64 *bytesExpected); #ifndef GPAC_DISABLE_ISOM_FRAGMENTS +GF_Err MergeTrack(GF_TrackBox *trak, GF_TrackFragmentBox *traf, u64 moof_offset, Bool is_first_merge); GF_Err MergeFragment(GF_MovieFragmentBox *moof, GF_ISOFile *mov) { @@ -40,8 +41,6 @@ GF_Err MergeFragment(GF_MovieFragmentBox *moof, GF_ISOFile *mov) u64 MaxDur; GF_TrackFragmentBox *traf; GF_TrackBox *trak; - - GF_Err MergeTrack(GF_TrackBox *trak, GF_TrackFragmentBox *traf, u64 moof_offset); MaxDur = 0; @@ -65,7 +64,7 @@ GF_Err MergeFragment(GF_MovieFragmentBox *moof, GF_ISOFile *mov) } if (!trak || !traf->trex) return GF_ISOM_INVALID_FILE; - MergeTrack(trak, traf, mov->current_top_box_start); + MergeTrack(trak, traf, mov->current_top_box_start, !mov->first_moof_merged); //update trak duration SetTrackDuration(trak); @@ -73,6 +72,7 @@ GF_Err MergeFragment(GF_MovieFragmentBox *moof, GF_ISOFile *mov) MaxDur = trak->Header->duration; } + mov->first_moof_merged = 1; mov->NextMoofNumber = moof->mfhd->sequence_number; //update movie duration if (mov->moov->mvhd->duration < MaxDur) mov->moov->mvhd->duration = MaxDur; @@ -160,7 +160,7 @@ GF_Err gf_isom_parse_movie_boxes(GF_ISOFile *mov, u64 *bytesMissing) /*if we don't have any MDAT yet, create one (edit-write mode) We only work with one mdat, but we're puting it at the place of the first mdat found when opening a file for editing*/ - else if (!mov->mdat && (mov->openMode != GF_ISOM_OPEN_READ)) { + else if (!mov->mdat && (mov->openMode != GF_ISOM_OPEN_READ) && (mov->openMode != GF_ISOM_OPEN_CAT_FRAGMENTS)) { gf_isom_box_del(a); mov->mdat = (GF_MediaDataBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MDAT); e = gf_list_add(mov->TopBoxes, mov->mdat); @@ -214,10 +214,17 @@ GF_Err gf_isom_parse_movie_boxes(GF_ISOFile *mov, u64 *bytesMissing) /*read & debug: store at root level*/ if (mov->FragmentsFlags & GF_ISOM_FRAG_READ_DEBUG) { gf_list_add(mov->TopBoxes, a); + } else if (mov->openMode==GF_ISOM_OPEN_CAT_FRAGMENTS) { + mov->NextMoofNumber = mov->moof->mfhd->sequence_number+1; + mov->moof = NULL; + gf_isom_box_del(a); } else { /*merge all info*/ e = MergeFragment((GF_MovieFragmentBox *)a, mov); gf_isom_box_del(a); + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Error merging fragment: %s\n", gf_error_to_string(e) )); + } } break; #endif @@ -264,7 +271,7 @@ GF_Err gf_isom_parse_movie_boxes(GF_ISOFile *mov, u64 *bytesMissing) #ifndef GPAC_DISABLE_ISOM_FRAGMENTS /*in edit mode with successfully loaded fragments, delete all fragment signaling since file is no longer fragmented*/ - if ((mov->openMode > GF_ISOM_OPEN_READ) && mov->moov->mvex) { + if ((mov->openMode > GF_ISOM_OPEN_READ) && (mov->openMode != GF_ISOM_OPEN_CAT_FRAGMENTS) && mov->moov->mvex) { gf_isom_box_del((GF_Box *)mov->moov->mvex); mov->moov->mvex = NULL; } @@ -366,6 +373,7 @@ GF_ISOFile *gf_isom_open_file(const char *fileName, u32 OpenMode, const char *tm gf_isom_delete_movie(mov); return NULL; } + mov->es_id_default_sync = -1; #endif @@ -378,6 +386,12 @@ GF_ISOFile *gf_isom_open_file(const char *fileName, u32 OpenMode, const char *tm gf_isom_delete_movie(mov); return NULL; } + + if (OpenMode == GF_ISOM_OPEN_CAT_FRAGMENTS) { + gf_isom_datamap_del(mov->movieFileMap); + /*reopen the movie file map in cat mode*/ + e = gf_isom_datamap_new(fileName, tmp_dir, GF_ISOM_DATA_MAP_CAT, & mov->movieFileMap); + } return mov; } @@ -730,7 +744,7 @@ GF_EdtsEntry *CreateEditEntry(u64 EditDuration, u64 MediaTime, u8 EditMode) return ent; } -GF_Err gf_isom_add_subsample_info(GF_SubSampleInformationBox *sub_samples, u32 sampleNumber, u32 subSampleSize, u32 priority, Bool discardable) +GF_Err gf_isom_add_subsample_info(GF_SubSampleInformationBox *sub_samples, u32 sampleNumber, u32 subSampleSize, u8 priority, u32 reserved, Bool discardable) { u32 i, count, last_sample; GF_SampleEntry *pSamp; @@ -780,6 +794,7 @@ GF_Err gf_isom_add_subsample_info(GF_SubSampleInformationBox *sub_samples, u32 s if (!pSubSamp) return GF_OUT_OF_MEM; pSubSamp->subsample_size = subSampleSize; pSubSamp->subsample_priority = priority; + pSubSamp->reserved = reserved; pSubSamp->discardable = discardable; return gf_list_add(pSamp->SubSamples, pSubSamp); } diff --git a/src/isomedia/isom_read.c b/src/isomedia/isom_read.c index 1c96930..0eaac68 100644 --- a/src/isomedia/isom_read.c +++ b/src/isomedia/isom_read.c @@ -192,6 +192,7 @@ GF_ISOFile *gf_isom_open(const char *fileName, u32 OpenMode, const char *tmp_dir movie = gf_isom_create_movie(fileName, OpenMode, tmp_dir); break; case GF_ISOM_OPEN_EDIT: + case GF_ISOM_OPEN_CAT_FRAGMENTS: movie = gf_isom_open_file(fileName, OpenMode, tmp_dir); break; case GF_ISOM_WRITE_EDIT: @@ -606,6 +607,28 @@ GF_Err gf_isom_get_reference(GF_ISOFile *movie, u32 trackNumber, u32 referenceTy return GF_OK; } +//Return the number of track references of a track for a given ReferenceType +//return -1 if error +GF_EXPORT +Bool gf_isom_has_track_reference(GF_ISOFile *movie, u32 trackNumber, u32 referenceType, u32 refTrackID) +{ + u32 i; + GF_TrackBox *trak; + GF_TrackReferenceTypeBox *dpnd; + trak = gf_isom_get_track_from_file(movie, trackNumber); + if (!trak) return 0; + if (!trak->References) return 0; + + dpnd = NULL; + if ( (movie->LastError = Track_FindRef(trak, referenceType, &dpnd)) ) return 0; + if (!dpnd) return 0; + for (i=0; itrackIDCount; i++) { + if (dpnd->trackIDs[i]==refTrackID) return 1; + } + return 0; +} + + //Return the media time given the absolute time in the Movie GF_EXPORT @@ -662,27 +685,7 @@ GF_ESD *gf_isom_get_esd(GF_ISOFile *movie, u32 trackNumber, u32 StreamDescriptio movie->LastError = e; return NULL; } - if (esd) { - GF_TrackBox *trak = gf_isom_get_track_from_file(movie, trackNumber); - if (trak->meta) { - u32 brand = gf_isom_get_meta_type(movie, 0, trackNumber); - if (brand==GF_4CC('r','v','c','z')) { - Bool compressed=0; - GF_XMLBox *xml = gf_isom_get_meta_xml(movie, 0, trackNumber, &compressed); - if (xml) { - esd->decoderConfig->rvc_config = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); - if (compressed) { - gf_gz_decompress_payload(xml->xml, xml->xml_length, &esd->decoderConfig->rvc_config->data, &esd->decoderConfig->rvc_config->dataLength); - } else { - esd->decoderConfig->rvc_config->data = gf_malloc(sizeof(char)*(xml->xml_length+1)); - memcpy(esd->decoderConfig->rvc_config->data, xml->xml, sizeof(char)*xml->xml_length); - esd->decoderConfig->rvc_config->data[xml->xml_length] = 0; - esd->decoderConfig->rvc_config->dataLength = xml->xml_length; - } - } - } - } - } + return esd; } @@ -1015,7 +1018,7 @@ u32 gf_isom_get_sample_count(GF_ISOFile *the_file, u32 trackNumber) GF_TrackBox *trak; trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak) return 0; - return trak->Media->information->sampleTable->SampleSize->sampleCount; + return trak->Media->information->sampleTable->SampleSize->sampleCount + trak->sample_count_at_seg_start; } u32 gf_isom_get_constant_sample_size(GF_ISOFile *the_file, u32 trackNumber) @@ -1115,6 +1118,32 @@ u32 gf_isom_get_sample_duration(GF_ISOFile *the_file, u32 trackNumber, u32 sampl return (u32) (dts - dur); } + +GF_EXPORT +u32 gf_isom_get_sample_size(GF_ISOFile *the_file, u32 trackNumber, u32 sampleNumber) +{ + u32 size = 0; + GF_TrackBox *trak = gf_isom_get_track_from_file(the_file, trackNumber); + if (!trak || !sampleNumber) return 0; + + stbl_GetSampleSize(trak->Media->information->sampleTable->SampleSize, sampleNumber, &size); + return size; +} + +GF_EXPORT +u8 gf_isom_get_sample_sync(GF_ISOFile *the_file, u32 trackNumber, u32 sampleNumber) +{ + u8 is_rap; + GF_Err e; + GF_TrackBox *trak = gf_isom_get_track_from_file(the_file, trackNumber); + if (!trak || !sampleNumber) return 0; + + if (! trak->Media->information->sampleTable->SyncSample) return 1; + e = stbl_GetSampleRAP(trak->Media->information->sampleTable->SyncSample, sampleNumber, &is_rap, NULL, NULL); + if (e) return 0; + return is_rap; +} + //same as gf_isom_get_sample but doesn't fetch media data GF_EXPORT GF_ISOSample *gf_isom_get_sample_info(GF_ISOFile *the_file, u32 trackNumber, u32 sampleNumber, u32 *sampleDescriptionIndex, u64 *data_offset) @@ -1733,10 +1762,30 @@ GF_Err gf_isom_get_fragment_defaults(GF_ISOFile *the_file, u32 trackNumber, GF_TrackBox *trak; GF_StscEntry *sc_ent; u32 i, j, maxValue, value; +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + GF_TrackExtendsBox *trex; +#endif GF_SampleTableBox *stbl; trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak) return GF_BAD_PARAM; + /*if trex is already set, restore flags*/ +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + trex = the_file->moov->mvex ? GetTrex(the_file->moov, gf_isom_get_track_id(the_file,trackNumber) ) : NULL; + if (trex) { + trex->track = trak; + + if (defaultDuration) *defaultDuration = trex->def_sample_duration; + if (defaultSize) *defaultSize = trex->def_sample_size; + if (defaultDescriptionIndex) *defaultDescriptionIndex = trex->def_sample_desc_index; + if (defaultRandomAccess) *defaultRandomAccess = GF_ISOM_GET_FRAG_SYNC(trex->def_sample_flags); + if (defaultPadding) *defaultPadding = GF_ISOM_GET_FRAG_PAD(trex->def_sample_flags); + if (defaultDegradationPriority) *defaultDegradationPriority = GF_ISOM_GET_FRAG_DEG(trex->def_sample_flags); + return GF_OK; + } +#endif + + stbl = trak->Media->information->sampleTable; //duration if (defaultDuration) { @@ -1850,13 +1899,14 @@ GF_Err gf_isom_release_segment(GF_ISOFile *movie, Bool reset_tables) trak->Media->information->dataHandler = NULL; } if (reset_tables) { - u32 type; + u32 type, dur; u64 dts; GF_SampleTableBox *stbl = trak->Media->information->sampleTable; trak->sample_count_at_seg_start += stbl->SampleSize->sampleCount; - stbl_GetSampleDTS(stbl->TimeToSample, stbl->SampleSize->sampleCount, &dts); - trak->dts_at_seg_start += dts; - + if (trak->sample_count_at_seg_start) { + stbl_GetSampleDTS_and_Duration(stbl->TimeToSample, stbl->SampleSize->sampleCount, &dts, &dur); + trak->dts_at_seg_start += dts + dur; + } #define RECREATE_BOX(_a, __cast) \ if (_a) { \ type = _a->type;\ @@ -1877,6 +1927,7 @@ GF_Err gf_isom_release_segment(GF_ISOFile *movie, Bool reset_tables) } } + movie->first_moof_merged = 0; gf_isom_datamap_del(movie->movieFileMap); movie->movieFileMap = NULL; #endif @@ -2517,7 +2568,7 @@ u32 gf_isom_sample_has_subsamples(GF_ISOFile *movie, u32 track, u32 sampleNumber return gf_isom_sample_get_subsample_entry(movie, track, sampleNumber, NULL); } -GF_Err gf_isom_sample_get_subsample(GF_ISOFile *movie, u32 track, u32 sampleNumber, u32 subSampleNumber, u32 *size, u8 *priority, Bool *discardable) +GF_Err gf_isom_sample_get_subsample(GF_ISOFile *movie, u32 track, u32 sampleNumber, u32 subSampleNumber, u32 *size, u8 *priority, u32 *reserved, Bool *discardable) { GF_SubSampleEntry *entry; GF_SampleEntry *sub_sample; @@ -2528,9 +2579,44 @@ GF_Err gf_isom_sample_get_subsample(GF_ISOFile *movie, u32 track, u32 sampleNumb entry = gf_list_get(sub_sample->SubSamples, subSampleNumber-1); *size = entry->subsample_size; *priority = entry->subsample_priority; + *reserved = entry->reserved; *discardable = entry->discardable ? 1 : 0; return GF_OK; } +GF_Err gf_isom_get_rvc_config(GF_ISOFile *movie, u32 track, u32 sampleDescriptionIndex, u16 *rvc_predefined, char **data, u32 *size, const char **mime) +{ + GF_MPEGVisualSampleEntryBox *entry; + GF_TrackBox *trak; + + if (!rvc_predefined || !data || !size) return GF_BAD_PARAM; + *rvc_predefined = 0; + + trak = gf_isom_get_track_from_file(movie, track); + if (!trak) return GF_BAD_PARAM; + + + entry = (GF_MPEGVisualSampleEntryBox *) gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, sampleDescriptionIndex-1); + if (!entry ) return GF_BAD_PARAM; + switch (entry->type) { + case GF_ISOM_BOX_TYPE_MP4V: + case GF_ISOM_BOX_TYPE_AVC1: + case GF_ISOM_BOX_TYPE_AVC2: + case GF_ISOM_BOX_TYPE_SVC1: + case GF_ISOM_BOX_TYPE_ENCV: + break; + default: + return GF_BAD_PARAM; + } + if (!entry->rvcc) return GF_BAD_PARAM; + + *rvc_predefined = entry->rvcc->predefined_rvc_config; + if (entry->rvcc->rvc_meta_idx) { + if (!data || !size) return GF_OK; + return gf_isom_extract_meta_item_mem(movie, 0, track, entry->rvcc->rvc_meta_idx, data, size, mime); + } + return GF_OK; +} + #endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/isom_store.c b/src/isomedia/isom_store.c index a7e1763..6a954e6 100644 --- a/src/isomedia/isom_store.c +++ b/src/isomedia/isom_store.c @@ -410,12 +410,17 @@ GF_Err DoWriteMeta(GF_ISOFile *file, GF_MetaBox *meta, GF_BitStream *bs, Bool Em /*new resource*/ if (iinf->full_path) { - FILE *src = gf_f64_open(iinf->full_path, "rb"); - - if (!src) continue; - gf_f64_seek(src, 0, SEEK_END); - it_size = gf_f64_tell(src); - gf_f64_seek(src, 0, SEEK_SET); + FILE *src=NULL; + + if (!iinf->data_len) { + src = gf_f64_open(iinf->full_path, "rb"); + if (!src) continue; + gf_f64_seek(src, 0, SEEK_END); + it_size = gf_f64_tell(src); + gf_f64_seek(src, 0, SEEK_SET); + } else { + it_size = iinf->data_len; + } if (maxExtendSizeextent_entries)) { @@ -428,16 +433,20 @@ GF_Err DoWriteMeta(GF_ISOFile *file, GF_MetaBox *meta, GF_BitStream *bs, Bool Em /*OK write to mdat*/ if (!Emulation) { - char cache_data[4096]; - u64 remain = entry->extent_length; - while (remain) { - u32 size_cache = (remain>4096) ? 4096 : (u32) remain; - size_cache = fread(cache_data, sizeof(char), size_cache, src); - gf_bs_write_data(bs, cache_data, size_cache); - remain -= size_cache; + if (src) { + char cache_data[4096]; + u64 remain = entry->extent_length; + while (remain) { + u32 size_cache = (remain>4096) ? 4096 : (u32) remain; + size_cache = fread(cache_data, sizeof(char), size_cache, src); + gf_bs_write_data(bs, cache_data, size_cache); + remain -= size_cache; + } + } else { + gf_bs_write_data(bs, iinf->full_path, iinf->data_len); } } - fclose(src); + if (src) fclose(src); } else if (gf_list_count(iloc->extent_entries)) { u32 j; @@ -1180,6 +1189,7 @@ static GF_Err WriteInterleaved(MovieWriter *mw, GF_BitStream *bs, Bool drift_int //so just shift the offset e = ShiftOffset(movie, writers, finalOffset - offset); if (e) goto exit; + firstSize = GetMoovAndMetaSize(movie, writers); } //now write our stuff e = WriteMoovAndMeta(movie, writers, bs); diff --git a/src/isomedia/isom_write.c b/src/isomedia/isom_write.c index 88b8102..048ffcb 100644 --- a/src/isomedia/isom_write.c +++ b/src/isomedia/isom_write.c @@ -718,6 +718,22 @@ GF_Err gf_isom_add_sample_shadow(GF_ISOFile *movie, u32 trackNumber, GF_ISOSampl return SetTrackDuration(trak); } +GF_Err gf_isom_set_sample_rap(GF_ISOFile *movie, u32 trackNumber) +{ + GF_SampleTableBox *stbl; + GF_Err e; + GF_TrackBox *trak; + e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); + if (e) return e; + + trak = gf_isom_get_track_from_file(movie, trackNumber); + if (!trak) return GF_BAD_PARAM; + stbl = trak->Media->information->sampleTable; + if (!stbl->SyncSample) stbl->SyncSample = (GF_SyncSampleBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STSS); + return stbl_AddRAP(stbl->SyncSample, stbl->SampleSize->sampleCount); + +} + GF_Err gf_isom_append_sample_data(GF_ISOFile *movie, u32 trackNumber, char *data, u32 data_size) { GF_Err e; @@ -1944,12 +1960,13 @@ GF_Err gf_isom_set_brand_info(GF_ISOFile *movie, u32 MajorBrand, u32 MinorVersio if (!MajorBrand) return GF_BAD_PARAM; - e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); - if (e) return e; - - e = CheckNoData(movie); - if (e) return e; + if (! (movie->FragmentsFlags & GF_ISOM_FRAG_WRITE_READY)) { + e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); + if (e) return e; + e = CheckNoData(movie); + if (e) return e; + } if (!movie->brand) { movie->brand = (GF_FileTypeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_FTYP); @@ -1985,13 +2002,15 @@ GF_Err gf_isom_modify_alternate_brand(GF_ISOFile *movie, u32 Brand, u8 AddIt) u32 i, k, *p; GF_Err e; - e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); - if (e) return e; - if (!Brand) return GF_BAD_PARAM; - e = CheckNoData(movie); - if (e) return e; + if (! (movie->FragmentsFlags & GF_ISOM_FRAG_WRITE_READY)) { + e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); + if (e) return e; + + e = CheckNoData(movie); + if (e) return e; + } if (!movie->brand && AddIt) { movie->brand = (GF_FileTypeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_FTYP); @@ -2051,11 +2070,13 @@ GF_Err gf_isom_reset_alt_brands(GF_ISOFile *movie) u32 *p; GF_Err e; - e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); - if (e) return e; - - e = CheckNoData(movie); - if (e) return e; + if (! (movie->FragmentsFlags & GF_ISOM_FRAG_WRITE_READY)) { + e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); + if (e) return e; + + e = CheckNoData(movie); + if (e) return e; + } if (!movie->brand) { movie->brand = (GF_FileTypeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_FTYP); @@ -2212,10 +2233,11 @@ GF_Err gf_isom_add_user_data(GF_ISOFile *movie, u32 trackNumber, u32 UserDataTyp memcpy( ((GF_UUIDBox*)a)->uuid, UUID, 16); } - a->data = (char*)gf_malloc(sizeof(char)*DataLength); - memcpy(a->data, data, DataLength); - a->dataSize = DataLength; - + if (DataLength) { + a->data = (char*)gf_malloc(sizeof(char)*DataLength); + memcpy(a->data, data, DataLength); + a->dataSize = DataLength; + } return udta_AddBox(udta, (GF_Box *) a); } @@ -2323,12 +2345,21 @@ GF_Err gf_isom_clone_movie(GF_ISOFile *orig_file, GF_ISOFile *dest_file, Bool cl e = CanAccessMovie(dest_file, GF_ISOM_OPEN_WRITE); if (e) return e; - if (orig_file->brand) + if (orig_file->brand) { + gf_list_del_item(dest_file->TopBoxes, dest_file->brand); + gf_isom_box_del((GF_Box *)dest_file->brand); + dest_file->brand = NULL; clone_box((GF_Box *)orig_file->brand, (GF_Box **)&dest_file->brand); + if (dest_file->brand) gf_list_add(dest_file->TopBoxes, dest_file->brand); + } if (orig_file->meta) { + gf_list_del_item(dest_file->TopBoxes, dest_file->meta); + gf_isom_box_del((GF_Box *)dest_file->meta); + dest_file->meta = NULL; /*fixme - check imports*/ clone_box((GF_Box *)orig_file->meta, (GF_Box **)dest_file->meta); + if (dest_file->meta) gf_list_add(dest_file->TopBoxes, dest_file->meta); } if (orig_file->moov) { u32 i, dstTrack; @@ -2357,6 +2388,7 @@ GF_Err gf_isom_clone_movie(GF_ISOFile *orig_file, GF_ISOFile *dest_file, Bool cl dest_file->moov->mvhd->nextTrackID = 1; gf_isom_clone_pl_indications(orig_file, dest_file); } + dest_file->moov->mov = dest_file; } return GF_OK; } @@ -3905,7 +3937,7 @@ GF_Err gf_isom_timed_meta_data_config_new(GF_ISOFile *movie, u32 trackNumber, Bo } -GF_Err gf_isom_add_subsample(GF_ISOFile *movie, u32 track, u32 sampleNumber, u32 subSampleSize, u32 priority, Bool discardable) +GF_Err gf_isom_add_subsample(GF_ISOFile *movie, u32 track, u32 sampleNumber, u32 subSampleSize, u8 priority, u32 reserved, Bool discardable) { GF_SubSampleInformationBox *sub_samples; GF_TrackBox *trak; @@ -3925,9 +3957,57 @@ GF_Err gf_isom_add_subsample(GF_ISOFile *movie, u32 track, u32 sampleNumber, u32 } else { sub_samples = trak->Media->information->sampleTable->SubSamples; } - return gf_isom_add_subsample_info(sub_samples, sampleNumber, subSampleSize, priority, discardable); + return gf_isom_add_subsample_info(sub_samples, sampleNumber, subSampleSize, priority, reserved, discardable); } + +GF_Err gf_isom_set_rvc_config(GF_ISOFile *movie, u32 track, u32 sampleDescriptionIndex, u16 rvc_predefined, char *mime, char *data, u32 size) +{ + GF_MPEGVisualSampleEntryBox *entry; + GF_Err e; + GF_TrackBox *trak; + + e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); + if (e) return e; + + trak = gf_isom_get_track_from_file(movie, track); + if (!trak) return GF_BAD_PARAM; + + + entry = (GF_MPEGVisualSampleEntryBox *) gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, sampleDescriptionIndex-1); + if (!entry ) return GF_BAD_PARAM; + switch (entry->type) { + case GF_ISOM_BOX_TYPE_MP4V: + case GF_ISOM_BOX_TYPE_AVC1: + case GF_ISOM_BOX_TYPE_AVC2: + case GF_ISOM_BOX_TYPE_SVC1: + case GF_ISOM_BOX_TYPE_ENCV: + break; + default: + return GF_BAD_PARAM; + } + + if (entry->rvcc && entry->rvcc->rvc_meta_idx) { + gf_isom_remove_meta_item(movie, 0, track, entry->rvcc->rvc_meta_idx); + entry->rvcc->rvc_meta_idx = 0; + } + + if (!entry->rvcc) { + entry->rvcc = (GF_RVCConfigurationBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_RVCC); + } + entry->rvcc->predefined_rvc_config = rvc_predefined; + if (!rvc_predefined) { + e = gf_isom_set_meta_type(movie, 0, track, GF_4CC('r','v','c','i')); + if (e) return e; + gf_isom_modify_alternate_brand(movie, GF_ISOM_BRAND_ISO2, 1); + e = gf_isom_add_meta_item_memory(movie, 0, track, "rvcconfig.xml", mime, NULL, data, size); + if (e) return e; + entry->rvcc->rvc_meta_idx = gf_isom_get_meta_item_count(movie, 0, track); + } + return GF_OK; +} + + #endif /*!defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_ISOM_WRITE)*/ diff --git a/src/isomedia/media.c b/src/isomedia/media.c index 39f7f53..87977f0 100644 --- a/src/isomedia/media.c +++ b/src/isomedia/media.c @@ -220,7 +220,7 @@ GF_Err Media_GetESD(GF_MediaBox *mdia, u32 sampleDescIndex, GF_ESD **out_esd, Bo gf_bs_write_u16(bs, ((GF_MPEGVisualSampleEntryBox*)entry)->Height); gf_bs_get_content(bs, & esd->decoderConfig->decoderSpecificInfo->data, & esd->decoderConfig->decoderSpecificInfo->dataLength); gf_bs_del(bs); - return GF_OK; + break; } case GF_ISOM_SUBTYPE_LSR1: @@ -235,7 +235,7 @@ GF_Err Media_GetESD(GF_MediaBox *mdia, u32 sampleDescIndex, GF_ESD **out_esd, Bo esd->decoderConfig->decoderSpecificInfo->dataLength = ptr->lsr_config->hdr_size; esd->decoderConfig->decoderSpecificInfo->data = gf_malloc(sizeof(char)*ptr->lsr_config->hdr_size); memcpy(esd->decoderConfig->decoderSpecificInfo->data, ptr->lsr_config->hdr, sizeof(char)*ptr->lsr_config->hdr_size); - return GF_OK; + break; } default: return GF_ISOM_INVALID_MEDIA; diff --git a/src/isomedia/meta.c b/src/isomedia/meta.c index 7477f76..89ab536 100644 --- a/src/isomedia/meta.c +++ b/src/isomedia/meta.c @@ -95,7 +95,6 @@ GF_Err gf_isom_extract_meta_xml(GF_ISOFile *file, Bool root_meta, u32 track_num, GF_XMLBox *gf_isom_get_meta_xml(GF_ISOFile *file, Bool root_meta, u32 track_num, Bool *is_binary) { u32 i, count; - GF_XMLBox *xml = NULL; GF_MetaBox *meta = gf_isom_get_meta(file, root_meta, track_num); if (!meta) return NULL; @@ -190,8 +189,9 @@ u32 gf_isom_get_meta_item_by_id(GF_ISOFile *file, Bool root_meta, u32 track_num, return 0; } -GF_Err gf_isom_extract_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num, u32 item_id, const char *dump_file_name) +GF_Err gf_isom_extract_meta_item_extended(GF_ISOFile *file, Bool root_meta, u32 track_num, u32 item_id, const char *dump_file_name, char **out_data, u32 *out_size, const char **out_mime ) { + GF_BitStream *item_bs; char szPath[1024]; GF_ItemExtentEntry *extent_entry; FILE *resource = NULL; @@ -202,11 +202,14 @@ GF_Err gf_isom_extract_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num GF_MetaBox *meta = gf_isom_get_meta(file, root_meta, track_num); if (!meta || !meta->item_infos || !meta->item_locations) return GF_BAD_PARAM; + + if (out_mime) *out_mime = NULL; item_num = gf_isom_get_meta_item_by_id(file, root_meta, track_num, item_id); if (item_num) { GF_ItemInfoEntryBox *item_entry = (GF_ItemInfoEntryBox *)gf_list_get(meta->item_infos->item_infos, item_num-1); item_name = item_entry->item_name; + if (out_mime) *out_mime = item_entry->content_type; } location_entry = NULL; @@ -243,13 +246,20 @@ GF_Err gf_isom_extract_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num ) return GF_BAD_PARAM; } - if (dump_file_name) { + item_bs = NULL; + + if (out_data) { + item_bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); + } else if (dump_file_name) { strcpy(szPath, dump_file_name); + resource = gf_f64_open(szPath, "wb"); + item_bs = gf_bs_from_file(resource, GF_BITSTREAM_WRITE); } else { if (item_name) strcpy(szPath, item_name); else sprintf(szPath, "item_id%02d", item_id); + resource = gf_f64_open(szPath, "wb"); + item_bs = gf_bs_from_file(resource, GF_BITSTREAM_WRITE); } - resource = gf_f64_open(szPath, "wb"); for (i=0; i4096) ? 4096 : (u32) remain; gf_bs_read_data(file->movieFileMap->bs, buf_cache, cache_size); - fwrite(buf_cache, 1, cache_size, resource); + gf_bs_write_data(item_bs, buf_cache, cache_size); remain -= cache_size; } } - fclose(resource); + if (out_data) { + gf_bs_get_content(item_bs, out_data, out_size); + } + if (resource) { + fclose(resource); + } + gf_bs_del(item_bs); return GF_OK; } +GF_Err gf_isom_extract_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num, u32 item_id, const char *dump_file_name) +{ + return gf_isom_extract_meta_item_extended(file, root_meta, track_num, item_id, dump_file_name, NULL, NULL, NULL); +} + +GF_Err gf_isom_extract_meta_item_mem(GF_ISOFile *file, Bool root_meta, u32 track_num, u32 item_id, char **out_data, u32 *out_size, const char **out_mime) +{ + return gf_isom_extract_meta_item_extended(file, root_meta, track_num, item_id, NULL, out_data, out_size, out_mime); +} + u32 gf_isom_get_meta_primary_item_id(GF_ISOFile *file, Bool root_meta, u32 track_num) { GF_MetaBox *meta = gf_isom_get_meta(file, root_meta, track_num); @@ -424,7 +450,7 @@ GF_Err gf_isom_set_meta_xml_memory(GF_ISOFile *file, Bool root_meta, u32 track_n return GF_OK; } -GF_Err gf_isom_add_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num, Bool self_reference, char *resource_path, const char *item_name, const char *mime_type, const char *content_encoding, const char *URL, const char *URN) +GF_Err gf_isom_add_meta_item_extended(GF_ISOFile *file, Bool root_meta, u32 track_num, Bool self_reference, char *resource_path, const char *item_name, const char *mime_type, const char *content_encoding, const char *URL, const char *URN, char *data, u32 data_len) { GF_Err e; GF_ItemLocationEntry *location_entry; @@ -445,7 +471,7 @@ GF_Err gf_isom_add_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num, Bo if (e) return e; /*check file exists */ - if (!URN && !URL && !self_reference) { + if (!URN && !URL && !self_reference && !data) { FILE *src = gf_f64_open(resource_path, "rb"); if (!src) return GF_URL_ERROR; fclose(src); @@ -545,35 +571,58 @@ GF_Err gf_isom_add_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num, Bo entry->extent_offset = 0; gf_list_add(location_entry->extent_entries, entry); - src = gf_f64_open(resource_path, "rb"); - if (src) { - char cache_data[4096]; - u64 remain; - gf_f64_seek(src, 0, SEEK_END); - entry->extent_length = gf_f64_tell(src); - gf_f64_seek(src, 0, SEEK_SET); - - remain = entry->extent_length; - while (remain) { - u32 size_cache = (remain>4096) ? 4096 : (u32) remain; - size_cache = fread(cache_data, 1, size_cache, src); - gf_bs_write_data(file->editFileMap->bs, cache_data, size_cache); - remain -= size_cache; - } - fclose(src); - + if (data) { + gf_bs_write_data(file->editFileMap->bs, data, data_len); /*update length size*/ if (entry->extent_length>0xFFFFFFFF) meta->item_locations->length_size = 8; else if (entry->extent_length && !meta->item_locations->length_size) meta->item_locations->length_size = 4; + } else if (resource_path) { + src = gf_f64_open(resource_path, "rb"); + if (src) { + char cache_data[4096]; + u64 remain; + gf_f64_seek(src, 0, SEEK_END); + entry->extent_length = gf_f64_tell(src); + gf_f64_seek(src, 0, SEEK_SET); + + remain = entry->extent_length; + while (remain) { + u32 size_cache = (remain>4096) ? 4096 : (u32) remain; + size_cache = fread(cache_data, 1, size_cache, src); + gf_bs_write_data(file->editFileMap->bs, cache_data, size_cache); + remain -= size_cache; + } + fclose(src); + + /*update length size*/ + if (entry->extent_length>0xFFFFFFFF) meta->item_locations->length_size = 8; + else if (entry->extent_length && !meta->item_locations->length_size) meta->item_locations->length_size = 4; + } } } /*store full path for info*/ else if (!location_entry->data_reference_index) { - infe->full_path = gf_strdup(resource_path); + if (data) { + infe->full_path = gf_malloc(sizeof(char) * data_len); + memcpy(infe->full_path, data, sizeof(char) * data_len); + infe->data_len = data_len; + } else { + infe->full_path = gf_strdup(resource_path); + infe->data_len = 0; + } } return GF_OK; } +GF_Err gf_isom_add_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num, Bool self_reference, char *resource_path, const char *item_name, const char *mime_type, const char *content_encoding, const char *URL, const char *URN) +{ + return gf_isom_add_meta_item_extended(file, root_meta, track_num, self_reference, resource_path, item_name, mime_type, content_encoding, URL, URN, NULL, 0); +} + +GF_Err gf_isom_add_meta_item_memory(GF_ISOFile *file, Bool root_meta, u32 track_num, const char *item_name, const char *mime_type, const char *content_encoding, char *data, u32 data_len) +{ + return gf_isom_add_meta_item_extended(file, root_meta, track_num, 0, NULL, item_name, mime_type, content_encoding, NULL, NULL, data, data_len); +} GF_Err gf_isom_remove_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num, u32 item_id) { diff --git a/src/isomedia/movie_fragments.c b/src/isomedia/movie_fragments.c index 7a4ee10..096bb86 100644 --- a/src/isomedia/movie_fragments.c +++ b/src/isomedia/movie_fragments.c @@ -60,20 +60,35 @@ GF_Err gf_isom_finalize_for_fragment(GF_ISOFile *movie, Bool use_segments) { GF_Err e; u32 i; + Bool store_file = 1; GF_TrackExtendsBox *trex; if (!movie || !movie->moov) return GF_BAD_PARAM; + + if (movie->openMode==GF_ISOM_OPEN_CAT_FRAGMENTS) { + /*from now on we are in write mode*/ + movie->openMode = GF_ISOM_OPEN_WRITE; + store_file = 0; + movie->append_segment = 1; + } else { + movie->NextMoofNumber = 1; + } + //this is only allowed in write mode if (movie->openMode != GF_ISOM_OPEN_WRITE) return GF_ISOM_INVALID_MODE; if (movie->FragmentsFlags & GF_ISOM_FRAG_WRITE_READY) return GF_OK; movie->FragmentsFlags = 0; - //update durations - gf_isom_get_duration(movie); + if (store_file) { + /*"dash" brand: this is a DASH Initialization Segment*/ + gf_isom_modify_alternate_brand(movie, GF_4CC('d','a','s','h'), 1); + //update durations + gf_isom_get_duration(movie); - //write movie - e = WriteToFile(movie); - if (e) return e; + //write movie + e = WriteToFile(movie); + if (e) return e; + } //make sure we do have all we need. If not this is not an error, just consider //the file closed @@ -92,12 +107,25 @@ GF_Err gf_isom_finalize_for_fragment(GF_ISOFile *movie, Bool use_segments) //ok we are fine - note the data map is created at the begining if (i) movie->FragmentsFlags |= GF_ISOM_FRAG_WRITE_READY; - movie->NextMoofNumber = 1; if (use_segments) { movie->use_segments = 1; movie->moof_list = gf_list_new(); } + + /*set brands for segment*/ + + /*"msdh": it's a media segment */ + gf_isom_set_brand_info(movie, GF_4CC('m','s','d','h'), 0); + /*remove all brands */ + gf_isom_reset_alt_brands(movie); + /* + msdh: it's a media segment + sims: it's a media segment with an SSIX + msix: it's a media segment with an index + lmsg: it's the last media segment + */ + return GF_OK; } @@ -510,6 +538,33 @@ u32 moof_get_duration(GF_MovieFragmentBox *moof, u32 refTrackID) return duration; } +u32 moof_get_earliest_cts(GF_MovieFragmentBox *moof, u32 refTrackID) +{ + u32 i, j, cts, duration; + GF_TrunEntry *ent; + GF_TrackFragmentBox *traf; + GF_TrackFragmentRunBox *trun; + for (i=0; iTrackList); i++) { + traf = gf_list_get(moof->TrackList, i); + if (traf->tfhd->trackID==refTrackID) break; + traf=NULL; + } + if (!traf) return 0; + + duration = 0; + cts = 0xFFFFFFFF; + i=0; + while ((trun = gf_list_enum(traf->TrackRuns, &i))) { + j=0; + while ((ent = gf_list_enum(trun->entries, &j))) { + if (duration + ent->CTS_Offset < cts) + cts = duration + ent->CTS_Offset; + duration += ent->Duration; + } + } + return cts; +} + GF_Err StoreFragment(GF_ISOFile *movie, Bool load_mdat_only, s32 data_offset_diff, u32 *moof_size) { GF_Err e; @@ -661,13 +716,29 @@ GF_Err StoreFragment(GF_ISOFile *movie, Bool load_mdat_only, s32 data_offset_dif return GF_OK; } +static GF_Err sidx_rewrite(GF_SegmentIndexBox *sidx, GF_BitStream *bs, u64 start_pos) +{ + GF_Err e; + u64 pos = gf_bs_get_position(bs); + /*write sidx*/ + gf_bs_seek(bs, start_pos); + e = gf_isom_box_write((GF_Box *) sidx, bs); + gf_bs_seek(bs, pos); + return e; +} -GF_Err gf_isom_close_segment(GF_ISOFile *movie, u32 frags_per_sidx, u32 referenceTrackID, GF_SIDXTrackTimes *tracks_times, u32 nb_times, Bool daisy_chain_sidx) +GF_Err gf_isom_close_segment(GF_ISOFile *movie, s32 frags_per_sidx, u32 referenceTrackID, u64 ref_track_decode_time, Bool daisy_chain_sidx, Bool last_segment) { GF_SegmentIndexBox *sidx=NULL; + GF_SegmentIndexBox *prev_sidx=NULL; + GF_SegmentIndexBox *root_sidx=NULL; u64 sidx_start, sidx_end; - u32 count, nb_subsegs, idx; + Bool first_sidx = 0; + Bool no_sidx = 0; + u32 count, nb_subsegs=0, idx, cur_dur, sidx_dur, sidx_idx; + u64 last_top_box_pos, root_prev_offset, local_sidx_start, local_sidx_end; + GF_TrackBox *trak = NULL; GF_Err e; sidx_start = sidx_end = 0; //and only at setup @@ -687,7 +758,18 @@ GF_Err gf_isom_close_segment(GF_ISOFile *movie, u32 frags_per_sidx, u32 referenc gf_bs_seek(movie->editFileMap->bs, movie->segment_start); gf_bs_truncate(movie->editFileMap->bs); + if (referenceTrackID) { + trak = gf_isom_get_track_from_id(movie->moov, referenceTrackID); + + /*modify brands STYP*/ + /*"msix" brand: this is a DASH Initialization Segment*/ + gf_isom_modify_alternate_brand(movie, GF_4CC('m','s','i','x'), 1); + if (last_segment) { + /*"lmsg" brand: this is the last DASH Segment*/ + gf_isom_modify_alternate_brand(movie, GF_4CC('l','m','s','g'), 1); + } + } /*write STYP*/ movie->brand->type = GF_ISOM_BOX_TYPE_STYP; e = gf_isom_box_size((GF_Box *) movie->brand); @@ -695,22 +777,49 @@ GF_Err gf_isom_close_segment(GF_ISOFile *movie, u32 frags_per_sidx, u32 referenc e = gf_isom_box_write((GF_Box *) movie->brand, movie->editFileMap->bs); if (e) return e; - /* TODO: change code for SIDX new version */ - /*prepare SIDX*/ + if (frags_per_sidx < 0) { + referenceTrackID = 0; + frags_per_sidx = 0; + no_sidx = 1; + } + + /*prepare SIDX: we write a blank SIDX box with the right number of entries, and will rewrite it later on*/ if (referenceTrackID) { + Bool is_root_sidx=0; sidx = (GF_SegmentIndexBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_SIDX); sidx->reference_ID = referenceTrackID; - //sidx->nb_track_times = nb_times; - //sidx->tracks_times = tracks_times; - - if (!frags_per_sidx) nb_subsegs = 1; - else { + sidx->timescale = trak->Media->mediaHeader->timeScale; + /*we don't write anything between sidx and following moov*/ + sidx->first_offset = 0; + sidx->earliest_presentation_time = ref_track_decode_time; + + /*we consider that each fragment is a subsegment - this could be controled by another parameter*/ + if (!frags_per_sidx) { + nb_subsegs = 1; + frags_per_sidx = count; + } else { nb_subsegs = count/frags_per_sidx; if (nb_subsegs*frags_per_sidxnb_refs = nb_subsegs; - sidx->refs = gf_malloc(sizeof(GF_SIDXReference)*nb_subsegs); - memset(sidx->refs, 0, sizeof(GF_SIDXReference)*nb_subsegs); + + /*single SIDX, reference all fragments*/ + if (nb_subsegs==1) { + sidx->nb_refs = frags_per_sidx; + daisy_chain_sidx = 0; + } + /*daisy-chain SIDX, reference all fragments plus next */ + else if (daisy_chain_sidx) { + sidx->nb_refs = frags_per_sidx + 1; + /*we will have to adjust earliest cpresentation time*/ + first_sidx = 1; + } + /*root SIDX referencing all subsegments*/ + else { + sidx->nb_refs = nb_subsegs; + is_root_sidx = 1; + } + sidx->refs = gf_malloc(sizeof(GF_SIDXReference)*sidx->nb_refs); + memset(sidx->refs, 0, sizeof(GF_SIDXReference)*sidx->nb_refs); /*remember start of sidx*/ sidx_start = gf_bs_get_position(movie->editFileMap->bs); @@ -723,34 +832,139 @@ GF_Err gf_isom_close_segment(GF_ISOFile *movie, u32 frags_per_sidx, u32 referenc sidx_end = gf_bs_get_position(movie->editFileMap->bs); count = idx = 0; + + if (is_root_sidx) { + root_sidx = sidx; + sidx = NULL; + } } - /*write all moofs*/ + sidx_idx = 0; + sidx_dur = 0; + last_top_box_pos = root_prev_offset = sidx_end; + local_sidx_start = local_sidx_end = 0; + + /*cumulated segments duration since start of the sidx */ + cur_dur = 0; e = GF_OK; while (gf_list_count(movie->moof_list)) { s32 offset_diff; u32 moof_size; + u32 dur; + movie->moof = gf_list_get(movie->moof_list, 0); gf_list_rem(movie->moof_list, 0); + + if (!root_sidx && sidx && first_sidx) { + first_sidx = 0; + sidx->earliest_presentation_time = ref_track_decode_time + moof_get_earliest_cts(movie->moof, referenceTrackID); + } + + /*hierarchical or daisy-chain SIDXs*/ + if (!no_sidx && !sidx && (root_sidx || daisy_chain_sidx) ) { + sidx = (GF_SegmentIndexBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_SIDX); + sidx->reference_ID = referenceTrackID; + sidx->timescale = trak->Media->mediaHeader->timeScale; + sidx->earliest_presentation_time = ref_track_decode_time + sidx_dur + moof_get_earliest_cts(movie->moof, referenceTrackID); + + /*we don't write anything between sidx and following moov*/ + sidx->first_offset = 0; + sidx->nb_refs = frags_per_sidx; + if (daisy_chain_sidx && (nb_subsegs>1)) { + sidx->nb_refs += 1; + } + sidx->refs = gf_malloc(sizeof(GF_SIDXReference)*sidx->nb_refs); + memset(sidx->refs, 0, sizeof(GF_SIDXReference)*sidx->nb_refs); + + if (root_sidx) + root_sidx->refs[sidx_idx].reference_type = 1; + + /*remember start of sidx*/ + local_sidx_start = gf_bs_get_position(movie->editFileMap->bs); + + /*write it*/ + e = gf_isom_box_size((GF_Box *) sidx); + if (e) return e; + e = gf_isom_box_write((GF_Box *) sidx, movie->editFileMap->bs); + if (e) return e; + + local_sidx_end = gf_bs_get_position(movie->editFileMap->bs); + + /*adjust prev offset*/ + last_top_box_pos = local_sidx_end; + } + offset_diff = (s32) (gf_bs_get_position(movie->editFileMap->bs) - movie->moof->fragment_offset); movie->moof->fragment_offset = gf_bs_get_position(movie->editFileMap->bs); + if (!e) { - if (sidx && !count) { + e = StoreFragment(movie, 0, offset_diff, &moof_size); + + if (sidx) { /*we refer to next moof*/ sidx->refs[idx].reference_type = 0; sidx->refs[idx].contains_RAP = moof_get_rap_time_offset(movie->moof, referenceTrackID, & sidx->refs[idx].RAP_delta_time); - sidx->refs[idx].subsegment_duration += moof_get_duration(movie->moof, referenceTrackID); - /*reference offset is startof the moof we're about to write*/ - sidx->refs[idx].reference_offset = (u32) ( gf_bs_get_position(movie->editFileMap->bs) - sidx_end) ; - } - e = StoreFragment(movie, 0, offset_diff, &moof_size); - - if (sidx) { + if (sidx->refs[idx].contains_RAP) { + sidx->refs[idx].RAP_delta_time += cur_dur; + + if (root_sidx && !root_sidx->refs[sidx_idx].contains_RAP) { + root_sidx->refs[sidx_idx].contains_RAP = 1; + root_sidx->refs[sidx_idx].RAP_delta_time = sidx->refs[idx].RAP_delta_time + sidx_dur; + } + else if (prev_sidx && !prev_sidx->refs[prev_sidx->nb_refs - 1].contains_RAP) { + prev_sidx->refs[prev_sidx->nb_refs - 1].contains_RAP = 1; + prev_sidx->refs[prev_sidx->nb_refs - 1].RAP_delta_time = sidx->refs[idx].RAP_delta_time; + } + + } + + dur = moof_get_duration(movie->moof, referenceTrackID); + sidx->refs[idx].subsegment_duration += dur; + cur_dur += dur; + /*reference size is end of the moof we just wrote minus last_box_pos*/ + sidx->refs[idx].reference_size = (u32) ( gf_bs_get_position(movie->editFileMap->bs) - last_top_box_pos) ; + last_top_box_pos = gf_bs_get_position(movie->editFileMap->bs); + idx++; + count++; + /*switching to next SIDX*/ if (count==frags_per_sidx) { + + if (root_sidx) { + root_sidx->refs[sidx_idx].reference_size = (u32) (gf_bs_get_position(movie->editFileMap->bs) - local_sidx_start); + root_sidx->refs[sidx_idx].subsegment_duration = cur_dur; + if (!sidx_idx) { + root_sidx->earliest_presentation_time = sidx->earliest_presentation_time; + } + + sidx_rewrite(sidx, movie->editFileMap->bs, local_sidx_start); + gf_isom_box_del((GF_Box*)sidx); + sidx = NULL; + } else if (daisy_chain_sidx) { + if (prev_sidx) { + if (prev_sidx->refs[prev_sidx->nb_refs - 1].contains_RAP) { + prev_sidx->refs[prev_sidx->nb_refs - 1].contains_RAP = 1; + prev_sidx->refs[prev_sidx->nb_refs - 1].RAP_delta_time += sidx_dur; + } + prev_sidx->refs[prev_sidx->nb_refs - 1].subsegment_duration = sidx_dur; + prev_sidx->refs[prev_sidx->nb_refs - 1].reference_size = (u32) (gf_bs_get_position(movie->editFileMap->bs) - local_sidx_start); + prev_sidx->refs[prev_sidx->nb_refs - 1].reference_type = 1; + sidx_rewrite(prev_sidx, movie->editFileMap->bs, sidx_start); + gf_isom_box_del((GF_Box*)prev_sidx); + + sidx_start = local_sidx_start; + sidx_end = local_sidx_end; + } + nb_subsegs--; + prev_sidx = sidx; + sidx = NULL; + } + sidx_dur += cur_dur; + cur_dur = 0; count = 0; - idx++; + idx=0; + sidx_idx++; } } } @@ -759,23 +973,38 @@ GF_Err gf_isom_close_segment(GF_ISOFile *movie, u32 frags_per_sidx, u32 referenc } if (sidx) { - u64 pos = gf_bs_get_position(movie->editFileMap->bs); - /*write sidx*/ - gf_bs_seek(movie->editFileMap->bs, sidx_start); - e = gf_isom_box_write((GF_Box *) sidx, movie->editFileMap->bs); - gf_bs_seek(movie->editFileMap->bs, pos); - - //sidx->tracks_times=NULL; - //sidx->nb_track_times=0; + sidx_rewrite(sidx, movie->editFileMap->bs, sidx_start); gf_isom_box_del((GF_Box*)sidx); } + if (prev_sidx) { + sidx_rewrite(prev_sidx, movie->editFileMap->bs, sidx_start); + gf_isom_box_del((GF_Box*)prev_sidx); + } + if (root_sidx) { + sidx_rewrite(root_sidx, movie->editFileMap->bs, sidx_start); + gf_isom_box_del((GF_Box*)root_sidx); + } + + if (movie->append_segment) { + char bloc[1024]; + u32 seg_size = (u32) gf_bs_get_size(movie->editFileMap->bs); + gf_bs_seek(movie->editFileMap->bs, 0); + while (seg_size) { + u32 size = gf_bs_read_data(movie->editFileMap->bs, bloc, (seg_size>1024) ? 1024 : seg_size); + gf_bs_write_data(movie->movieFileMap->bs, bloc, size); + seg_size -= size; + } + gf_isom_datamap_del(movie->editFileMap); + movie->editFileMap = gf_isom_fdm_new_temp(NULL); + } + return e; } GF_Err gf_isom_close_fragments(GF_ISOFile *movie) { if (movie->use_segments) { - return gf_isom_close_segment(movie, 0, 0, NULL, 0, 0); + return gf_isom_close_segment(movie, 0, 0, 0, 0, 1); } else { return StoreFragment(movie, 0, 0, NULL); } @@ -791,6 +1020,7 @@ GF_Err gf_isom_start_segment(GF_ISOFile *movie, char *SegName) if (gf_list_count(movie->moof_list)) return GF_BAD_PARAM; + movie->append_segment = 0; /*update segment file*/ if (SegName) { gf_isom_datamap_del(movie->editFileMap); @@ -800,6 +1030,9 @@ GF_Err gf_isom_start_segment(GF_ISOFile *movie, char *SegName) } assert(gf_list_count(movie->moof_list) == 0); movie->segment_start = gf_bs_get_position(movie->editFileMap->bs); + /*if movieFileMap is not null, we are concatenating segments to the original move, force a copy*/ + if (movie->movieFileMap) + movie->append_segment = 1; return GF_OK; } @@ -1048,7 +1281,7 @@ GF_Err gf_isom_fragment_append_data(GF_ISOFile *movie, u32 TrackID, char *data, return GF_OK; } -GF_Err gf_isom_fragment_add_subsample(GF_ISOFile *movie, u32 TrackID, u32 subSampleSize, u32 priority, Bool discardable) +GF_Err gf_isom_fragment_add_subsample(GF_ISOFile *movie, u32 TrackID, u32 subSampleSize, u8 priority, u32 reserved, Bool discardable) { u32 i, count, last_sample; GF_TrackFragmentBox *traf; @@ -1069,7 +1302,7 @@ GF_Err gf_isom_fragment_add_subsample(GF_ISOFile *movie, u32 TrackID, u32 subSam traf->subs = (GF_SubSampleInformationBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_SUBS); traf->subs->version = (subSampleSize>0xFFFF) ? 1 : 0; } - return gf_isom_add_subsample_info(traf->subs, last_sample, subSampleSize, priority, discardable); + return gf_isom_add_subsample_info(traf->subs, last_sample, subSampleSize, priority, reserved, discardable); } GF_Err gf_isom_fragment_copy_subsample(GF_ISOFile *dest, u32 TrackID, GF_ISOFile *orig, u32 track, u32 sampleNumber) @@ -1103,7 +1336,7 @@ GF_Err gf_isom_fragment_copy_subsample(GF_ISOFile *dest, u32 TrackID, GF_ISOFile count = gf_list_count(sub_sample->SubSamples); for (i=0; iSubSamples, i); - e = gf_isom_add_subsample_info(traf->subs, last_sample, entry->subsample_size, entry->subsample_priority, entry->discardable); + e = gf_isom_add_subsample_info(traf->subs, last_sample, entry->subsample_size, entry->subsample_priority, entry->reserved, entry->discardable); if (e) return e; } return GF_OK; @@ -1131,6 +1364,23 @@ u32 gf_isom_is_fragmented(GF_ISOFile *movie) return 0; } + +GF_Err gf_isom_set_traf_base_media_decode_time(GF_ISOFile *movie, u32 TrackID, u64 decode_time) +{ + GF_TrackFragmentBox *traf; + if (!movie || !movie->moof || !(movie->FragmentsFlags & GF_ISOM_FRAG_WRITE_READY) ) return GF_BAD_PARAM; + + traf = GetTraf(movie, TrackID); + if (!traf) return GF_BAD_PARAM; + + if (!traf->tfdt) { + traf->tfdt = (GF_TFBaseMediaDecodeTimeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_TFDT); + if (!traf->tfdt) return GF_OUT_OF_MEM; + } + traf->tfdt->baseMediaDecodeTime = decode_time; + return GF_OK; +} + #else GF_Err gf_isom_finalize_for_fragment(GF_ISOFile *the_file) @@ -1179,7 +1429,7 @@ u32 gf_isom_is_fragmented(GF_ISOFile *the_file) return 0; } -GF_Err gf_isom_fragment_add_subsample(GF_ISOFile *movie, u32 TrackID, u32 subSampleSize, u32 priority, Bool discardable) +GF_Err gf_isom_fragment_add_subsample(GF_ISOFile *movie, u32 TrackID, u32 subSampleSize, u8 priority, u32 reserved, Bool discardable) { return GF_NOT_SUPPORTED; } @@ -1189,7 +1439,27 @@ GF_Err gf_isom_fragment_copy_subsample(GF_ISOFile *dest, u32 TrackID, GF_ISOFile return GF_NOT_SUPPORTED; } +GF_Err gf_isom_set_traf_base_media_decode_time(GF_ISOFile *movie, u32 TrackID, u64 decode_time) +{ + return GF_NOT_SUPPORTED; +} #endif /*GPAC_DISABLE_ISOM_FRAGMENTS)*/ + +void gf_isom_set_next_moof_number(GF_ISOFile *movie, u32 value) +{ +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + if (movie) movie->NextMoofNumber = value; +#endif +} + +u32 gf_isom_get_next_moof_number(GF_ISOFile *movie) +{ +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + if (movie) return movie->NextMoofNumber; +#endif + return 0; +} + #endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/stbl_read.c b/src/isomedia/stbl_read.c index 7902612..51f8e25 100644 --- a/src/isomedia/stbl_read.c +++ b/src/isomedia/stbl_read.c @@ -167,7 +167,7 @@ GF_Err stbl_GetSampleCTS(GF_CompositionOffsetBox *ctts, u32 SampleNumber, u32 *C } //Get the DTS of a sample -GF_Err stbl_GetSampleDTS(GF_TimeToSampleBox *stts, u32 SampleNumber, u64 *DTS) +GF_Err stbl_GetSampleDTS_and_Duration(GF_TimeToSampleBox *stts, u32 SampleNumber, u64 *DTS, u32 *duration) { u32 i, j, count; GF_SttsEntry *ent; @@ -212,15 +212,17 @@ GF_Err stbl_GetSampleDTS(GF_TimeToSampleBox *stts, u32 SampleNumber, u64 *DTS) found: (*DTS) = stts->r_CurrentDTS + j * (u64) ent->sampleDelta; - + if (duration) *duration = ent->sampleDelta; if (stts->r_FirstSampleInEntry == 1) stts->r_FirstSampleInEntry = 1; - - return GF_OK; } +GF_Err stbl_GetSampleDTS(GF_TimeToSampleBox *stts, u32 SampleNumber, u64 *DTS) +{ + return stbl_GetSampleDTS_and_Duration(stts, SampleNumber, DTS, NULL); +} //Set the RAP flag of a sample GF_Err stbl_GetSampleRAP(GF_SyncSampleBox *stss, u32 SampleNumber, u8 *IsRAP, u32 *prevRAP, u32 *nextRAP) { diff --git a/src/isomedia/stbl_write.c b/src/isomedia/stbl_write.c index d66d66f..c4b6e1b 100644 --- a/src/isomedia/stbl_write.c +++ b/src/isomedia/stbl_write.c @@ -90,6 +90,7 @@ GF_Err stbl_AddDTS(GF_SampleTableBox *stbl, u64 DTS, u32 *sampleNumber, u32 Last ALLOC_INC(stts->alloc_size); stts->entries = gf_realloc(stts->entries, sizeof(GF_SttsEntry)*stts->alloc_size); if (!stts->entries) return GF_OUT_OF_MEM; + memset(&stts->entries[stts->nb_entries], 0, sizeof(GF_SttsEntry)*(stts->alloc_size-stts->nb_entries) ); } ent = &stts->entries[stts->nb_entries]; stts->nb_entries++; @@ -134,6 +135,7 @@ GF_Err stbl_AddDTS(GF_SampleTableBox *stbl, u64 DTS, u32 *sampleNumber, u32 Last stts->alloc_size += 2; stts->entries = gf_realloc(stts->entries, sizeof(GF_SttsEntry)*stts->alloc_size); if (!stts->entries) return GF_OUT_OF_MEM; + memset(&stts->entries[stts->nb_entries], 0, sizeof(GF_SttsEntry)*(stts->alloc_size - stts->nb_entries) ); } /*repack the DTSs*/ @@ -172,6 +174,7 @@ GF_Err AddCompositionOffset(GF_CompositionOffsetBox *ctts, u32 offset) ALLOC_INC(ctts->alloc_size); ctts->entries = gf_realloc(ctts->entries, sizeof(GF_DttsEntry)*ctts->alloc_size); if (!ctts->entries) return GF_OUT_OF_MEM; + memset(&ctts->entries[ctts->nb_entries], 0, sizeof(GF_DttsEntry)*(ctts->alloc_size-ctts->nb_entries) ); } ctts->entries[ctts->nb_entries].decodingOffset = offset; ctts->entries[ctts->nb_entries].sampleCount = 1; @@ -194,6 +197,7 @@ GF_Err stbl_AddCTS(GF_SampleTableBox *stbl, u32 sampleNumber, u32 CTSoffset) ALLOC_INC(ctts->alloc_size); ctts->entries = gf_realloc(ctts->entries, sizeof(GF_DttsEntry)*ctts->alloc_size); if (!ctts->entries) return GF_OUT_OF_MEM; + memset(&ctts->entries[ctts->nb_entries], 0, sizeof(GF_DttsEntry)*(ctts->alloc_size - ctts->nb_entries) ); } ctts->entries[ctts->nb_entries].decodingOffset = CTSoffset; ctts->entries[ctts->nb_entries].sampleCount = 1; @@ -228,6 +232,7 @@ GF_Err stbl_AddCTS(GF_SampleTableBox *stbl, u32 sampleNumber, u32 CTSoffset) if (ctts->nb_entries+2>=ctts->alloc_size) { ctts->alloc_size += 2; ctts->entries = gf_realloc(ctts->entries, sizeof(GF_DttsEntry)*ctts->alloc_size); + memset(&ctts->entries[ctts->nb_entries], 0, sizeof(GF_DttsEntry)*(ctts->alloc_size-ctts->nb_entries) ); } ctts->entries[0].sampleCount = 1; @@ -271,7 +276,7 @@ GF_Err stbl_repackCTS(GF_CompositionOffsetBox *ctts) } } ctts->nb_entries=j+1; - /*note we don't gf_realloc*/ + /*note we don't realloc*/ return GF_OK; } @@ -294,6 +299,7 @@ GF_Err stbl_unpackCTS(GF_SampleTableBox *stbl) if (ctts->nb_entries == ctts->alloc_size) { ALLOC_INC(ctts->alloc_size); ctts->entries = gf_realloc(ctts->entries, sizeof(GF_DttsEntry)*ctts->alloc_size); + memset(&ctts->entries[ctts->nb_entries], 0, sizeof(GF_DttsEntry)*(ctts->alloc_size-ctts->nb_entries) ); } ctts->entries[ctts->nb_entries].decodingOffset = packed[i].decodingOffset; ctts->entries[ctts->nb_entries].sampleCount = 1; @@ -307,6 +313,7 @@ GF_Err stbl_unpackCTS(GF_SampleTableBox *stbl) if (ctts->nb_entries == ctts->alloc_size) { ALLOC_INC(ctts->alloc_size); ctts->entries = gf_realloc(ctts->entries, sizeof(GF_DttsEntry)*ctts->alloc_size); + memset(&ctts->entries[ctts->nb_entries], 0, sizeof(GF_DttsEntry)*(ctts->alloc_size-ctts->nb_entries) ); } ctts->entries[ctts->nb_entries].decodingOffset = 0; ctts->entries[ctts->nb_entries].sampleCount = 1; @@ -368,6 +375,7 @@ GF_Err stbl_AddSize(GF_SampleSizeBox *stsz, u32 sampleNumber, u32 size) ALLOC_INC(stsz->alloc_size); stsz->sizes = gf_realloc(stsz->sizes, sizeof(u32)*(stsz->alloc_size) ); if (!stsz->sizes) return GF_OUT_OF_MEM; + memset(&stsz->sizes[stsz->sampleCount], 0, sizeof(u32)*(stsz->alloc_size - stsz->sampleCount) ); } stsz->sizes[stsz->sampleCount] = size; } else { @@ -406,11 +414,14 @@ GF_Err stbl_AddRAP(GF_SyncSampleBox *stss, u32 sampleNumber) return GF_OK; } + if (stss->sampleNumbers[stss->nb_entries-1] == sampleNumber) return GF_OK; + if (stss->sampleNumbers[stss->nb_entries-1] < sampleNumber) { if (stss->nb_entries==stss->alloc_size) { ALLOC_INC(stss->alloc_size); stss->sampleNumbers = gf_realloc(stss->sampleNumbers, sizeof(u32) * stss->alloc_size); if (!stss->sampleNumbers) return GF_OUT_OF_MEM; + memset(&stss->sampleNumbers[stss->nb_entries], 0, sizeof(u32) * (stss->alloc_size-stss->nb_entries) ); } stss->sampleNumbers[stss->nb_entries] = sampleNumber; } else { @@ -446,6 +457,7 @@ GF_Err stbl_AddRedundant(GF_SampleTableBox *stbl, u32 sampleNumber) if (sdtp->sampleCount + 1 < sampleNumber) { u32 missed = sampleNumber-1 - sdtp->sampleCount; sdtp->sample_info = (u8*) gf_realloc(sdtp->sample_info, sizeof(u8) * (sdtp->sampleCount+missed) ); + memset(&sdtp->sample_info[sdtp->sampleCount], 0, sizeof(u8) * missed ); while (missed) { u8 isRAP; if (stbl->SyncSample) stbl_GetSampleRAP(stbl->SyncSample, sdtp->sampleCount+1, &isRAP, NULL, NULL); @@ -540,6 +552,7 @@ GF_Err stbl_AddChunkOffset(GF_MediaBox *mdia, u32 sampleNumber, u32 StreamDescIn ALLOC_INC(stco->alloc_size); stco->offsets = (u32*)gf_realloc(stco->offsets, sizeof(u32) * stco->alloc_size); if (!stco->offsets) return GF_OUT_OF_MEM; + memset(&stco->offsets[stco->nb_entries], 0, sizeof(u32) * (stco->alloc_size-stco->nb_entries) ); } stco->offsets[stco->nb_entries] = (u32) offset; stco->nb_entries += 1; @@ -570,6 +583,7 @@ GF_Err stbl_AddChunkOffset(GF_MediaBox *mdia, u32 sampleNumber, u32 StreamDescIn ALLOC_INC(co64->alloc_size); co64->offsets = (u64*)gf_realloc(co64->offsets, sizeof(u64) * co64->alloc_size); if (!co64->offsets) return GF_OUT_OF_MEM; + memset(&co64->offsets[co64->nb_entries], 0, sizeof(u64) * (co64->alloc_size - co64->nb_entries) ); } co64->offsets[co64->nb_entries] = offset; co64->nb_entries += 1; @@ -596,6 +610,7 @@ GF_Err stbl_AddChunkOffset(GF_MediaBox *mdia, u32 sampleNumber, u32 StreamDescIn ALLOC_INC(stsc->alloc_size); stsc->entries = gf_realloc(stsc->entries, sizeof(GF_StscEntry)*stsc->alloc_size); if (!stsc->entries) return GF_OUT_OF_MEM; + memset(&stsc->entries[stsc->nb_entries], 0, sizeof(GF_StscEntry)*(stsc->alloc_size-stsc->nb_entries) ); } if (sampleNumber == stsc->nb_entries + 1) { ent = &stsc->entries[stsc->nb_entries]; @@ -739,6 +754,7 @@ GF_Err stbl_SetSampleRAP(GF_SyncSampleBox *stss, u32 SampleNumber, u8 isRAP) ALLOC_INC(stss->alloc_size); stss->sampleNumbers = gf_realloc(stss->sampleNumbers, sizeof(u32)*stss->alloc_size); if (!stss->sampleNumbers) return GF_OUT_OF_MEM; + memset(&stss->sampleNumbers[stss->nb_entries], 0, sizeof(u32)*(stss->alloc_size - stss->nb_entries) ); } if (i+1 < stss->nb_entries) @@ -935,7 +951,7 @@ GF_Err stbl_RemoveChunk(GF_SampleTableBox *stbl, u32 sampleNumber) stbl->SampleToChunk->currentChunk = 1; stbl->SampleToChunk->ghostNumber = 1; - //gf_realloc the chunk offset + //realloc the chunk offset if (stbl->ChunkOffset->type == GF_ISOM_BOX_TYPE_STCO) { if (!stbl->SampleSize->sampleCount) { gf_free(((GF_ChunkOffsetBox *)stbl->ChunkOffset)->offsets); @@ -1069,7 +1085,7 @@ GF_Err stbl_SetPaddingBits(GF_SampleTableBox *stbl, u32 SampleNumber, u8 bits) if (!stbl->PaddingBits->padbits) return GF_OUT_OF_MEM; memset(stbl->PaddingBits->padbits, 0, sizeof(u8)*stbl->PaddingBits->SampleCount); } - //gf_realloc (this is needed in case n out of k samples get padding added) + //realloc (this is needed in case n out of k samples get padding added) if (stbl->PaddingBits->SampleCount < stbl->SampleSize->sampleCount) { p = (u8*)gf_malloc(sizeof(u8) * stbl->SampleSize->sampleCount); if (!p) return GF_OUT_OF_MEM; @@ -1213,7 +1229,7 @@ GF_Err stbl_SampleSizeAppend(GF_SampleSizeBox *stsz, u32 data_size) u32 i; if (!stsz || !stsz->sampleCount) return GF_BAD_PARAM; - //we must gf_realloc our table + //we must realloc our table if (stsz->sampleSize) { stsz->sizes = (u32*)gf_malloc(sizeof(u32)*stsz->sampleCount); if (!stsz->sizes) return GF_OUT_OF_MEM; @@ -1242,6 +1258,7 @@ void stbl_AppendTime(GF_SampleTableBox *stbl, u32 duration) ALLOC_INC(stts->alloc_size); stts->entries = gf_realloc(stts->entries, sizeof(GF_SttsEntry)*stts->alloc_size); if (!stts->entries) return; + memset(&stts->entries[stts->nb_entries], 0, sizeof(GF_SttsEntry)*(stts->alloc_size-stts->nb_entries) ); } stts->entries[stts->nb_entries].sampleCount = 1; stts->entries[stts->nb_entries].sampleDelta = duration; @@ -1269,6 +1286,7 @@ void stbl_AppendSize(GF_SampleTableBox *stbl, u32 size) stbl->SampleSize->sizes = (u32 *)gf_realloc(stbl->SampleSize->sizes, sizeof(u32)*stbl->SampleSize->alloc_size); if (!stbl->SampleSize->sizes) return; + memset(&stbl->SampleSize->sizes[stbl->SampleSize->sampleCount], 0, sizeof(u32) * (stbl->SampleSize->alloc_size - stbl->SampleSize->sampleCount) ); if (init_table) { for (i=0; iSampleSize->sampleCount;i++) @@ -1348,6 +1366,7 @@ void stbl_AppendSampleToChunk(GF_SampleTableBox *stbl, u32 DescIndex, u32 sample ALLOC_INC(stsc->alloc_size); stsc->entries = gf_realloc(stsc->entries, sizeof(GF_StscEntry)*stsc->alloc_size); if (!stsc->entries) return; + memset(&stsc->entries[stsc->nb_entries], 0, sizeof(GF_StscEntry)*(stsc->alloc_size - stsc->nb_entries) ); } //ok we need a new entry - this assumes this function is called AFTER AppendChunk ent = &stsc->entries[stsc->nb_entries]; @@ -1387,6 +1406,7 @@ void stbl_AppendRAP(GF_SampleTableBox *stbl, u8 isRap) ALLOC_INC(stbl->SyncSample->alloc_size); stbl->SyncSample->sampleNumbers = (u32*) gf_realloc(stbl->SyncSample->sampleNumbers, sizeof(u32) * stbl->SyncSample->alloc_size); if (!stbl->SyncSample->sampleNumbers) return; + memset(&stbl->SyncSample->sampleNumbers[stbl->SyncSample->nb_entries], 0, sizeof(u32) * (stbl->SyncSample->alloc_size-stbl->SyncSample->nb_entries) ); } stbl->SyncSample->sampleNumbers[stbl->SyncSample->nb_entries] = stbl->SampleSize->sampleCount; stbl->SyncSample->nb_entries += 1; @@ -1424,6 +1444,7 @@ void stbl_AppendCTSOffset(GF_SampleTableBox *stbl, u32 CTSOffset) if (ctts->nb_entries==ctts->alloc_size) { ALLOC_INC(ctts->alloc_size); ctts->entries = gf_realloc(ctts->entries, sizeof(GF_DttsEntry)*ctts->alloc_size); + memset(&ctts->entries[ctts->nb_entries], 0, sizeof(GF_DttsEntry)*(ctts->alloc_size-ctts->nb_entries) ); } ctts->entries[ctts->nb_entries].decodingOffset = CTSOffset; ctts->entries[ctts->nb_entries].sampleCount = 1; @@ -1592,6 +1613,7 @@ static GFINLINE GF_Err stbl_AddOffset(GF_Box **a, u64 offset) ALLOC_INC(stco->alloc_size); stco->offsets = (u32*)gf_realloc(stco->offsets, stco->alloc_size * sizeof(u32)); if (!stco->offsets) return GF_OUT_OF_MEM; + memset(&stco->offsets[stco->nb_entries], 0, (stco->alloc_size - stco->nb_entries) * sizeof(u32)); } stco->offsets[stco->nb_entries] = (u32) offset; @@ -1603,6 +1625,7 @@ static GFINLINE GF_Err stbl_AddOffset(GF_Box **a, u64 offset) ALLOC_INC(co64->alloc_size); co64->offsets = (u64*)gf_realloc(co64->offsets, co64->alloc_size * sizeof(u64)); if (!co64->offsets) return GF_OUT_OF_MEM; + memset(&co64->offsets[co64->nb_entries], 0, (co64->alloc_size - co64->nb_entries) * sizeof(u64) ); } co64->offsets[co64->nb_entries] = offset; co64->nb_entries += 1; @@ -1671,6 +1694,7 @@ GF_Err stbl_SetChunkAndOffset(GF_SampleTableBox *stbl, u32 sampleNumber, u32 Str ALLOC_INC(the_stsc->alloc_size); the_stsc->entries = gf_realloc(the_stsc->entries, sizeof(GF_StscEntry)*the_stsc->alloc_size); if (!the_stsc->entries) return GF_OUT_OF_MEM; + memset(&the_stsc->entries[the_stsc->nb_entries], 0, sizeof(GF_StscEntry)*(the_stsc->alloc_size-the_stsc->nb_entries)); } //create a new entry (could be the first one, BTW) newEnt = &the_stsc->entries[the_stsc->nb_entries]; diff --git a/src/isomedia/track.c b/src/isomedia/track.c index 1a36272..ef03064 100644 --- a/src/isomedia/track.c +++ b/src/isomedia/track.c @@ -66,16 +66,18 @@ GF_Err GetESD(GF_MovieBox *moov, u32 trackID, u32 StreamDescIndex, GF_ESD **outE { GF_Err e; GF_ESD *esd; + u32 track_num = 0; GF_SampleTableBox *stbl; GF_TrackBox *trak, *OCRTrack; GF_TrackReferenceTypeBox *dpnd; GF_SLConfig *slc; GF_MPEGSampleEntryBox *entry; + track_num = gf_isom_get_tracknum_from_id(moov, trackID); dpnd = NULL; *outESD = NULL; - trak = gf_isom_get_track(moov, gf_isom_get_tracknum_from_id(moov, trackID)); + trak = gf_isom_get_track(moov, track_num); if (!trak) return GF_ISOM_INVALID_FILE; e = Media_GetESD(trak->Media, StreamDescIndex, &esd, 0); @@ -98,6 +100,18 @@ GF_Err GetESD(GF_MovieBox *moov, u32 trackID, u32 StreamDescIndex, GF_ESD **outE esd->dependsOnESID = 0; } + if (trak->udta) { + GF_UserDataMap *map; + u32 i = 0; + while ((map = (GF_UserDataMap*)gf_list_enum(trak->udta->recordList, &i))) { + if (map->boxType == GF_4CC('A','U','X','V')) { + GF_Descriptor *d = gf_odf_desc_new(GF_ODF_AUX_VIDEO_DATA); + gf_list_add(esd->extensionDescriptors, d); + break; + } + } + } + //OK, get the OCR (in a REAL MP4File, OCR is 0 in ESD and is specified through track reference dpnd = NULL; OCRTrack = NULL; @@ -169,6 +183,30 @@ default_sync: esd->langDesc->langCode |= trak->Media->mediaHeader->packedLanguage[2]; } + + { + u16 rvc_predefined; + char *rvc_cfg_data; + const char *mime_type; + u32 rvc_cfg_size; + e = gf_isom_get_rvc_config(moov->mov, track_num, 1, &rvc_predefined, &rvc_cfg_data, &rvc_cfg_size, &mime_type); + if (e==GF_OK) { + if (rvc_predefined) { + esd->decoderConfig->predefined_rvc_config = rvc_predefined; + } else { + esd->decoderConfig->rvc_config = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); + if (mime_type && !strcmp(mime_type, "application/rvc-config+xml+gz") ) { + gf_gz_decompress_payload(rvc_cfg_data, rvc_cfg_size, &esd->decoderConfig->rvc_config->data, &esd->decoderConfig->rvc_config->dataLength); + gf_free(rvc_cfg_data); + } else { + esd->decoderConfig->rvc_config->data = rvc_cfg_data; + esd->decoderConfig->rvc_config->dataLength = rvc_cfg_size; + } + } + } + } + + /*normally all files shall be stored with predefined=SLPredef_MP4, but of course some are broken (philips) so we just check the ESD_URL. If set, use the given cfg, otherwise always rewrite it*/ if (esd->URLString != NULL) { @@ -241,7 +279,8 @@ default_sync: //this new SL will be OUT OF THE FILE. Let's set its predefined to 0 esd->slConfig->predefined = 0; - + + *outESD = esd; return GF_OK; } @@ -341,7 +380,7 @@ GF_Err SetTrackDuration(GF_TrackBox *trak) #ifndef GPAC_DISABLE_ISOM_FRAGMENTS -GF_Err MergeTrack(GF_TrackBox *trak, GF_TrackFragmentBox *traf, u64 moof_offset) +GF_Err MergeTrack(GF_TrackBox *trak, GF_TrackFragmentBox *traf, u64 moof_offset, Bool is_first_merge) { u32 i, j, chunk_size; u64 base_offset, data_offset; @@ -375,6 +414,16 @@ GF_Err MergeTrack(GF_TrackBox *trak, GF_TrackFragmentBox *traf, u64 moof_offset) chunk_size = 0; prev_trun_data_offset = 0; + /*in playback mode*/ + if (traf->tfdt && is_first_merge) { +#ifndef GPAC_DISABLE_LOG + if (trak->sample_count_at_seg_start && (trak->dts_at_seg_start != traf->tfdt->baseMediaDecodeTime)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[iso file] Error: TFDT timing "LLD" different from track cumulated timing "LLD" - using tfdt\n", traf->tfdt->baseMediaDecodeTime, trak->dts_at_seg_start )); + } +#endif + trak->dts_at_seg_start = traf->tfdt->baseMediaDecodeTime; + } + i=0; while ((trun = (GF_TrackFragmentRunBox *)gf_list_enum(traf->TrackRuns, &i))) { //merge the run diff --git a/src/laser/lsr_dec.c b/src/laser/lsr_dec.c index 2399c01..86bc803 100644 --- a/src/laser/lsr_dec.c +++ b/src/laser/lsr_dec.c @@ -3803,7 +3803,7 @@ static GF_Node *lsr_read_listener(GF_LASeRCodec *lsr, SVG_Element *parent) if (!target->target) post_pone = 1; else par = target->target; } - if (!handler->target) { + if (!handler->target && !handler->string) { handler->type = XMLRI_ELEMENTID; handler->target = parent; } @@ -3983,7 +3983,8 @@ static void lsr_read_group_content(GF_LASeRCodec *lsr, GF_Node *elt, Bool skip_o /*node attributes are all parsed*/ - gf_node_init(elt); + if (elt->sgprivate->tag!=TAG_SVG_script) + gf_node_init(elt); GF_LSR_READ_INT(lsr, count, 1, "opt_group"); if (count) { @@ -4002,6 +4003,9 @@ static void lsr_read_group_content(GF_LASeRCodec *lsr, GF_Node *elt, Bool skip_o } } } + + if (elt->sgprivate->tag==TAG_SVG_script) + gf_node_init(elt); } static void lsr_read_group_content_post_init(GF_LASeRCodec *lsr, SVG_Element *elt, Bool skip_init) diff --git a/src/laser/lsr_enc.c b/src/laser/lsr_enc.c index 0d1bf84..dc17e94 100644 --- a/src/laser/lsr_enc.c +++ b/src/laser/lsr_enc.c @@ -483,8 +483,7 @@ static void lsr_write_paint(GF_LASeRCodec *lsr, SVG_Paint *paint, const char *na } } -#ifdef UNUSED_FUNC - +#ifdef GPAC_UNUSED_FUNC static void lsr_write_private_element_container(GF_LASeRCodec *lsr) { /*NO PRIVATE DATA ON ENCODING YET*/ @@ -524,7 +523,7 @@ static Bool lsr_float_list_equal(GF_List *l1, GF_List *l2) } return 1; } -#endif /* UNUSED_FUNC */ +#endif /*GPAC_UNUSED_FUNC*/ @@ -550,9 +549,9 @@ static void lsr_write_private_attributes(GF_LASeRCodec *lsr, SVG_Element *elt) GF_LSR_WRITE_INT(lsr, 0, 1, "has_private_attr"); } else { GF_LSR_WRITE_INT(lsr, 1, 1, "has_private_attr"); -#ifdef UNUSED_FUNC +#ifdef GPAC_UNUSED_FUNC lsr_write_private_att_class(lsr); -#endif /* UNUSED_FUNC */ +#endif /*GPAC_UNUSED_FUNC*/ } } static void lsr_write_string_attribute(GF_LASeRCodec *lsr, char *class_attr, char *name) diff --git a/src/media_tools/av_parsers.c b/src/media_tools/av_parsers.c index a391acb..154563d 100644 --- a/src/media_tools/av_parsers.c +++ b/src/media_tools/av_parsers.c @@ -1553,9 +1553,9 @@ static u8 avc_golomb_bits[256] = { static u32 avc_get_ue(GF_BitStream *bs) { u8 coded; - u32 bits, read; - bits = 0; + u32 bits = 0, read = 0; while (1) { + if (!gf_bs_available(bs)) break; read = gf_bs_peek_bits(bs, 8, 0); if (read) break; gf_bs_read_int(bs, 8); @@ -1737,7 +1737,7 @@ static u32 avc_add_emulation_bytes(const unsigned char *buffer_src, unsigned cha } return nal_size+emulation_bytes_count; } -#ifdef UNUSED_FUNC +#ifdef GPAC_UNUSED_FUNC /*returns the nal_size without emulation prevention bytes*/ static u32 avc_emulation_bytes_remove_count(unsigned char *buffer, u32 nal_size) { @@ -1774,7 +1774,7 @@ static u32 avc_emulation_bytes_remove_count(unsigned char *buffer, u32 nal_size) return emulation_bytes_count; } -#endif /* UNUSED_FUNC */ +#endif /*GPAC_UNUSED_FUNC*/ /*nal_size is updated to allow better error detection*/ static u32 avc_remove_emulation_bytes(const unsigned char *buffer_src, unsigned char *buffer_dst, u32 nal_size) @@ -1819,8 +1819,8 @@ s32 AVC_ReadSeqInfo(char *sps_data, u32 sps_size, AVCState *avc, u32 subseq_sps, { AVC_SPS *sps; u32 ChromaArrayType = 0; - s32 mb_width, mb_height; - u32 sps_id, profile_idc, level_idc, pcomp, i, chroma_format_idc, cl, cr, ct, cb; + s32 mb_width, mb_height, sps_id = -1; + u32 profile_idc, level_idc, pcomp, i, chroma_format_idc, cl, cr, ct, cb; GF_BitStream *bs; char *sps_data_without_emulation_bytes = NULL; u32 sps_data_without_emulation_bytes_size = 0; @@ -1833,8 +1833,14 @@ s32 AVC_ReadSeqInfo(char *sps_data, u32 sps_size, AVCState *avc, u32 subseq_sps, if (vui_flag_pos) *vui_flag_pos = 0; profile_idc = gf_bs_read_int(bs, 8); + pcomp = gf_bs_read_int(bs, 8); + /*sanity checks*/ + if (pcomp & 0x3) + goto exit; + level_idc = gf_bs_read_int(bs, 8); + /*SubsetSps is used to be sure that AVC SPS are not going to be scratched by subset SPS. According to the SVC standard, subset SPS can have the same sps_id than its base layer, but it does not refer to the same SPS. */ @@ -1850,8 +1856,13 @@ s32 AVC_ReadSeqInfo(char *sps_data, u32 sps_size, AVCState *avc, u32 subseq_sps, case 122: case 244: case 44: + /*sanity checks: note1 from 7.4.2.1.1 of iso/iec 14496-10-N11084*/ + if (pcomp & 0xE0) + goto exit; case 83: case 86: + case 118: + case 128: chroma_format_idc = avc_get_ue(bs); ChromaArrayType = chroma_format_idc; if (chroma_format_idc == 3) { @@ -1902,8 +1913,8 @@ s32 AVC_ReadSeqInfo(char *sps_data, u32 sps_size, AVCState *avc, u32 subseq_sps, for(i=0; ipoc_cycle_length; i++) sps->offset_for_ref_frame[i] = avc_get_se(bs); } if (sps->poc_type > 2) { - gf_free(sps_data_without_emulation_bytes); - return -1; + sps_id = -1; + goto exit; } avc_get_ue(bs); /*ref_frame_count*/ gf_bs_read_int(bs, 1); /*gaps_in_frame_num_allowed_flag*/ @@ -2019,15 +2030,15 @@ s32 AVC_ReadSeqInfo(char *sps_data, u32 sps_size, AVCState *avc, u32 subseq_sps, vui_ext_num_entries_minus1 = avc_get_ue(bs); for (i=0; i <= vui_ext_num_entries_minus1; i++) { - u8 vui_ext_nal_hrd_parameters_present_flag, vui_ext_vcl_hrd_parameters_present_flag; - u8 vui_ext_dependency_id = gf_bs_read_int(bs, 3); - u8 vui_ext_quality_id = gf_bs_read_int(bs, 4); - u8 vui_ext_temporal_id = gf_bs_read_int(bs, 3); - u8 vui_ext_timing_info_present_flag = gf_bs_read_int(bs, 1); + u8 vui_ext_nal_hrd_parameters_present_flag, vui_ext_vcl_hrd_parameters_present_flag, vui_ext_timing_info_present_flag; + /*u8 vui_ext_dependency_id = */gf_bs_read_int(bs, 3); + /*u8 vui_ext_quality_id = */gf_bs_read_int(bs, 4); + /*u8 vui_ext_temporal_id = */gf_bs_read_int(bs, 3); + vui_ext_timing_info_present_flag = gf_bs_read_int(bs, 1); if (vui_ext_timing_info_present_flag) { - u32 vui_ext_num_units_in_tick = gf_bs_read_int(bs, 32); - u32 vui_ext_time_scale = gf_bs_read_int(bs, 32); - u8 vui_ext_fixed_frame_rate_flag = gf_bs_read_int(bs, 1); + /*u32 vui_ext_num_units_in_tick = */gf_bs_read_int(bs, 32); + /*u32 vui_ext_time_scale = */gf_bs_read_int(bs, 32); + /*u8 vui_ext_fixed_frame_rate_flag = */gf_bs_read_int(bs, 1); } vui_ext_nal_hrd_parameters_present_flag = gf_bs_read_int(bs, 1); if (vui_ext_nal_hrd_parameters_present_flag) { @@ -2045,7 +2056,7 @@ s32 AVC_ReadSeqInfo(char *sps_data, u32 sps_size, AVCState *avc, u32 subseq_sps, } } else if ((profile_idc==118) || (profile_idc==128)) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[avc-h264] MVC not spported - skipping parsing end of Subset SPS\n")); + GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[avc-h264] MVC not supported - skipping parsing end of Subset SPS\n")); goto exit; } diff --git a/src/media_tools/carousel.c b/src/media_tools/carousel.c new file mode 100644 index 0000000..99cc818 --- /dev/null +++ b/src/media_tools/carousel.c @@ -0,0 +1,409 @@ +/* +* GPAC - Multimedia Framework C SDK +* +* Authors: Telecom Paristech +* Copyright (c)2006-200X ENST - All rights reserved +* +* This file is part of GPAC / MPEG2-TS sub-project +* +* GPAC is gf_free software; you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the gf_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 gf_free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +* +*/ + +#include + + +GF_M2TS_ES *gf_ait_section_new(u32 service_id) +{ + GF_M2TS_ES *es; + + GF_M2TS_AIT *ses; + GF_SAFEALLOC(ses, GF_M2TS_AIT); + es = (GF_M2TS_ES *)ses; + es->flags = GF_M2TS_ES_IS_SECTION; + ses->service_id = service_id; + return es; +} + + +void on_ait_section(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) +{ + GF_M2TS_SL_PCK *pck = (GF_M2TS_SL_PCK *)par; + char *data; + u32 u32_data_size; + u32 u32_table_id; + + if (evt_type == GF_M2TS_EVT_AIT_FOUND) { + data = pck->data; + u32_data_size = pck->data_len; + u32_table_id = data[0]; + + gf_m2ts_process_ait((GF_M2TS_AIT*)pck->stream, data, u32_data_size, u32_table_id); + + } +} + +GF_Err gf_m2ts_process_ait(GF_M2TS_AIT *ait, char *data, u32 data_size, u32 table_id) +{ + + GF_BitStream *bs; + u8 temp_descriptor_tag; + u32 data_shift, app_desc_data_shift, ait_app_data_shift; + u32 nb_of_ait; + + data_shift = 0; + temp_descriptor_tag = 0; + nb_of_ait = 0; + ait_app_data_shift = 0; + bs = gf_bs_new(data,data_size,GF_BITSTREAM_READ); + + ait->common_descriptors = gf_list_new(); + ait->application = gf_list_new(); + + ait->table_id = gf_bs_read_int(bs,8); + ait->section_syntax_indicator = gf_bs_read_int(bs,1); + gf_bs_read_int(bs,3); + ait->section_length = gf_bs_read_int(bs,12); + if( (data[1] & 0x0C) != 0){ + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] section length is not correct abroding \n")); + }else if( ait->section_length > AIT_SECTION_LENGTH_MAX){ + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] section length should not exceed 1021. Wrong section, abording processing \n")); + } + ait->test_application_flag = gf_bs_read_int(bs,1); + ait->application_type = gf_bs_read_int(bs,15); + if(ait->application_type != APPLICATION_TYPE_HTTP_APPLICATION){ + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] application type should 0x10. Wrong section, abording processing \n")); + } + gf_bs_read_int(bs,2); + ait->version_number = gf_bs_read_int(bs,5); + + ait->current_next_indicator = gf_bs_read_int(bs,1); + if(!ait->current_next_indicator){ + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] current next indicator should be at 1 \n")); + } + ait->section_number = gf_bs_read_int(bs,8); + ait->last_section_number = gf_bs_read_int(bs,8); + gf_bs_read_int(bs,4);/* bit shifting */ + ait->common_descriptors_length = gf_bs_read_int(bs,12); + gf_bs_read_int(bs,(unsigned int)ait->common_descriptors_length/8); + gf_bs_read_int(bs,4);/* bit shifting */ + ait->application_loop_length = gf_bs_read_int(bs,12); + + data_shift = (u32)(gf_bs_get_position(bs)) + ait->common_descriptors_length/8; + + while(ait_app_data_shiftapplication_loop_length){ + + GF_M2TS_AIT_APPLICATION* application; + GF_SAFEALLOC(application,GF_M2TS_AIT_APPLICATION); + application->application_descriptors = gf_list_new(); + application->index_app_desc_id = 0; + + /* application loop */ + application->organisation_id = gf_bs_read_int(bs,32); + application->application_id= gf_bs_read_int(bs,16); + application->application_control_code= gf_bs_read_int(bs,8); + gf_bs_read_int(bs,4);/* bit shifting */ + application->application_descriptors_loop_length= gf_bs_read_int(bs,12); + + ait_app_data_shift += 9; + app_desc_data_shift = 0; + + while(app_desc_data_shift< application->application_descriptors_loop_length){ + temp_descriptor_tag = gf_bs_read_int(bs,8); + switch(temp_descriptor_tag){ + case APPLICATION_DESCRIPTOR: + { + u64 pre_processing_pos; + GF_M2TS_APPLICATION_DESCRIPTOR* application_descriptor; + GF_SAFEALLOC(application_descriptor, GF_M2TS_APPLICATION_DESCRIPTOR); + application_descriptor->descriptor_tag = temp_descriptor_tag; + application->application_descriptors_id[application->index_app_desc_id] = temp_descriptor_tag; + application->index_app_desc_id++; + application_descriptor->descriptor_length = gf_bs_read_int(bs,8); + pre_processing_pos = gf_bs_get_position(bs); + application_descriptor->application_profiles_length = gf_bs_read_int(bs,8); + application_descriptor->application_profile = gf_bs_read_int(bs,16); + application_descriptor->version_major = gf_bs_read_int(bs,8); + application_descriptor->version_minor = gf_bs_read_int(bs,8); + application_descriptor->version_micro = gf_bs_read_int(bs,8); + application_descriptor->service_bound_flag = gf_bs_read_int(bs,1); + application_descriptor->visibility = gf_bs_read_int(bs,2); + gf_bs_read_int(bs,5); /*bit shift*/ + application_descriptor->application_priority = gf_bs_read_int(bs,8); + application_descriptor->transport_protocol_label = gf_bs_read_int(bs,8); + if(pre_processing_pos+application_descriptor->descriptor_length != gf_bs_get_position(bs)){ + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor data processed length error. Difference between byte shifting %d and descriptor length %d \n",(gf_bs_get_position(bs) - pre_processing_pos),application_descriptor->descriptor_length)); + } + gf_list_add(application->application_descriptors,application_descriptor); + app_desc_data_shift += (2+ application_descriptor->descriptor_length); + break; + } + case APPLICATION_NAME_DESCRIPTOR: + { + u64 pre_processing_pos; + GF_M2TS_APPLICATION_NAME_DESCRIPTOR* name_descriptor; + GF_SAFEALLOC(name_descriptor, GF_M2TS_APPLICATION_NAME_DESCRIPTOR); + application->application_descriptors_id[application->index_app_desc_id] = temp_descriptor_tag; + application->index_app_desc_id++; + name_descriptor->descriptor_tag = temp_descriptor_tag; + name_descriptor->descriptor_length = gf_bs_read_int(bs,8); + pre_processing_pos = gf_bs_get_position(bs); + name_descriptor->ISO_639_language_code = gf_bs_read_int(bs,24); + name_descriptor->application_name_length = gf_bs_read_int(bs,8); + name_descriptor->application_name_char = (char*) gf_calloc(name_descriptor->application_name_length+1,sizeof(char)); + gf_bs_read_data(bs,name_descriptor->application_name_char,name_descriptor->application_name_length); + name_descriptor->application_name_char[name_descriptor->application_name_length] = 0 ; + if(pre_processing_pos+name_descriptor->descriptor_length != gf_bs_get_position(bs)){ + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor data processed length error. Difference between byte shifting %d and descriptor length %d \n",(gf_bs_get_position(bs) - pre_processing_pos),name_descriptor->descriptor_length)); + } + gf_list_add(application->application_descriptors,name_descriptor); + app_desc_data_shift += (2+ name_descriptor->descriptor_length); + break; + } + case TRANSPORT_PROTOCOL_DESCRIPTOR: + { + u64 pre_processing_pos; + GF_M2TS_TRANSPORT_PROTOCOL_DESCRIPTOR* protocol_descriptor; + GF_SAFEALLOC(protocol_descriptor, GF_M2TS_TRANSPORT_PROTOCOL_DESCRIPTOR); + application->application_descriptors_id[application->index_app_desc_id] = temp_descriptor_tag; + application->index_app_desc_id++; + protocol_descriptor->descriptor_tag = temp_descriptor_tag; + protocol_descriptor->descriptor_length = gf_bs_read_int(bs,8); + pre_processing_pos = gf_bs_get_position(bs); + protocol_descriptor->protocol_id = gf_bs_read_int(bs,16); + protocol_descriptor->transport_protocol_label = gf_bs_read_int(bs,8); + switch(protocol_descriptor->protocol_id){ + case CAROUSEL: + { + GF_M2TS_OBJECT_CAROUSEL_SELECTOR_BYTE* Carousel_selector_byte; + GF_SAFEALLOC(Carousel_selector_byte, GF_M2TS_OBJECT_CAROUSEL_SELECTOR_BYTE); + Carousel_selector_byte->remote_connection = gf_bs_read_int(bs,1); + gf_bs_read_int(bs,7); /* bit shifting */ + if(Carousel_selector_byte->remote_connection){ + Carousel_selector_byte->original_network_id = gf_bs_read_int(bs,16); + Carousel_selector_byte->transport_stream_id = gf_bs_read_int(bs,16); + Carousel_selector_byte->service_id = gf_bs_read_int(bs,16); + } + Carousel_selector_byte->component_tag = gf_bs_read_int(bs,8); + protocol_descriptor->selector_byte = Carousel_selector_byte; + break; + } + case TRANSPORT_HTTP: + { + u32 i; + GF_M2TS_TRANSPORT_HTTP_SELECTOR_BYTE* Transport_http_selector_byte; + GF_SAFEALLOC(Transport_http_selector_byte, GF_M2TS_TRANSPORT_HTTP_SELECTOR_BYTE); + Transport_http_selector_byte->URL_base_length = gf_bs_read_int(bs,8); + //printf("Transport_http_selector_byte->URL_base_length %d \n",Transport_http_selector_byte->URL_base_length); + Transport_http_selector_byte->URL_base_byte = (char*)gf_calloc(Transport_http_selector_byte->URL_base_length,sizeof(char)); + gf_bs_read_data(bs,Transport_http_selector_byte->URL_base_byte ,(u32)(Transport_http_selector_byte->URL_base_length)); + Transport_http_selector_byte->URL_base_byte[Transport_http_selector_byte->URL_base_length] = 0; + Transport_http_selector_byte->URL_extension_count = gf_bs_read_int(bs,8); + if(Transport_http_selector_byte->URL_extension_count){ + Transport_http_selector_byte->URL_extentions = (GF_M2TS_TRANSPORT_HTTP_URL_EXTENTION*) gf_calloc(Transport_http_selector_byte->URL_extension_count,sizeof(GF_M2TS_TRANSPORT_HTTP_URL_EXTENTION)); + for(i = 0; i < Transport_http_selector_byte->URL_extension_count;i++){ + Transport_http_selector_byte->URL_extentions[i].URL_extension_length = gf_bs_read_int(bs,8); + Transport_http_selector_byte->URL_extentions[i].URL_extension_byte = (char*)gf_calloc(Transport_http_selector_byte->URL_extentions[i].URL_extension_length,sizeof(char)); + gf_bs_read_data(bs,Transport_http_selector_byte->URL_extentions[i].URL_extension_byte,(u32)(Transport_http_selector_byte->URL_extentions[i].URL_extension_length)); + Transport_http_selector_byte->URL_extentions[i].URL_extension_byte[Transport_http_selector_byte->URL_extentions[i].URL_extension_length] = 0; + } + } + protocol_descriptor->selector_byte = Transport_http_selector_byte; + break; + } + default: + { + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Protocol ID %d unsupported, ignoring the selector byte \n",protocol_descriptor->protocol_id)); + } + } + if(pre_processing_pos+protocol_descriptor->descriptor_length != gf_bs_get_position(bs)){ + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor data processed length error. Difference between byte shifting %d and descriptor length %d \n",(gf_bs_get_position(bs) - pre_processing_pos),protocol_descriptor->descriptor_length)); + } + gf_list_add(application->application_descriptors,protocol_descriptor); + app_desc_data_shift += (2+ protocol_descriptor->descriptor_length); + break; + } + case SIMPLE_APPLICATION_LOCATION_DESCRIPTOR: + { + u64 pre_processing_pos; + GF_M2TS_SIMPLE_APPLICATION_LOCATION* Simple_application_location; + GF_SAFEALLOC(Simple_application_location, GF_M2TS_SIMPLE_APPLICATION_LOCATION); + application->application_descriptors_id[application->index_app_desc_id] = temp_descriptor_tag; + application->index_app_desc_id++; + Simple_application_location->descriptor_tag = temp_descriptor_tag; + Simple_application_location->descriptor_length = gf_bs_read_int(bs,8); + pre_processing_pos = gf_bs_get_position(bs); + Simple_application_location->initial_path_bytes = (char*)gf_calloc(Simple_application_location->descriptor_length,sizeof(char)); + gf_bs_read_data(bs,Simple_application_location->initial_path_bytes ,(u32)(Simple_application_location->descriptor_length)); + Simple_application_location->initial_path_bytes[Simple_application_location->descriptor_length] = 0; + if(pre_processing_pos+Simple_application_location->descriptor_length != gf_bs_get_position(bs)){ + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor data processed length error. Difference between byte shifting %d and descriptor length %d \n",(gf_bs_get_position(bs) - pre_processing_pos),Simple_application_location->descriptor_length)); + } + gf_list_add(application->application_descriptors,Simple_application_location); + app_desc_data_shift += (2+ Simple_application_location->descriptor_length); + break; + } + case APPLICATION_USAGE_DESCRIPTOR: + { + u64 pre_processing_pos; + GF_M2TS_APPLICATION_USAGE* Application_usage; + GF_SAFEALLOC(Application_usage, GF_M2TS_APPLICATION_USAGE); + application->application_descriptors_id[application->index_app_desc_id] = temp_descriptor_tag; + application->index_app_desc_id++; + Application_usage->descriptor_tag = temp_descriptor_tag; + Application_usage->descriptor_length = gf_bs_read_int(bs,8); + pre_processing_pos = gf_bs_get_position(bs); + Application_usage->usage_type = gf_bs_read_int(bs,8); + if(pre_processing_pos+Application_usage->descriptor_length != gf_bs_get_position(bs)){ + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor data processed length error. Difference between byte shifting %d and descriptor length %d \n",(gf_bs_get_position(bs) - pre_processing_pos),Application_usage->descriptor_length)); + } + gf_list_add(application->application_descriptors,Application_usage); + app_desc_data_shift += (2+ Application_usage->descriptor_length); + break; + } + default: + { + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor tag %d unknown, ignoring the descriptor \n",temp_descriptor_tag)); + } + + } + + } + ait_app_data_shift += application->application_descriptors_loop_length; + gf_list_add(ait->application,application); + } + + data_shift +=ait->application_loop_length; + ait->CRC_32 = gf_bs_read_int(bs,32); + data_shift += 4; + + if(data_shift != data_size){ + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] AIT processed length error. Difference between byte shifting %d and data size %d \n",data_shift,data_size)); + } + + return GF_OK; +} + +void gf_ait_destroy(GF_M2TS_AIT* ait) +{ +// u32 common_descr_numb, app_numb; +// GF_M2TS_ES *es = (GF_M2TS_ES *)ait; +// +// /* delete de Elementary Stream part of the AIT structure */ +// gf_m2ts_es_del(es); +// +// common_descr_numb = 0; +// app_numb = 0; +// +// /* delete the common descriptors */ +// common_descr_numb = gf_list_count(ait->common_descriptors); +// // while(common_app_numb != 0){ +// // +// // }; +// +// /* delete the applications and their descriptors */ +// app_numb = gf_list_count(ait->application); +// while(app_numb != 0){ +// u32 app_desc_num; +// u32 app_descr_index; +// +// app_desc_num = 0; +// app_descr_index = 0; +// app_desc_num = gf_list_count(ait->application->application_descriptors); +// while(app_desc_num != 0){ +// u32 descr_tag; +// ait->application->index_app_desc_id--; +// descr_tag = ait->application->application_descriptors_id[ait->application->index_app_desc_id]; +// +// switch(descr_tag){ +// case APPLICATION_DESCRIPTOR: +// { +// GF_M2TS_APPLICATION_DESCRIPTOR* application_descriptor = (GF_M2TS_APPLICATION_DESCRIPTOR*)gf_list_get(ait->application->application_descriptors,ait->application->index_app_desc_id); +// gf_free(application_descriptor); +// break; +// } +// case APPLICATION_NAME_DESCRIPTOR: +// { +// u64 pre_processing_pos; +// GF_M2TS_APPLICATION_NAME_DESCRIPTOR* name_descriptor = (GF_M2TS_APPLICATION_NAME_DESCRIPTOR*)gf_list_get(ait->application->application_descriptors,ait->application->index_app_desc_id); +// gf_free(name_descriptor->application_name_char); +// gf_free(name_descriptor); +// break; +// } +// case TRANSPORT_PROTOCOL_DESCRIPTOR: +// { +// u64 pre_processing_pos; +// GF_M2TS_TRANSPORT_PROTOCOL_DESCRIPTOR* protocol_descriptor = (GF_M2TS_TRANSPORT_PROTOCOL_DESCRIPTOR*)gf_list_get(ait->application->application_descriptors,ait->application->index_app_desc_id); +// +// +// switch(protocol_descriptor->protocol_id){ +// case CAROUSEL: +// { +// GF_M2TS_OBJECT_CAROUSEL_SELECTOR_BYTE* Carousel_selector_byte = (GF_M2TS_OBJECT_CAROUSEL_SELECTOR_BYTE*)protocol_descriptor->selector_byte; +// gf_free(Carousel_selector_byte); +// break; +// } +// case TRANSPORT_HTTP: +// { +// u32 i; +// GF_M2TS_TRANSPORT_HTTP_SELECTOR_BYTE* Transport_http_selector_byte = (GF_M2TS_TRANSPORT_HTTP_SELECTOR_BYTE*)protocol_descriptor->selector_byte; +// gf_free(Transport_http_selector_byte->URL_base_byte); +// if(Transport_http_selector_byte->URL_extension_count){ +// for(i = 0; i < Transport_http_selector_byte->URL_extension_count;i++){ +// Transport_http_selector_byte->URL_extentions[i].URL_extension_length = gf_bs_read_int(bs,8); +// gf_free(Transport_http_selector_byte->URL_extentions[i].URL_extension_byte) +// } +// gf_free(Transport_http_selector_byte->URL_extentions); +// } +// gf_free(Transport_http_selector_byte); +// break; +// } +// default: +// { +// GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Protocol ID %d unsupported, ignoring the selector byte \n",protocol_descriptor->protocol_id)); +// } +// } +// gf_free(protocol_descriptor); +// break; +// } +// case SIMPLE_APPLICATION_LOCATION_DESCRIPTOR: +// { +// GF_M2TS_SIMPLE_APPLICATION_LOCATION* Simple_application_location = (GF_M2TS_SIMPLE_APPLICATION_LOCATION*)gf_list_get(ait->application->application_descriptors,ait->application->index_app_desc_id); +// gf_free(Simple_application_location->initial_path_bytes); +// gf_free(Simple_application_location); +// break; +// } +// case APPLICATION_USAGE_DESCRIPTOR: +// { +// GF_M2TS_APPLICATION_USAGE* Application_usage = (GF_M2TS_SIMPLE_APPLICATION_LOCATION*)gf_list_get(ait->application->application_descriptors,ait->application->index_app_desc_id); +// gf_free(Application_usage); +// break; +// } +// default: +// { +// GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] Descriptor tag %d unknown, ignoring the descriptor \n",temp_descriptor_tag)); +// } +// +// } +// gf_list_rem(ait->application->application_descriptors,ait->application->index_app_desc_id); +// +// } +// gf_list_del(ait->application->application_descriptors); +// } +// gf_list_del(ait->application); +// +// }; + +} \ No newline at end of file diff --git a/src/media_tools/dvb.c b/src/media_tools/dvb.c new file mode 100644 index 0000000..0ce6368 --- /dev/null +++ b/src/media_tools/dvb.c @@ -0,0 +1,68 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c)2006-201X ENST - All rights reserved + * + * This file is part of GPAC / MPEG2-TS sub-project + * + * GPAC is gf_free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the gf_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 gf_free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +#include +#include + + +/* decodes an Modified Julian Date (MJD) into a Co-ordinated Universal Time (UTC) +See annex C of DVB-SI ETSI EN 300468 */ +void dvb_decode_mjd_date(u32 date, u16 *year, u8 *month, u8 *day) +{ + u32 yp, mp, k; + yp = (u32)((date - 15078.2)/365.25); + mp = (u32)((date - 14956.1 - (u32)(yp * 365.25))/30.6001); + *day = (u32)(date - 14956 - (u32)(yp * 365.25) - (u32)(mp * 30.6001)); + if (mp == 14 || mp == 15) k = 1; + else k = 0; + *year = yp + k + 1900; + *month = mp - 1 - k*12; + assert(*year>=1900 && *year<=2100 && *month && *month<12 && *day && *day<=31); +} + +#if 0 /*disabled since mktime doesn't exist on Windows Mobile*/ +/* decodes an Modified Julian Date (MJD) into a unix time (i.e. seconds since Jan 1st 1970) */ +void dvb_decode_mjd_to_unix_time(u8 *data, time_t *unix_time) { + struct tm time; + char tmp_time[10]; + u16 year = (u16)time.tm_year; + u8 month = (u8) time.tm_mon; + u8 day = (u8) time.tm_mday; + + memset(&time, 0, sizeof(struct tm)); + dvb_decode_mjd_date((data[0] << 8) | data[1], &year, &month, &day); + time.tm_year = year - 1900; + time.tm_mon = month-1; /* months are 0-based in time_t */ + time.tm_mday = day; + time.tm_isdst = -1; /* we don't want to apply Daylight Saving Time */ + + sprintf(tmp_time, "%02x", data[2]); + time.tm_hour = atoi(tmp_time); + sprintf(tmp_time, "%02x", data[3]); + time.tm_min = atoi(tmp_time); + sprintf(tmp_time, "%02x", data[4]); + time.tm_sec = atoi(tmp_time); + *unix_time = mktime(&time); +} +#endif diff --git a/src/media_tools/dvb_mpe.c b/src/media_tools/dvb_mpe.c index d77a13b..9562f81 100644 --- a/src/media_tools/dvb_mpe.c +++ b/src/media_tools/dvb_mpe.c @@ -1200,7 +1200,7 @@ void addPadding(MPE_FEC_FRAME *mff , u32 offset) for ( i = offset ; i capacity_total; i ++ ) mff -> p_adt [i] = 0xff ; } -#ifdef UNUSED_FUNC +#ifdef GPAC_UNUSED_FUNC static void print_bytes2(u8 * data, u32 length ) /*print_bytes2 */ { u32 i = 0; @@ -1220,7 +1220,7 @@ static void print_bytes2(u8 * data, u32 length ) /*print_bytes2 */ } } } -#endif /* UNUSED_FUNC */ +#endif /*GPAC_UNUSED_FUNC*/ /*add a ip datagram into mpe fec frame, and indicate error positions*/ void setIpDatagram(MPE_FEC_FRAME * mff, u32 offset, u8* dgram, u32 length ) diff --git a/src/media_tools/img.c b/src/media_tools/img.c index 2e2d3bf..0f5d39c 100644 --- a/src/media_tools/img.c +++ b/src/media_tools/img.c @@ -201,7 +201,7 @@ exit: #ifdef GPAC_HAS_JPEG -void _nonfatal_error2(j_common_ptr cinfo, int lev) {} +void gf_jpeg_nonfatal_error2(j_common_ptr cinfo, int lev) {} /*JPG context while decoding*/ typedef struct @@ -219,26 +219,26 @@ typedef struct struct jpeg_decompress_struct cinfo; } JPGCtx; -void _output_message (j_common_ptr cinfo){ +static void gf_jpeg_output_message (j_common_ptr cinfo){ char buffer[JMSG_LENGTH_MAX]; /* Create the message */ (*cinfo->err->format_message) (cinfo, buffer); - GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[JPEG OUTPUT MESSAGE]: %s\n", buffer)); + GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[JPEG OUTPUT MESSAGE]: %s\n", buffer)); } -void _fatal_error(j_common_ptr cinfo) +static void gf_jpeg_fatal_error(j_common_ptr cinfo) { JPGErr *err = (JPGErr *) cinfo->err; - _output_message(cinfo); + gf_jpeg_output_message(cinfo); longjmp(err->jmpbuf, 1); } -void stub(j_decompress_ptr cinfo) {} +void gf_jpeg_stub(j_decompress_ptr cinfo) {} /*a JPEG is always carried in a complete, single MPEG4 AU so no refill*/ -boolean fill_input_buffer(j_decompress_ptr cinfo) { return 0; } +static boolean gf_jpeg_fill_input_buffer(j_decompress_ptr cinfo) { return 0; } -void skip_input_data(j_decompress_ptr cinfo, long num_bytes) +static void gf_jpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes) { JPGCtx *jpx = (JPGCtx *) cinfo->src; if (num_bytes > (long) jpx->src.bytes_in_buffer) { @@ -266,11 +266,11 @@ GF_Err gf_img_jpeg_dec(char *jpg, u32 jpg_size, u32 *width, u32 *height, u32 *pi JPGCtx jpx; jpx.cinfo.err = jpeg_std_error(&(jper.pub)); - jper.pub.error_exit = _fatal_error; - jper.pub.output_message = _output_message; - jper.pub.emit_message = _nonfatal_error2; + jper.pub.error_exit = gf_jpeg_fatal_error; + jper.pub.output_message = gf_jpeg_output_message; + jper.pub.emit_message = gf_jpeg_nonfatal_error2; if (setjmp(jper.jmpbuf)) { - GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[gf_img_jpeg_dec] : Failed to call cannot setjmp(jper.jmpbuf)\n")); + GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[JPEGDecode] : Failed to decode\n")); jpeg_destroy_decompress(&jpx.cinfo); return GF_IO_ERR; } @@ -279,11 +279,11 @@ GF_Err gf_img_jpeg_dec(char *jpg, u32 jpg_size, u32 *width, u32 *height, u32 *pi jpeg_create_decompress(&jpx.cinfo); /*prepare IO*/ - jpx.src.init_source = stub; - jpx.src.fill_input_buffer = fill_input_buffer; - jpx.src.skip_input_data = skip_input_data; + jpx.src.init_source = gf_jpeg_stub; + jpx.src.fill_input_buffer = gf_jpeg_fill_input_buffer; + jpx.src.skip_input_data = gf_jpeg_skip_input_data; jpx.src.resync_to_restart = jpeg_resync_to_restart; - jpx.src.term_source = stub; + jpx.src.term_source = gf_jpeg_stub; jpx.skip = 0; jpx.src.next_input_byte = jpg; jpx.src.bytes_in_buffer = jpg_size; @@ -395,7 +395,7 @@ typedef struct u32 size; } GFpng; -static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +static void gf_png_user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { GFpng *ctx = (GFpng*)png_get_io_ptr(png_ptr); @@ -406,7 +406,7 @@ static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t lengt ctx->pos += length; } } -static void user_error_fn(png_structp png_ptr,png_const_charp error_msg) +static void gf_png_user_error_fn(png_structp png_ptr,png_const_charp error_msg) { longjmp(png_jmpbuf(png_ptr), 1); } @@ -471,8 +471,8 @@ GF_Err gf_img_png_dec(char *png, u32 png_size, u32 *width, u32 *height, u32 *pix png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); return GF_IO_ERR; } - png_set_read_fn(png_ptr, &udta, (png_rw_ptr) user_read_data); - png_set_error_fn(png_ptr, &udta, (png_error_ptr) user_error_fn, NULL); + png_set_read_fn(png_ptr, &udta, (png_rw_ptr) gf_png_user_read_data); + png_set_error_fn(png_ptr, &udta, (png_error_ptr) gf_png_user_error_fn, NULL); png_read_info(png_ptr, info_ptr); @@ -536,13 +536,13 @@ GF_Err gf_img_png_dec(char *png, u32 png_size, u32 *width, u32 *height, u32 *pix } -void my_png_write(png_structp png, png_bytep data, png_size_t size) +void gf_png_write(png_structp png, png_bytep data, png_size_t size) { GFpng *p = (GFpng *)png_get_io_ptr(png); memcpy(p->buffer+p->pos, data, sizeof(char)*size); p->pos += size; } -void my_png_flush(png_structp png) +void gf_png_flush(png_structp png) { } @@ -608,7 +608,7 @@ GF_Err gf_img_png_enc(char *data, u32 width, u32 height, s32 stride, u32 pixel_f udta.buffer = dst; udta.pos = 0; - png_set_write_fn(png_ptr, &udta, my_png_write, my_png_flush); + png_set_write_fn(png_ptr, &udta, gf_png_write, gf_png_flush); png_set_IHDR(png_ptr, info_ptr, width, height, 8, type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); diff --git a/src/media_tools/isom_hinter.c b/src/media_tools/isom_hinter.c index 81ffe11..ccdc84d 100644 --- a/src/media_tools/isom_hinter.c +++ b/src/media_tools/isom_hinter.c @@ -760,7 +760,7 @@ GF_EXPORT GF_Err gf_hinter_track_finalize(GF_RTPHinter *tkHint, Bool AddSystemInfo) { u32 Width, Height; - GF_DecoderConfig *dcd; + GF_ESD *esd; char sdpLine[20000]; char mediaName[30], payloadName[30]; @@ -844,14 +844,14 @@ GF_Err gf_hinter_track_finalize(GF_RTPHinter *tkHint, Bool AddSystemInfo) } /*MPEG-4 decoder config*/ else if (tkHint->rtp_p->rtp_payt==GF_RTP_PAYT_MPEG4) { - dcd = gf_isom_get_decoder_config(tkHint->file, tkHint->TrackNum, 1); + esd = gf_isom_get_esd(tkHint->file, tkHint->TrackNum, 1); - if (dcd && dcd->decoderSpecificInfo && dcd->decoderSpecificInfo->data) { - gf_rtp_builder_format_sdp(tkHint->rtp_p, payloadName, sdpLine, dcd->decoderSpecificInfo->data, dcd->decoderSpecificInfo->dataLength); + if (esd && esd->decoderConfig && esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) { + gf_rtp_builder_format_sdp(tkHint->rtp_p, payloadName, sdpLine, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); } else { gf_rtp_builder_format_sdp(tkHint->rtp_p, payloadName, sdpLine, NULL, 0); } - if (dcd) gf_odf_desc_del((GF_Descriptor *)dcd); + if (esd) gf_odf_desc_del((GF_Descriptor *)esd); if (tkHint->rtp_p->slMap.IV_length) { const char *kms; @@ -881,12 +881,12 @@ GF_Err gf_hinter_track_finalize(GF_RTPHinter *tkHint, Bool AddSystemInfo) gf_bs_write_int(bs, 0, 3); /* numLayer */ /* audio-specific config */ - dcd = gf_isom_get_decoder_config(tkHint->file, tkHint->TrackNum, 1); - if (dcd) { + esd = gf_isom_get_esd(tkHint->file, tkHint->TrackNum, 1); + if (esd && esd->decoderConfig && esd->decoderConfig->decoderSpecificInfo) { /*PacketVideo patch: don't signal SBR and PS stuff, not allowed in LATM with audioMuxVersion=0*/ - gf_bs_write_data(bs, dcd->decoderSpecificInfo->data, MIN(dcd->decoderSpecificInfo->dataLength, 2) ); - gf_odf_desc_del((GF_Descriptor *)dcd); + gf_bs_write_data(bs, esd->decoderConfig->decoderSpecificInfo->data, MIN(esd->decoderConfig->decoderSpecificInfo->dataLength, 2) ); } + if (esd) gf_odf_desc_del((GF_Descriptor *)esd); /* other data */ gf_bs_write_int(bs, 0, 3); /* frameLengthType */ @@ -937,6 +937,22 @@ GF_Err gf_hinter_track_finalize(GF_RTPHinter *tkHint, Bool AddSystemInfo) gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); } + esd = gf_isom_get_esd(tkHint->file, tkHint->TrackNum, 1); + if (esd && esd->decoderConfig && (esd->decoderConfig->rvc_config || esd->decoderConfig->predefined_rvc_config)) { + if (esd->decoderConfig->predefined_rvc_config) { + sprintf(sdpLine, "a=rvc-config-predef:%d", esd->decoderConfig->predefined_rvc_config); + } else { + /*temporary ...*/ + if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_AVC) { + sprintf(sdpLine, "a=rvc-config:%s", "http://download.tsi.telecom-paristech.fr/gpac/RVC/rvc_config_avc.xml"); + } else { + sprintf(sdpLine, "a=rvc-config:%s", "http://download.tsi.telecom-paristech.fr/gpac/RVC/rvc_config_sp.xml"); + } + } + gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); + } + if (esd) gf_odf_desc_del((GF_Descriptor *)esd); + gf_isom_set_track_enabled(tkHint->file, tkHint->HintTrack, 1); return GF_OK; } diff --git a/src/media_tools/isom_tools.c b/src/media_tools/isom_tools.c index 48b5f41..0b22a36 100644 --- a/src/media_tools/isom_tools.c +++ b/src/media_tools/isom_tools.c @@ -26,6 +26,7 @@ #include #include +#include #ifndef GPAC_DISABLE_ISOM @@ -609,30 +610,32 @@ GF_Err gf_media_make_psp(GF_ISOFile *mp4) typedef struct { + Bool done; u32 TrackID; u32 SampleNum, SampleCount; u32 FragmentLength; u32 OriginalTrack; - u32 TimeScale, MediaType, DefaultDuration; - u64 last_sample_cts; + u32 TimeScale, MediaType, DefaultDuration, InitialTSOffset; + u64 last_sample_cts, next_sample_dts; } TrackFragmenter; GF_EXPORT -GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_duration_sec, u32 dash_mode, Double dash_duration_sec, char *seg_rad_name, char *seg_ext, u32 fragments_per_sidx, Bool daisy_chain_sidx, Bool use_url_template) +GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_duration_sec, u32 dash_mode, Double dash_duration_sec, char *seg_rad_name, char *seg_ext, s32 fragments_per_sidx, Bool daisy_chain_sidx, Bool use_url_template, const char *dash_ctx_file) { u8 NbBits; - u32 i, TrackNum, descIndex, j, count, nb_sync, ref_track_id; + u32 i, TrackNum, descIndex, j, count, nb_sync, ref_track_id, nb_tracks_done; u32 defaultDuration, defaultSize, defaultDescriptionIndex, defaultRandomAccess, nb_samp, nb_done; u8 defaultPadding; u16 defaultDegradationPriority; GF_Err e; - u32 cur_seg; + char sOpt[100], sKey[100]; + u32 cur_seg, fragment_index; GF_ISOFile *output; GF_ISOSample *sample, *next; GF_List *fragmenters; u32 MaxFragmentDuration, MaxSegmentDuration, SegmentDuration, maxFragDurationOverSegment; - Double average_duration, file_duration; + Double average_duration, file_duration, period_duration, max_segment_duration; u32 nb_segments, width, height, sample_rate, nb_channels; char langCode[5]; Bool switch_segment = 0; @@ -642,13 +645,19 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_d Bool next_sample_rap = 0; Bool flush_all_samples = 0; u64 last_ref_cts = 0; - u64 start_range, end_range, file_size, init_seg_size; + u64 start_range, end_range, file_size, init_seg_size, ref_track_cur_dur; u32 tfref_timescale = 0; u32 bandwidth = 0; TrackFragmenter *tf, *tfref; FILE *mpd = NULL; FILE *mpd_segs = NULL; char *SegName = NULL; + const char *opt; + GF_Config *dash_ctx = NULL; + Bool store_dash_params = 0; + Bool dash_moov_setup = 0; + Bool segments_start_with_rap = 1; + Bool first_sample_in_segment = 0; SegmentDuration = 0; nb_samp = 0; fragmenters = NULL; @@ -656,17 +665,42 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_d //create output file if (dash_mode) { - u32 len = strlen(output_file); + u32 len; + + if (dash_ctx_file) { + dash_ctx = gf_cfg_new(NULL, dash_ctx_file); + if (!dash_ctx) { + FILE *t = fopen(dash_ctx_file, "wt"); + if (t) fclose(t); + dash_ctx = gf_cfg_new(NULL, dash_ctx_file); + + if (dash_ctx) store_dash_params=1; + } + } + len = strlen(output_file); len += 100; SegName = gf_malloc(sizeof(char)*len); if (!SegName) return GF_OUT_OF_MEM; - strcpy(SegName, output_file); - strcat(SegName, ".mp4"); - output = gf_isom_open(SegName, GF_ISOM_OPEN_WRITE, NULL); + + opt = dash_ctx ? gf_cfg_get_key(dash_ctx, "DASH", "InitializationSegment") : NULL; + if (opt) { + output = gf_isom_open(opt, GF_ISOM_OPEN_CAT_FRAGMENTS, NULL); + dash_moov_setup = 1; + } else { + strcpy(SegName, output_file); + strcat(SegName, ".mp4"); + output = gf_isom_open(SegName, GF_ISOM_OPEN_WRITE, NULL); + } if (!output) { e = gf_isom_last_error(NULL); goto err_exit; } + + if (store_dash_params) { + gf_cfg_set_key(dash_ctx, "DASH", "InitializationSegment", SegName); + } + + strcpy(SegName, output_file); strcat(SegName, ".mpd"); mpd = gf_f64_open(SegName, "wt"); @@ -680,8 +714,10 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_d nb_samp = 0; fragmenters = gf_list_new(); - e = gf_isom_clone_movie(input, output, 0, 0); - if (e) goto err_exit; + if (! dash_moov_setup) { + e = gf_isom_clone_movie(input, output, 0, 0); + if (e) goto err_exit; + } MaxFragmentDuration = (u32) (max_duration_sec * 1000); MaxSegmentDuration = (u32) (dash_duration_sec * 1000); @@ -693,78 +729,114 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_d //duplicates all tracks for (i=0; iTrackID = gf_isom_get_track_id(output, TrackNum); - tf->SampleCount = gf_isom_get_sample_count(input, i+1); - tf->OriginalTrack = i+1; - tf->TimeScale = gf_isom_get_media_timescale(input, i+1); - tf->MediaType = gf_isom_get_media_type(input, i+1); - tf->DefaultDuration = defaultDuration; + } else { + gf_isom_get_fragment_defaults(output, TrackNum, + &defaultDuration, &defaultSize, &defaultDescriptionIndex, &defaultRandomAccess, &defaultPadding, &defaultDegradationPriority); + } - if (gf_isom_get_sync_point_count(input, i+1)>nb_sync) { - tfref = tf; - tfref_timescale = tf->TimeScale; - nb_sync = gf_isom_get_sync_point_count(input, i+1); - } + GF_SAFEALLOC(tf, TrackFragmenter); + tf->TrackID = gf_isom_get_track_id(output, TrackNum); + tf->SampleCount = gf_isom_get_sample_count(input, i+1); + tf->OriginalTrack = i+1; + tf->TimeScale = gf_isom_get_media_timescale(input, i+1); + tf->MediaType = gf_isom_get_media_type(input, i+1); + tf->DefaultDuration = defaultDuration; + + if (gf_isom_get_sync_point_count(input, i+1)>nb_sync) { + tfref = tf; + nb_sync = gf_isom_get_sync_point_count(input, i+1); + } - switch (mtype) { - case GF_ISOM_MEDIA_TEXT: - gf_isom_get_media_language(input, i+1, langCode); - case GF_ISOM_MEDIA_VISUAL: - case GF_ISOM_MEDIA_SCENE: - case GF_ISOM_MEDIA_DIMS: - gf_isom_get_track_layout_info(input, i+1, &_w, &_h, NULL, NULL, NULL); - if (_w>width) width = _w; - if (_h>height) height = _h; - break; - case GF_ISOM_MEDIA_AUDIO: - gf_isom_get_audio_info(input, i+1, 1, &_sr, &_nb_ch, NULL); - if (_sr>sample_rate) sample_rate=_sr; - if (_nb_ch>nb_channels) nb_channels = _nb_ch; - gf_isom_get_media_language(input, i+1, langCode); - break; + /*figure out if we have an initial TS*/ + if (!dash_moov_setup) { + if (gf_isom_get_edit_segment_count(input, i+1)) { + u64 EditTime, SegmentDuration, MediaTime; + u8 EditMode; + gf_isom_get_edit_segment(input, i+1, 1, &EditTime, &SegmentDuration, &MediaTime, &EditMode); + if (EditMode==GF_ISOM_EDIT_EMPTY) { + tf->InitialTSOffset = (u32) (SegmentDuration * tf->TimeScale / gf_isom_get_timescale(input)); + } + /*and remove edit segments*/ + gf_isom_remove_edit_segments(output, TrackNum); } + } + /*restore track decode times*/ + else { + char *opt, sKey[100]; + sprintf(sKey, "TrackID_%d", tf->TrackID); + opt = (char *)gf_cfg_get_key(dash_ctx, sKey, "NextDecodingTime"); + if (opt) tf->InitialTSOffset = atoi(opt); + } - if (file_duration < ((Double) gf_isom_get_media_duration(input, i+1)) / tf->TimeScale ) { - file_duration = ((Double) gf_isom_get_media_duration(input, i+1)) / tf->TimeScale; + switch (mtype) { + case GF_ISOM_MEDIA_TEXT: + gf_isom_get_media_language(input, i+1, langCode); + case GF_ISOM_MEDIA_VISUAL: + if (!tfref && (count >=10)) { + tfref = tf; } - gf_list_add(fragmenters, tf); - nb_samp += count; + case GF_ISOM_MEDIA_SCENE: + case GF_ISOM_MEDIA_DIMS: + gf_isom_get_track_layout_info(input, i+1, &_w, &_h, NULL, NULL, NULL); + if (_w>width) width = _w; + if (_h>height) height = _h; + break; + case GF_ISOM_MEDIA_AUDIO: + gf_isom_get_audio_info(input, i+1, 1, &_sr, &_nb_ch, NULL); + if (_sr>sample_rate) sample_rate=_sr; + if (_nb_ch>nb_channels) nb_channels = _nb_ch; + gf_isom_get_media_language(input, i+1, langCode); + break; } - if (gf_isom_is_track_in_root_od(input, i+1)) gf_isom_add_track_to_root_od(output, TrackNum); + if (file_duration < ((Double) gf_isom_get_media_duration(input, i+1)) / tf->TimeScale ) { + file_duration = ((Double) gf_isom_get_media_duration(input, i+1)) / tf->TimeScale; + } + gf_list_add(fragmenters, tf); + nb_samp += count; } if (!tfref) tfref = gf_list_get(fragmenters, 0); + tfref_timescale = tfref->TimeScale; ref_track_id = tfref->TrackID; //flush movie @@ -776,29 +848,71 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_d file_size = end_range; init_seg_size = end_range; + if (dash_ctx) { + if (store_dash_params) { + char szVal[1024]; + sprintf(szVal, LLU, init_seg_size); + gf_cfg_set_key(dash_ctx, "DASH", "InitializationSegmentSize", szVal); + } else { + const char *opt = gf_cfg_get_key(dash_ctx, "DASH", "InitializationSegmentSize"); + if (opt) init_seg_size = atoi(opt); + } + } + average_duration = 0; nb_segments = 0; + nb_tracks_done = 0; + ref_track_cur_dur = tfref ? tfref->InitialTSOffset : 0; nb_done = 0; - cur_seg=1; + maxFragDurationOverSegment=0; if (dash_mode) switch_segment=1; if (!seg_rad_name) use_url_template = 0; + cur_seg=1; + fragment_index=1; + period_duration = 0; + /*setup previous URL list*/ + if (dash_ctx) { + const char *opt; + count = gf_cfg_get_key_count(dash_ctx, "URLs"); + for (i=0; i\n", SegName); + if (dash_ctx) { + char szKey[100], szVal[4046]; + sprintf(szKey, "UrlInfo%d", gf_cfg_get_key_count(dash_ctx, "URLs") + 1 ); + sprintf(szVal, "", SegName); + gf_cfg_set_key(dash_ctx, "URLs", szKey, szVal); + } } } else { e = gf_isom_start_segment(output, NULL); @@ -812,6 +926,12 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_d if (e) goto err_exit; sample = NULL; + for (i=0; idone) continue; + gf_isom_set_traf_base_media_decode_time(output, tf->TrackID, tf->InitialTSOffset + tf->next_sample_dts); + } + //process track by track for (i=0; idone) continue; //ok write samples while (1) { @@ -846,6 +967,12 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_d defaultDuration = tf->DefaultDuration; } + if (segments_start_with_rap && first_sample_in_segment && (tf==tfref)) { + first_sample_in_segment = 0; + if (!sample->IsRAP) segments_start_with_rap = 0; + } + + e = gf_isom_fragment_add_sample(output, tf->TrackID, sample, descIndex, defaultDuration, NbBits, 0); if (e) @@ -860,6 +987,7 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_d nb_done++; tf->last_sample_cts = sample->DTS + sample->CTS_Offset; + tf->next_sample_dts = sample->DTS + defaultDuration; gf_isom_sample_del(&sample); sample = next; @@ -919,10 +1047,8 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_d } if (tf->SampleNum==tf->SampleCount) { - gf_free(tf); - gf_list_rem(fragmenters, i); - i--; - count --; + tf->done = 1; + nb_tracks_done++; if (tf == tfref) { tfref = NULL; flush_all_samples = 1; @@ -938,6 +1064,11 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_d if ((SegmentDuration >= MaxSegmentDuration) && (!split_seg_at_rap || next_sample_rap)) { average_duration += SegmentDuration; nb_segments++; + if (max_segment_duration * 1000 <= SegmentDuration) { + max_segment_duration = SegmentDuration; + max_segment_duration /= 1000; + } + #if 0 if (split_seg_at_rap) has_rap = 0; @@ -955,12 +1086,19 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_d /*restore fragment duration*/ MaxFragmentDuration = (u32) (max_duration_sec * 1000); - gf_isom_close_segment(output, fragments_per_sidx, ref_track_id, NULL, 0, daisy_chain_sidx); - + gf_isom_close_segment(output, fragments_per_sidx, ref_track_id, ref_track_cur_dur, daisy_chain_sidx, flush_all_samples ? 1 : 0); + if (tfref) ref_track_cur_dur = tfref->InitialTSOffset + tfref->next_sample_dts; if (!seg_rad_name) { file_size = end_range = gf_isom_get_file_size(output); fprintf(mpd_segs, " \n", start_range, end_range); + if (dash_ctx) { + char szKey[100], szVal[4046]; + sprintf(szKey, "UrlInfo%d", gf_cfg_get_key_count(dash_ctx, "URLs") + 1 ); + sprintf(szVal, "", start_range, end_range); + gf_cfg_set_key(dash_ctx, "URLs", szKey, szVal); + + } } else { file_size += gf_isom_get_file_size(output); } @@ -971,6 +1109,8 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_d split_at_rap = 1; } } + + if (nb_tracks_done==count) break; } @@ -982,22 +1122,39 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_d /*flush last segment*/ if (!switch_segment) { - gf_isom_close_segment(output, fragments_per_sidx, ref_track_id, NULL, 0, daisy_chain_sidx); + if (max_segment_duration * 1000 <= SegmentDuration) { + max_segment_duration = SegmentDuration; + max_segment_duration /= 1000; + } + if (!split_at_rap) { + assert(max_segment_duration <= dash_duration_sec); + } + + gf_isom_close_segment(output, fragments_per_sidx, ref_track_id, ref_track_cur_dur, daisy_chain_sidx, 1); nb_segments++; if (!seg_rad_name) { file_size = end_range = gf_isom_get_file_size(output); fprintf(mpd_segs, " \n", start_range, end_range); - } else { - if (use_url_template) { - sprintf(SegName, "%s_seg$Index$.%s", seg_rad_name, seg_ext); - fprintf(mpd_segs, " \n", SegName, nb_segments); + + if (dash_ctx) { + char szKey[100], szVal[4046]; + sprintf(szKey, "UrlInfo%d", gf_cfg_get_key_count(dash_ctx, "URLs") + 1 ); + sprintf(szVal, "", start_range, end_range); + gf_cfg_set_key(dash_ctx, "URLs", szKey, szVal); } + } else { file_size += gf_isom_get_file_size(output); } } - h = (u32) (file_duration/3600); - m = (u32) (file_duration-h*60)/60; - s = file_duration - h*3600 - m*60; + + if (use_url_template) { + sprintf(SegName, "%s_seg$Index$.%s", seg_rad_name, seg_ext); + fprintf(mpd_segs, " \n", SegName, cur_seg-1); + } + period_duration += file_duration; + h = (u32) (period_duration/3600); + m = (u32) (period_duration-h*60)/60; + s = period_duration - h*3600 - m*60; bandwidth = (u32) (file_size * 8 / file_duration); fprintf(mpd, "\n"); @@ -1009,14 +1166,34 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_d if (width && height) fprintf(mpd, " width=\"%d\" height=\"%d\"", width, height); if (sample_rate && nb_channels) fprintf(mpd, " sampleRate=\"%d\" numChannels=\"%d\"", sample_rate, nb_channels); if (langCode[0]) fprintf(mpd, " lang=\"%s\"", langCode); - fprintf(mpd, " startWithRAP=\"%s\"", split_seg_at_rap ? "true" : "false"); + fprintf(mpd, " startWithRAP=\"%s\"", (segments_start_with_rap || split_seg_at_rap) ? "true" : "false"); fprintf(mpd, " bandwidth=\"%d\"", bandwidth); + /*what should we put here ?? */ + fprintf(mpd, " minBufferTime=\"%d\"", MaxFragmentDuration); fprintf(mpd, ">\n"); - h = (u32) (dash_duration_sec/3600); - m = (u32) (dash_duration_sec-h*60)/60; - s = dash_duration_sec - h*3600 - m*60; + if (dash_ctx) { + Double seg_dur; + opt = gf_cfg_get_key(dash_ctx, "DASH", "MaxSegmentDuration"); + if (opt) { + seg_dur = atof(opt); + if (seg_dur < max_segment_duration) { + sprintf(sOpt, "%f", max_segment_duration); + gf_cfg_set_key(dash_ctx, "DASH", "MaxSegmentDuration", sOpt); + seg_dur = max_segment_duration; + } else { + max_segment_duration = seg_dur; + } + } else { + sprintf(sOpt, "%f", max_segment_duration); + gf_cfg_set_key(dash_ctx, "DASH", "MaxSegmentDuration", sOpt); + } + } + + h = (u32) (max_segment_duration / 3600); + m = (u32) (max_segment_duration - h*60)/60; + s = max_segment_duration - h*3600 - m*60; if (m) { fprintf(mpd, " "); } + /*store context*/ + if (dash_ctx) { + for (i=0; iTrackID); + sprintf(sOpt, LLU, tf->InitialTSOffset + tf->next_sample_dts); + gf_cfg_set_key(dash_ctx, sKey, "NextDecodingTime", sOpt); + } + sprintf(sOpt, "%d", cur_seg); + gf_cfg_set_key(dash_ctx, "DASH", "NextSegmentIndex", sOpt); + + fragment_index = gf_isom_get_next_moof_number(output); + sprintf(sOpt, "%d", fragment_index); + gf_cfg_set_key(dash_ctx, "DASH", "NextFragmentIndex", sOpt); + sprintf(sOpt, "%f", period_duration); + gf_cfg_set_key(dash_ctx, "DASH", "PeriodDuration", sOpt); + } + err_exit: if (fragmenters){ while (gf_list_count(fragmenters)) { @@ -1059,6 +1255,7 @@ err_exit: if (SegName) gf_free(SegName); if (mpd) fclose(mpd); if (mpd_segs) fclose(mpd_segs); + if (dash_ctx) gf_cfg_del(dash_ctx); return e; } diff --git a/src/media_tools/m2ts_mux.c b/src/media_tools/m2ts_mux.c index 3ebefdb..f60671e 100644 --- a/src/media_tools/m2ts_mux.c +++ b/src/media_tools/m2ts_mux.c @@ -28,6 +28,17 @@ #ifndef GPAC_DISABLE_MPEG2TS_MUX +/*num ms between PCR*/ +#define PCR_UPDATE_MS 200 +/*90khz internal delay between two updates for instant bitrate compute per stream*/ +#define BITRATE_UPDATE_WINDOW 90000 +/* length of adaptation_field_length; */ +#define ADAPTATION_LENGTH_LENGTH 1 +/* discontinuty flag, random access flag ... */ +#define ADAPTATION_FLAGS_LENGTH 1 +/* length of encoded pcr */ +#define PCR_LENGTH 6 + static GFINLINE Bool gf_m2ts_time_less(GF_M2TS_Time *a, GF_M2TS_Time *b) { if (a->sec>b->sec) return 0; @@ -117,6 +128,8 @@ void gf_m2ts_mux_table_update(GF_M2TS_Mux_Stream *stream, u8 table_id, u16 table case GF_M2TS_TABLE_ID_PAT: case GF_M2TS_TABLE_ID_SDT_ACTUAL: case GF_M2TS_TABLE_ID_SDT_OTHER: + case GF_M2TS_TABLE_ID_TDT: + case GF_M2TS_TABLE_ID_TOT: case GF_M2TS_TABLE_ID_BAT: maxSectionLength = 1024; break; @@ -222,15 +235,23 @@ void gf_m2ts_mux_table_update_bitrate(GF_M2TS_Mux *mux, GF_M2TS_Mux_Stream *stre while (table) { GF_M2TS_Mux_Section *section = table->section; while (section) { - stream->bit_rate += section->length; + u32 nb_bytes = 0; + while (nb_byteslength) nb_bytes += 188; + stream->bit_rate += nb_bytes; section = section->next; } table = table->next; } stream->bit_rate *= 8; - if (!stream->refresh_rate_ms) stream->refresh_rate_ms = 500; stream->bit_rate *= 1000; - stream->bit_rate /= stream->refresh_rate_ms; + if (stream->refresh_rate_ms) { + stream->bit_rate /= stream->refresh_rate_ms; + } else if (stream->table_needs_send) { + /*no clue ... */ + stream->bit_rate /= 100; + } else { + stream->bit_rate = 0; + } } void gf_m2ts_mux_table_update_mpeg4(GF_M2TS_Mux_Stream *stream, u8 table_id, u16 table_id_extension, @@ -285,14 +306,14 @@ void gf_m2ts_mux_table_update_mpeg4(GF_M2TS_Mux_Stream *stream, u8 table_id, u16 section_number = 0; nb_sections = 1; hdr = stream->sl_header; - sl_size = gf_sl_get_header_size(&stream->sl_config, &hdr); + sl_size = gf_sl_get_header_size(stream->ifce->sl_config, &hdr); /*SL-packetized data doesn't fit in one section, we must repacketize*/ if (sl_size + table_payload_length > maxSectionLength - overhead_size) { nb_sections = 0; offset = 0; hdr.accessUnitEndFlag = 0; while (offsetsl_config, &hdr); + sl_size = gf_sl_get_header_size(stream->ifce->sl_config, &hdr); /*remove start flag*/ hdr.accessUnitStartFlag = 0; /*fill each section but beware of last packet*/ @@ -310,7 +331,7 @@ void gf_m2ts_mux_table_update_mpeg4(GF_M2TS_Mux_Stream *stream, u8 table_id, u16 GF_SAFEALLOC(section, GF_M2TS_Mux_Section); hdr.accessUnitEndFlag = (section_number+1==nb_sections) ? stream->sl_header.accessUnitEndFlag : 0; - gf_sl_packetize(&stream->sl_config, &hdr, NULL, 0, &slhdr, &slhdr_size); + gf_sl_packetize(stream->ifce->sl_config, &hdr, NULL, 0, &slhdr, &slhdr_size); hdr.accessUnitStartFlag = 0; remain = table_payload_length - offset; @@ -372,25 +393,13 @@ void gf_m2ts_mux_table_update_mpeg4(GF_M2TS_Mux_Stream *stream, u8 table_id, u16 stream->current_table = stream->tables; stream->current_section = stream->current_table->section; stream->current_section_offset = 0; + stream->table_needs_send = 1; GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Generating %d sections for MPEG-4 SL packet - version number %d - extension ID %d\n", stream->pid, nb_sections, table->version_number, table_id_extension)); - if (stream->ifce->repeat_rate) { - stream->refresh_rate_ms = stream->ifce->repeat_rate; - gf_m2ts_mux_table_update_bitrate(stream->program->mux, stream); - } else { - gf_m2ts_mux_table_update_bitrate(stream->program->mux, stream); - stream->refresh_rate_ms=0; - } + /*MPEG-4 tables are input streams for the mux, the bitrate is updated when fetching AUs*/ } -/* length of adaptation_field_length; */ -#define ADAPTATION_LENGTH_LENGTH 1 -/* discontinuty flag, random access flag ... */ -#define ADAPTATION_FLAGS_LENGTH 1 -/* length of encoded pcr */ -#define PCR_LENGTH 6 - static u32 gf_m2ts_add_adaptation(GF_BitStream *bs, u16 pid, Bool has_pcr, u64 pcr_time, Bool is_rap, @@ -426,11 +435,8 @@ static u32 gf_m2ts_add_adaptation(GF_BitStream *bs, u16 pid, } - while (padding_length) { - gf_bs_write_u8(bs, 0xff); // stuffing byte - padding_length--; - } - + gf_bs_write_byte(bs, 0xFF, padding_length); // stuffing byte + return adaptation_length + ADAPTATION_LENGTH_LENGTH; } @@ -442,6 +448,7 @@ void gf_m2ts_mux_table_get_next_packet(GF_M2TS_Mux_Stream *stream, u8 *packet) u32 payload_length, padding_length; u8 adaptation_field_control; + stream->table_needs_send = 0; table = stream->current_table; assert(table); @@ -517,7 +524,8 @@ void gf_m2ts_mux_table_get_next_packet(GF_M2TS_Mux_Stream *stream, u8 *packet) if (stream->current_table) stream->current_section = stream->current_table->section; } } - + /*updates number of bytes sent for bitrate compute (MPEG4 sections)*/ + stream->bytes_since_last_time += 188; } @@ -542,9 +550,14 @@ Bool gf_m2ts_stream_process_pat(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream) gf_bs_del(bs); gf_m2ts_mux_table_update(stream, GF_M2TS_TABLE_ID_PAT, muxer->ts_id, payload, size, 1, 0, 0); stream->table_needs_update = 0; + stream->table_needs_send = 1; gf_free(payload); } - return 1; + if (stream->table_needs_send) + return 1; + if (stream->refresh_rate_ms) + return 1; + return 0; } Bool gf_m2ts_stream_process_pmt(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream) @@ -552,16 +565,27 @@ Bool gf_m2ts_stream_process_pmt(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream) if (stream->table_needs_update) { /* generate table payload */ GF_M2TS_Mux_Stream *es; u8 *payload; + u32 i; u32 length, nb_streams=0; + u32 info_length = 0; GF_BitStream *bs; + bs = gf_bs_new(NULL,0,GF_BITSTREAM_WRITE); gf_bs_write_int(bs, 0x7, 3); // reserved gf_bs_write_int(bs, stream->program->pcr->pid, 13); gf_bs_write_int(bs, 0xF, 4); // reserved + + if (stream->program->loop_descriptors) { + for (i=0; iprogram->loop_descriptors); i++) { + GF_M2TSDescriptor *desc = gf_list_get(stream->program->loop_descriptors, i); + info_length += 2 + desc->data_len; + } + } + if (!stream->program->iod) { - gf_bs_write_int(bs, 0, 12); // program info length =0 + gf_bs_write_int(bs, info_length, 12); // program info length =0 } else { u32 len, i; GF_ESD *esd; @@ -575,7 +599,8 @@ Bool gf_m2ts_stream_process_pmt(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream) GF_M2TS_Mux_Stream *es_stream = stream->program->streams; while (es_stream) { if (es_stream->ifce && (es_stream->ifce->stream_id==esd->ESID)) { - memcpy(esd->slConfig, &es_stream->sl_config, sizeof(GF_SLConfig)); + /*thay should be the same ...*/ + memcpy(esd->slConfig, es_stream->ifce->sl_config, sizeof(GF_SLConfig)); break; } es_stream = es_stream->next; @@ -588,7 +613,7 @@ Bool gf_m2ts_stream_process_pmt(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream) gf_bs_del(bs_iod); len = iod_data_len + 4; - gf_bs_write_int(bs, len, 12); // program info length + gf_bs_write_int(bs, len + info_length, 12); // program info length gf_bs_write_int(bs, GF_M2TS_MPEG4_IOD_DESCRIPTOR, 8); len = iod_data_len + 2; @@ -604,6 +629,17 @@ Bool gf_m2ts_stream_process_pmt(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream) gf_bs_write_data(bs, iod_data, iod_data_len); gf_free(iod_data); } + + /*write all other descriptors*/ + if (stream->program->loop_descriptors) { + for (i=0; iprogram->loop_descriptors); i++) { + GF_M2TSDescriptor *desc = gf_list_get(stream->program->loop_descriptors, i); + gf_bs_write_int(bs, desc->tag, 8); + gf_bs_write_int(bs, desc->data_len, 8); + gf_bs_write_data(bs, desc->data, desc->data_len); + } + } + es = stream->program->streams; while (es) { nb_streams++; @@ -613,7 +649,7 @@ Bool gf_m2ts_stream_process_pmt(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream) gf_bs_write_int(bs, 0xF, 4); // reserved /* Second Loop Descriptor */ - if (stream->program->iod) { + if (stream->program->iod && !(es->ifce->caps & GF_ESI_STREAM_WITHOUT_MPEG4_SYSTEMS)) { gf_bs_write_int(bs, 4, 12); // ES info length = 4 :only SL Descriptor gf_bs_write_int(bs, GF_M2TS_MPEG4_SL_DESCRIPTOR, 8); gf_bs_write_int(bs, 2, 8); @@ -629,42 +665,74 @@ Bool gf_m2ts_stream_process_pmt(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream) gf_m2ts_mux_table_update(stream, GF_M2TS_TABLE_ID_PMT, stream->program->number, payload, length, 1, 0, 0); stream->table_needs_update = 0; + stream->table_needs_send = 1; gf_free(payload); GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Updating PMT - Program Number %d - %d streams - size %d%s\n", stream->pid, stream->program->number, nb_streams, length, stream->program->iod ? " - MPEG-4 Systems detected":"")); } - return 1; + if (stream->table_needs_send) + return 1; + if (stream->refresh_rate_ms) + return 1; + return 0; } -static u32 gf_m2ts_stream_get_pes_header_length(GF_M2TS_Mux_Stream *stream) +static void gf_m2ts_remap_timestamps_for_pes(GF_M2TS_Mux_Stream *stream, u32 pck_flags, u64 *dts, u64 *cts) { - u32 hdr_len; - /*not the AU start*/ - if (stream->pck_offset || !(stream->curr_pck.flags & GF_ESI_DATA_AU_START) ) return 0; - hdr_len = 9; - if (stream->curr_pck.flags & GF_ESI_DATA_HAS_CTS) hdr_len += 5; - if (stream->curr_pck.flags & GF_ESI_DATA_HAS_DTS) hdr_len += 5; - return hdr_len; + u64 pcr_offset; + + /*Rescale our timestamps and express them in PCR*/ + if (stream->ts_scale) { + *cts = (u64) (stream->ts_scale * (s64) *cts); + *dts = (u64) (stream->ts_scale * (s64) *dts); + } + if (!stream->program->initial_ts_set) { + u32 nb_bits = (u32) (stream->program->mux->tot_pck_sent - stream->program->num_pck_at_pcr_init) * 1504; + u32 nb_ticks = 90000*nb_bits / stream->program->mux->bit_rate; + stream->program->initial_ts = *dts; + + if (stream->program->initial_ts > nb_ticks) + stream->program->initial_ts -= nb_ticks; + else + stream->program->initial_ts = 0; + + stream->program->initial_ts_set = 1; + } + else if (*dts < stream->program->initial_ts) { + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: DTS "LLD" is less than initial DTS "LLD" - adjusting\n", stream->pid, *dts, stream->program->initial_ts)); + stream->program->initial_ts = *dts; + } + + /*offset our timestamps*/ + *cts += stream->program->pcr_offset; + *dts += stream->program->pcr_offset; + + /*PCR offset, in 90000 hz not in 270000000*/ + pcr_offset = stream->program->pcr_init_time/300; + *cts = *cts - stream->program->initial_ts + pcr_offset; + *dts = *dts - stream->program->initial_ts + pcr_offset; } -Bool gf_m2ts_stream_process_stream(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream) +u32 gf_m2ts_stream_process_stream(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream) { - u64 pcr_offset; - u32 next_time; Bool ret = 0; if (stream->mpeg2_stream_type==GF_M2TS_SYSTEMS_MPEG4_SECTIONS) { + /*section has just been updated */ + if (stream->table_needs_send) + return stream->scheduling_priority; /*section is not completely sent yet or this is not the first section of the table*/ if (stream->current_section && (stream->current_section_offset || stream->current_section!=stream->current_table->section)) - return 1; + return stream->scheduling_priority; if (stream->ifce->repeat_rate && stream->tables) - ret = 1; + ret = stream->program->pcr_init_time ? stream->scheduling_priority : 0; } else if (stream->curr_pck.data_len && stream->pck_offset < stream->curr_pck.data_len) { /*PES packet not completely sent yet*/ - return 1; + return stream->scheduling_priority + stream->pcr_priority; } + stream->pcr_priority = 0; /*PULL mode*/ if (stream->ifce->caps & GF_ESI_AU_PULL_CAP) { if (stream->curr_pck.data_len) { @@ -678,12 +746,15 @@ Bool gf_m2ts_stream_process_stream(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *strea stream->discard_data = 0; /*EOS*/ - if (stream->ifce->caps & GF_ESI_STREAM_IS_OVER) return 0; + if (stream->ifce->caps & GF_ESI_STREAM_IS_OVER) return ret; assert( stream->ifce->input_ctrl); stream->ifce->input_ctrl(stream->ifce, GF_ESI_INPUT_DATA_PULL, &stream->curr_pck); } else { GF_M2TS_Packet *curr_pck; + if (!stream->pck_first && (stream->ifce->caps & GF_ESI_STREAM_IS_OVER)) + return ret; + /*flush input pipe*/ if (stream->ifce->input_ctrl) stream->ifce->input_ctrl(stream->ifce, GF_ESI_INPUT_DATA_FLUSH, NULL); @@ -711,22 +782,20 @@ Bool gf_m2ts_stream_process_stream(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *strea gf_mx_v(stream->mx); } + if (!(stream->curr_pck.flags & GF_ESI_DATA_HAS_DTS)) stream->curr_pck.dts = stream->curr_pck.cts; - /*Rescale our timestamps and express them in PCR*/ - if (stream->ts_scale) { - stream->curr_pck.cts = (u64) (stream->ts_scale * (s64) stream->curr_pck.cts); - stream->curr_pck.dts = (u64) (stream->ts_scale * (s64) stream->curr_pck.dts); - } /*initializing the PCR*/ if (!stream->program->pcr_init_time) { if (stream==stream->program->pcr) { - while (!stream->program->pcr_init_time) - stream->program->pcr_init_time = gf_rand(); - - stream->program->pcr_init_time = 1; + if (stream->program->mux->init_pcr_value) { + stream->program->pcr_init_time = stream->program->mux->init_pcr_value; + } else { + while (!stream->program->pcr_init_time) + stream->program->pcr_init_time = gf_rand(); + } stream->program->ts_time_at_pcr_init = muxer->time; stream->program->num_pck_at_pcr_init = muxer->tot_pck_sent; @@ -737,15 +806,6 @@ Bool gf_m2ts_stream_process_stream(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *strea return 0; } } - if (!stream->initial_ts) { - u32 nb_bits = (u32) (muxer->tot_pck_sent - stream->program->num_pck_at_pcr_init) * 1504; - u32 nb_ticks = 90000*nb_bits / muxer->bit_rate; - stream->initial_ts = stream->curr_pck.dts; - if (stream->initial_ts > nb_ticks) - stream->initial_ts -= nb_ticks; - else - stream->initial_ts = 0; - } /*SL-encapsultaion*/ switch (stream->mpeg2_stream_type) { @@ -795,7 +855,7 @@ Bool gf_m2ts_stream_process_stream(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *strea stream->curr_pck.data_len = 0; stream->curr_pck.data = NULL; - gf_sl_packetize(&stream->sl_config, &stream->sl_header, src_data, src_data_len, &stream->curr_pck.data, &stream->curr_pck.data_len); + gf_sl_packetize(stream->ifce->sl_config, &stream->sl_header, src_data, src_data_len, &stream->curr_pck.data, &stream->curr_pck.data_len); /*discard src data*/ if (!(stream->ifce->caps & GF_ESI_AU_PULL_CAP)) { @@ -810,7 +870,7 @@ Bool gf_m2ts_stream_process_stream(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *strea /*perform LATM encapsulation*/ case GF_M2TS_AUDIO_LATM_AAC: { - u32 size; + u32 size, next_time; GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_int(bs, 0x2B7, 11); gf_bs_write_int(bs, 0, 13); @@ -850,11 +910,13 @@ Bool gf_m2ts_stream_process_stream(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *strea break; } } + stream->reframe_overhead = stream->curr_pck.data_len; gf_bs_write_data(bs, stream->curr_pck.data, stream->curr_pck.data_len); gf_bs_align(bs); gf_free(stream->curr_pck.data); gf_bs_get_content(bs, &stream->curr_pck.data, &stream->curr_pck.data_len); gf_bs_del(bs); + stream->reframe_overhead = stream->curr_pck.data_len - stream->reframe_overhead; /*rewrite LATM frame header*/ size = stream->curr_pck.data_len - 2; @@ -889,90 +951,204 @@ Bool gf_m2ts_stream_process_stream(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *strea gf_free(stream->curr_pck.data); gf_bs_get_content(bs, &stream->curr_pck.data, &stream->curr_pck.data_len); gf_bs_del(bs); + /*constant reframe overhead*/ + stream->reframe_overhead = 7; } /*since we reallocated the packet data buffer, force a discard in pull mode*/ stream->discard_data = 1; break; } + /*rewrite timestamps for PES header*/ + gf_m2ts_remap_timestamps_for_pes(stream, stream->curr_pck.flags, &stream->curr_pck.dts, &stream->curr_pck.cts); + /*compute next interesting time in TS unit: this will be DTS of next packet*/ - next_time = (u32) (stream->curr_pck.dts - stream->initial_ts); - /*we need to take into account transmission time, eg nb packets to send the data*/ - if (next_time) { - u32 nb_pck, bytes, nb_bits, nb_ticks; - bytes = 184 - ADAPTATION_LENGTH_LENGTH - ADAPTATION_FLAGS_LENGTH - PCR_LENGTH; - bytes -= gf_m2ts_stream_get_pes_header_length(stream); - nb_pck=1; - while (bytescurr_pck.data_len) { - bytes+=184; - nb_pck++; + stream->time = stream->program->ts_time_at_pcr_init; + gf_m2ts_time_inc(&stream->time, (u32) stream->curr_pck.dts, 90000); + + /*do we need to send a PCR*/ + if (stream == stream->program->pcr) { + if (muxer->real_time) { + if (gf_sys_clock() > stream->program->last_sys_clock + PCR_UPDATE_MS) + stream->pcr_priority = 1; + } else { + if (!stream->program->last_dts || (stream->curr_pck.dts > stream->program->last_dts + PCR_UPDATE_MS*90)) + stream->pcr_priority = 1; } - nb_bits = nb_pck * 1504; - nb_ticks = 90000*nb_bits / muxer->bit_rate; - if (next_time>nb_ticks) - next_time -= nb_ticks; - else - next_time = 0; } + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Next data schedule for %d:%09d - mux time %d:%09d\n", stream->pid, stream->time.sec, stream->time.nanosec, muxer->time.sec, muxer->time.nanosec)); - stream->time = stream->program->ts_time_at_pcr_init; - gf_m2ts_time_inc(&stream->time, next_time, 90000); + /*compute instant bitrate*/ + if (!stream->last_br_time) { + stream->last_br_time = stream->curr_pck.dts + 1; + stream->bytes_since_last_time = 0; + stream->pes_since_last_time = 0; + } else { + u32 time_diff = (u32) (stream->curr_pck.dts - stream->last_br_time - 1 ); + if ((stream->pes_since_last_time > 4) && (time_diff >= BITRATE_UPDATE_WINDOW)) { + u32 bitrate; + u64 r = 8*stream->bytes_since_last_time; + r*=90000; + bitrate = (u32) (r / time_diff); + stream->bit_rate = bitrate; + stream->last_br_time = 0; + stream->bytes_since_last_time = 0; + stream->pes_since_last_time = 0; + stream->program->mux->needs_reconfig = 1; + } + } + stream->pes_since_last_time ++; + return stream->scheduling_priority + stream->pcr_priority; +} - /*PCR offset, in 90000 hz not in 270000000*/ - pcr_offset = stream->program->pcr_init_time/300; - stream->curr_pck.cts = stream->curr_pck.cts - stream->initial_ts + pcr_offset; - stream->curr_pck.dts = stream->curr_pck.dts - stream->initial_ts + pcr_offset; +static GFINLINE u64 gf_m2ts_get_pcr(GF_M2TS_Mux_Program *program) +{ + u32 nb_pck = (u32) (program->mux->tot_pck_sent - program->num_pck_at_pcr_init); + u64 pcr = 27000000; + pcr *= nb_pck*1504; + pcr /= program->mux->bit_rate; + pcr += program->pcr_init_time; + return pcr; +} - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Next data schedule for %d:%09d - mux time %d:%09d\n", stream->pid, stream->time.sec, stream->time.nanosec, muxer->time.sec, muxer->time.nanosec)); +void gf_m2ts_stream_update_data_following(GF_M2TS_Mux_Stream *stream) +{ + stream->next_payload_size = 0; + stream->copy_from_next_packets = 0; + + if (stream->program->mux->one_au_per_pes) return; + switch (stream->mpeg2_stream_type) { + /*the following stream types do not allow PES boundaries at any place on their payload*/ + case GF_M2TS_SYSTEMS_MPEG4_PES: + /*one and only one SL per PES: we cannot concatenate*/ + return; + default: + break; + } + if (stream->ifce->caps & GF_ESI_AU_PULL_CAP) { + GF_ESIPacket test_pck; + test_pck.data_len = 0; + /*pull next data but do not release it since it might be needed later on*/ + stream->ifce->input_ctrl(stream->ifce, GF_ESI_INPUT_DATA_PULL, &test_pck); + if (test_pck.data_len) { + stream->next_payload_size = test_pck.data_len; + stream->next_pck_flags = test_pck.flags; + stream->next_pck_cts = test_pck.cts; + stream->next_pck_dts = test_pck.dts; + } + } else { + /*flush input*/ + if (!stream->pck_first && stream->ifce->input_ctrl) stream->ifce->input_ctrl(stream->ifce, GF_ESI_INPUT_DATA_FLUSH, NULL); + if (stream->pck_first) { + stream->next_payload_size = stream->pck_first->data_len; + stream->next_pck_cts = stream->pck_first->cts; + stream->next_pck_dts = stream->pck_first->dts; + stream->next_pck_flags = stream->pck_first->flags; + } + } + if (stream->next_payload_size) { + stream->next_payload_size += stream->reframe_overhead; - /*compute bitrate if needed*/ - if (!stream->bit_rate) { - if (!stream->last_br_time) { - stream->last_br_time = stream->curr_pck.dts + 1; - stream->bytes_since_last_time = stream->curr_pck.data_len; - } else { - if (stream->curr_pck.dts - stream->last_br_time - 1 >= 90000) { - u64 r = 8*stream->bytes_since_last_time; - r*=90000; - stream->bit_rate = (u32) (r / (stream->curr_pck.dts - stream->last_br_time - 1)); - stream->program->mux->needs_reconfig = 1; - } else { - stream->bytes_since_last_time += stream->curr_pck.data_len; + gf_m2ts_remap_timestamps_for_pes(stream, stream->next_pck_flags, &stream->next_pck_dts, &stream->next_pck_cts); + } +} + + +Bool gf_m2ts_stream_compute_pes_length(GF_M2TS_Mux_Stream *stream, u32 payload_length) +{ + stream->copy_from_next_packets = 0; + stream->next_payload_size = 0; + + gf_m2ts_stream_update_data_following(stream); + + assert(stream->pes_data_remain==0); + stream->pes_data_len = stream->curr_pck.data_len - stream->pck_offset; + +// stream->next_payload_size = 0; + /*if we have next payload ready, compute transmitted size*/ + if (stream->next_payload_size) { + u32 pck_size = stream->curr_pck.data_len - stream->pck_offset; + u32 ts_bytes = payload_length; + + /*flushing end of previous PES, let's put the entire next AU in it*/ + if (pck_size<=ts_bytes) { + while (ts_bytes < pck_size + stream->next_payload_size) { + ts_bytes += 184; + } + } + /*needs several TS packets to send the PES, don't attempt to stick in the entire next AU*/ + else { + while (ts_bytes < pck_size) { + ts_bytes += 184; + } + } + /*that's how much bytes we copy from the following AUs*/ + stream->copy_from_next_packets = ts_bytes - pck_size; + + if (stream->ifce->caps & GF_ESI_STREAM_IS_OVER) { + while (stream->copy_from_next_packets > stream->next_payload_size) { + if (stream->copy_from_next_packets < 184) { + stream->copy_from_next_packets = 0; + break; + } + stream->copy_from_next_packets -= 184; } } + stream->pes_data_len += stream->copy_from_next_packets; } + stream->pes_data_remain = stream->pes_data_len; return 1; } -static GFINLINE u64 gf_m2ts_get_pcr(GF_M2TS_Mux_Program *program) + +static u32 gf_m2ts_stream_get_pes_header_length(GF_M2TS_Mux_Stream *stream) { - u32 nb_pck = (u32) (program->mux->tot_pck_sent - program->num_pck_at_pcr_init); - u64 pcr = 27000000; - pcr *= nb_pck*1504; - pcr /= program->mux->bit_rate; - pcr += program->pcr_init_time; - return pcr; + u32 hdr_len, flags; + flags = stream->pck_offset ? stream->next_pck_flags : stream->curr_pck.flags; + + if (stream->pes_data_remain) return 0; + /*not the AU start*/ + if ( !(flags & GF_ESI_DATA_AU_START) ) + return 0; + + hdr_len = 9; + if (flags & GF_ESI_DATA_HAS_CTS) hdr_len += 5; + if (flags & GF_ESI_DATA_HAS_DTS) hdr_len += 5; + return hdr_len; } -u32 gf_m2ts_stream_add_pes_header(GF_BitStream *bs, GF_M2TS_Mux_Stream *stream) +u32 gf_m2ts_stream_add_pes_header(GF_BitStream *bs, GF_M2TS_Mux_Stream *stream, u32 payload_length) { - u64 t; + u64 t, dts, cts; u32 pes_len; Bool use_pts, use_dts; gf_bs_write_int(bs, 0x1, 24);//packet start code gf_bs_write_u8(bs, stream->mpeg2_stream_id);// stream id - use_pts = (stream->curr_pck.flags & GF_ESI_DATA_HAS_CTS) ? 1 : 0; - use_dts = (stream->curr_pck.flags & GF_ESI_DATA_HAS_DTS) ? 1 : 0; + /*next AU start in current PES and current AU began in previous PES, use next AU timing*/ + if (stream->pck_offset && stream->copy_from_next_packets) { + use_pts = (stream->next_pck_flags & GF_ESI_DATA_HAS_CTS) ? 1 : 0; + use_dts = (stream->next_pck_flags & GF_ESI_DATA_HAS_DTS) ? 1 : 0; + dts = stream->next_pck_dts; + cts = stream->next_pck_cts; + } else { + use_pts = (stream->curr_pck.flags & GF_ESI_DATA_HAS_CTS) ? 1 : 0; + use_dts = (stream->curr_pck.flags & GF_ESI_DATA_HAS_DTS) ? 1 : 0; + dts = stream->curr_pck.dts; + cts = stream->curr_pck.cts; + } - pes_len = stream->curr_pck.data_len + 3; // 3 = header size + assert(stream->pes_data_len); + pes_len = stream->pes_data_len + 3; // 3 = header size if (use_pts) pes_len += 5; if (use_dts) pes_len += 5; + + if (pes_len>0xFFFF) pes_len = 0; gf_bs_write_int(bs, pes_len, 16); // pes packet length gf_bs_write_int(bs, 0x2, 2); // reserved @@ -990,73 +1166,97 @@ u32 gf_m2ts_stream_add_pes_header(GF_BitStream *bs, GF_M2TS_Mux_Stream *stream) if (use_pts) { gf_bs_write_int(bs, use_dts ? 0x3 : 0x2, 4); // reserved '0011' || '0010' - t = ((stream->curr_pck.cts >> 30) & 0x7); + t = ((cts >> 30) & 0x7); gf_bs_write_long_int(bs, t, 3); gf_bs_write_int(bs, 1, 1); // marker bit - t = ((stream->curr_pck.cts >> 15) & 0x7fff); + t = ((cts >> 15) & 0x7fff); gf_bs_write_long_int(bs, t, 15); gf_bs_write_int(bs, 1, 1); // marker bit - t = stream->curr_pck.cts & 0x7fff; + t = cts & 0x7fff; gf_bs_write_long_int(bs, t, 15); gf_bs_write_int(bs, 1, 1); // marker bit } if (use_dts) { gf_bs_write_int(bs, 0x1, 4); // reserved '0001' - t = ((stream->curr_pck.dts >> 30) & 0x7); + t = ((dts >> 30) & 0x7); gf_bs_write_long_int(bs, t, 3); gf_bs_write_int(bs, 1, 1); // marker bit - t = ((stream->curr_pck.dts >> 15) & 0x7fff); + t = ((dts >> 15) & 0x7fff); gf_bs_write_long_int(bs, t, 15); gf_bs_write_int(bs, 1, 1); // marker bit - t = stream->curr_pck.dts & 0x7fff; + t = dts & 0x7fff; gf_bs_write_long_int(bs, t, 15); gf_bs_write_int(bs, 1, 1); // marker bit } - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Adding PES header at PCR "LLD" - has PTS %d (%d) - has DTS %d (%d)\n", stream->pid, gf_m2ts_get_pcr(stream->program)/300, use_pts, stream->curr_pck.cts, use_dts, stream->curr_pck.dts)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Adding PES header at PCR "LLD" - has PTS %d (%d) - has DTS %d (%d)\n", stream->pid, gf_m2ts_get_pcr(stream->program)/300, use_pts, cts, use_dts, dts)); return pes_len+4; // 4 = start code + stream_id } -#define PCR_UPDATE_MS 200 - void gf_m2ts_mux_pes_get_next_packet(GF_M2TS_Mux_Stream *stream, u8 *packet) { GF_BitStream *bs; - Bool is_rap, needs_pcr; - u32 remain, adaptation_field_control, payload_length, padding_length, hdr_len; - u32 now = gf_sys_clock(); + Bool needs_pcr; + u32 adaptation_field_control, payload_length, payload_to_copy, padding_length, hdr_len, pos, copy_next; assert(stream->pid); bs = gf_bs_new(packet, 188, GF_BITSTREAM_WRITE); hdr_len = gf_m2ts_stream_get_pes_header_length(stream); - remain = stream->curr_pck.data_len - stream->pck_offset; - - needs_pcr = 0; - if (hdr_len && (stream==stream->program->pcr) ) { - if (now > stream->program->last_sys_clock + PCR_UPDATE_MS) - needs_pcr = 1; - } + adaptation_field_control = GF_M2TS_ADAPTATION_NONE; payload_length = 184 - hdr_len; - padding_length = 0; + payload_to_copy = padding_length = 0; + needs_pcr = (hdr_len && stream->pcr_priority ) ? 1 : 0; if (needs_pcr) { - adaptation_field_control = GF_M2TS_ADAPTATION_AND_PAYLOAD; /*AF headers + PCR*/ payload_length -= 8; - } else if (remain<184) { - /*AF headers*/ - payload_length -= 2; adaptation_field_control = GF_M2TS_ADAPTATION_AND_PAYLOAD; } - if (remain>=payload_length) { + + if (hdr_len) { + assert(!stream->pes_data_remain); + gf_m2ts_stream_compute_pes_length(stream, payload_length); + assert(stream->pes_data_remain==stream->pes_data_len); + } + + copy_next = stream->copy_from_next_packets; + payload_to_copy = stream->curr_pck.data_len - stream->pck_offset; + /*end of PES packet*/ + if (payload_to_copy > stream->pes_data_remain) { + payload_to_copy = stream->pes_data_remain; + copy_next = 0; + } + + + /*packet exceed payload length*/ + if (payload_to_copy >= payload_length) { + padding_length = 0; + payload_to_copy = payload_length; + } + /*packet + next packet exceed payload length*/ + else if (payload_to_copy + copy_next >= payload_length) { padding_length = 0; - } else { - padding_length = payload_length - remain; - payload_length -= padding_length; + } + /*packet + next packet less than payload length - pad */ + else { + /*AF headers*/ + if (!needs_pcr) { + payload_length -= 2; + adaptation_field_control = GF_M2TS_ADAPTATION_AND_PAYLOAD; + } + /*cannot add adaptation field for this TS packet with this payload, we need to split in 2 TS packets*/ + if (payload_length < payload_to_copy + copy_next) { + padding_length = 10; + payload_length -= padding_length; + payload_to_copy = payload_length; + } else { + padding_length = payload_length - payload_to_copy - copy_next; + payload_length -= padding_length; + } } gf_bs_write_int(bs, 0x47, 8); // sync byte @@ -1070,38 +1270,108 @@ void gf_m2ts_mux_pes_get_next_packet(GF_M2TS_Mux_Stream *stream, u8 *packet) if (stream->continuity_counter < 15) stream->continuity_counter++; else stream->continuity_counter=0; - is_rap = (hdr_len && (stream->curr_pck.flags & GF_ESI_DATA_AU_RAP) ) ? 1 : 0; - if (adaptation_field_control != GF_M2TS_ADAPTATION_NONE) { + Bool is_rap; u64 pcr = 0; if (needs_pcr) { - /*compute PCR*/ u32 now = gf_sys_clock(); - pcr = gf_m2ts_get_pcr(stream->program); + /*compute PCR*/ + if (stream->program->mux->real_time) { + pcr = gf_m2ts_get_pcr(stream->program); + } else { + pcr = (stream->curr_pck.dts - stream->program->pcr_offset) * 300; + if (pcr>stream->program->pcr_init_time) pcr -= stream->program->pcr_init_time; + else pcr = 0; + } -// fprintf(stdout, "PCR Diff in ms %d - sys clock diff in ms %d\n", (u32) (pcr - stream->program->last_pcr) / 27000, now - stream->program->last_sys_clock); + //fprintf(stdout, "PCR Diff in ms %d - sys clock diff in ms %d - DTS diff %d\n", (u32) (pcr - stream->program->last_pcr) / 27000, now - stream->program->last_sys_clock, (stream->curr_pck.dts - stream->program->last_dts)/90); - stream->program->last_pcr = pcr; stream->program->last_sys_clock = now; + stream->program->last_dts = stream->curr_pck.dts; + stream->program->last_pcr = pcr; + stream->pcr_priority = 0; } + is_rap = (hdr_len && (stream->curr_pck.flags & GF_ESI_DATA_AU_RAP) ) ? 1 : 0; gf_m2ts_add_adaptation(bs, stream->pid, needs_pcr, pcr, is_rap, padding_length); } - if (hdr_len) gf_m2ts_stream_add_pes_header(bs, stream); + if (hdr_len) gf_m2ts_stream_add_pes_header(bs, stream, payload_length); + pos = (u32) gf_bs_get_position(bs); gf_bs_del(bs); - memcpy(packet+188-payload_length, stream->curr_pck.data + stream->pck_offset, payload_length); - stream->pck_offset += payload_length; + memcpy(packet+pos, stream->curr_pck.data + stream->pck_offset, payload_to_copy); + stream->pck_offset += payload_to_copy; + assert(stream->pes_data_remain >= payload_to_copy); + stream->pes_data_remain -= payload_to_copy; + + /*update stream time, including headers*/ +// gf_m2ts_time_inc(&stream->time, payload_to_copy + pos - 4, stream->bit_rate); if (stream->pck_offset == stream->curr_pck.data_len) { /*PES has been sent, discard internal buffer*/ - gf_free(stream->curr_pck.data); + if (stream->discard_data) gf_free(stream->curr_pck.data); stream->curr_pck.data = NULL; stream->curr_pck.data_len = 0; - + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Done sending PES (%d bytes) from PID %d at stream time %d:%d (DTS "LLD" - PCR "LLD")\n", stream->curr_pck.data_len, stream->pid, stream->time.sec, stream->time.nanosec, stream->curr_pck.dts, gf_m2ts_get_pcr(stream->program)/300)); + +#ifndef GPAC_DISABLE_LOG + if ((gf_log_get_level() >= GF_LOG_INFO) + && (gf_log_get_tools() & GF_LOG_CONTAINER) + && gf_m2ts_time_less(&stream->program->mux->time, &stream->time) + ) { + s32 drift; + GF_M2TS_Time muxtime = stream->program->mux->time; + drift= stream->time.nanosec; + drift-=muxtime.nanosec; + drift/=1000; + if (muxtime.sec!=stream->time.sec) { + drift += (stream->time.sec - muxtime.sec)*1000000; + } + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] PES PID %d sent %d us too late\n", stream->pid, drift) ); + } +#endif + + /*copy over from next PES to fill this TS packet*/ + if (stream->copy_from_next_packets) { + u32 copy_next; + pos += payload_to_copy; + copy_next = payload_length - payload_to_copy; + /*we might need a more than one*/ + while (1) { + u32 remain = 0; + Bool res = stream->process(stream->program->mux, stream); + assert(res); + if (copy_next > stream->curr_pck.data_len) { + remain = copy_next - stream->curr_pck.data_len; + copy_next = stream->curr_pck.data_len; + } + + memcpy(packet+pos, stream->curr_pck.data + stream->pck_offset, copy_next); + stream->pck_offset += copy_next; + assert(stream->pes_data_remain >= copy_next); + stream->pes_data_remain -= copy_next; + + if (stream->copy_from_next_packets > copy_next) { + stream->copy_from_next_packets -= copy_next; + } else { + stream->copy_from_next_packets = 0; + } + + if (stream->pck_offset == stream->curr_pck.data_len) { + /*PES has been sent, discard internal buffer*/ + if (stream->discard_data) gf_free(stream->curr_pck.data); + stream->curr_pck.data = NULL; + stream->curr_pck.data_len = 0; + } + if (!remain) break; + pos += copy_next; + copy_next = remain; + } + } } + stream->bytes_since_last_time += 188; } @@ -1166,16 +1436,18 @@ GF_Err gf_m2ts_output_ctrl(GF_ESInterface *_self, u32 ctrl_type, void *param) return GF_OK; } -static void gf_m2ts_stream_setup_slconfig(GF_M2TS_Mux_Stream *stream) +static void gf_m2ts_stream_set_default_slconfig(GF_M2TS_Mux_Stream *stream) { - stream->sl_config.tag = GF_ODF_SLC_TAG; - stream->sl_config.useAccessUnitStartFlag = 1; - stream->sl_config.useAccessUnitEndFlag = 1; - stream->sl_config.useRandomAccessPointFlag = 1; - stream->sl_config.useTimestampsFlag = 1; + if (!stream->ifce->sl_config) { + stream->ifce->sl_config = (GF_SLConfig *)gf_odf_desc_new(GF_ODF_SLC_TAG); + stream->ifce->sl_config->useAccessUnitStartFlag = 1; + stream->ifce->sl_config->useAccessUnitEndFlag = 1; + stream->ifce->sl_config->useRandomAccessPointFlag = 1; + stream->ifce->sl_config->useTimestampsFlag = 1; + } } -GF_M2TS_Mux_Stream *gf_m2ts_program_stream_add(GF_M2TS_Mux_Program *program, struct __elementary_stream_ifce *ifce, u32 pid, Bool is_pcr) +GF_M2TS_Mux_Stream *gf_m2ts_program_stream_add(GF_M2TS_Mux_Program *program, struct __elementary_stream_ifce *ifce, u32 pid, Bool is_pcr, Bool force_pes) { GF_M2TS_Mux_Stream *stream, *st; @@ -1184,15 +1456,23 @@ GF_M2TS_Mux_Stream *gf_m2ts_program_stream_add(GF_M2TS_Mux_Program *program, str stream->pid = pid; stream->program = program; if (is_pcr) program->pcr = stream; + if (program->streams) { - st = program->streams; - while (st->next) st = st->next; - st->next = stream; + /*if PCR keep stream at the begining*/ + if (is_pcr) { + stream->next = program->streams; + program->streams = stream; + } else { + st = program->streams; + while (st->next) st = st->next; + st->next = stream; + } } else { program->streams = stream; } if (program->pmt) program->pmt->table_needs_update = 1; stream->bit_rate = ifce->bit_rate; + stream->scheduling_priority = 1; switch (ifce->stream_type) { case GF_STREAM_VISUAL: @@ -1221,7 +1501,7 @@ GF_M2TS_Mux_Stream *gf_m2ts_program_stream_add(GF_M2TS_Mux_Program *program, str case GPAC_OTI_IMAGE_PNG: stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_PES; stream->mpeg2_stream_id = 0xFA; - gf_m2ts_stream_setup_slconfig(stream); + gf_m2ts_stream_set_default_slconfig(stream); break; default: break; @@ -1244,21 +1524,40 @@ GF_M2TS_Mux_Stream *gf_m2ts_program_stream_add(GF_M2TS_Mux_Program *program, str /*just pick first valid stream_id in audio range*/ stream->mpeg2_stream_id = 0xC0; break; - case GF_STREAM_SCENE: case GF_STREAM_OD: - stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_SECTIONS; + /*highest priority for OD streams as they are needed to process other streams*/ + stream->scheduling_priority = 20; + stream->mpeg2_stream_id = 0xFA; + stream->table_id = GF_M2TS_TABLE_ID_MPEG4_OD; + gf_m2ts_stream_set_default_slconfig(stream); + if (force_pes) { + stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_PES; + } else { + stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_SECTIONS; + } + break; + case GF_STREAM_SCENE: stream->mpeg2_stream_id = 0xFA; - stream->table_id = (ifce->stream_type==GF_STREAM_OD) ? GF_M2TS_TABLE_ID_MPEG4_OD : GF_M2TS_TABLE_ID_MPEG4_BIFS; - gf_m2ts_stream_setup_slconfig(stream); + stream->table_id = GF_M2TS_TABLE_ID_MPEG4_BIFS; + gf_m2ts_stream_set_default_slconfig(stream); + + if (force_pes) { + stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_PES; + } else { + stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_SECTIONS; + } break; } - /*override signaling for all streams except BIFS/OD, to use MPEG-4 PES*/ - if (program->mpeg4_signaling==GF_M2TS_MPEG4_SIGNALING_FULL) { - if (stream->mpeg2_stream_type != GF_M2TS_SYSTEMS_MPEG4_SECTIONS) { - stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_PES; - stream->mpeg2_stream_id = 0xFA;/*ISO/IEC14496-1_SL-packetized_stream*/ - gf_m2ts_stream_setup_slconfig(stream); + + if (! (ifce->caps & GF_ESI_STREAM_WITHOUT_MPEG4_SYSTEMS)) { + /*override signaling for all streams except BIFS/OD, to use MPEG-4 PES*/ + if (program->mpeg4_signaling==GF_M2TS_MPEG4_SIGNALING_FULL) { + if (stream->mpeg2_stream_type != GF_M2TS_SYSTEMS_MPEG4_SECTIONS) { + stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_PES; + stream->mpeg2_stream_id = 0xFA;/*ISO/IEC14496-1_SL-packetized_stream*/ + gf_m2ts_stream_set_default_slconfig(stream); + } } } @@ -1279,23 +1578,15 @@ GF_Err gf_m2ts_program_stream_update_ts_scale(GF_ESInterface *_self, u32 time_sc return GF_OK; } -void gf_m2ts_program_stream_update_sl_config(GF_ESInterface *_self, GF_SLConfig *slc) -{ - GF_M2TS_Mux_Stream *stream = (GF_M2TS_Mux_Stream *)_self->output_udta; - if (stream->program->iod && slc) { - memcpy(&stream->sl_config, slc, sizeof(GF_SLConfig)); - } -} - -#define GF_M2TS_PSI_DEFAULT_REFRESH_RATE 200 -GF_M2TS_Mux_Program *gf_m2ts_mux_program_add(GF_M2TS_Mux *muxer, u32 program_number, u32 pmt_pid, u32 pmt_refresh_rate, Bool mpeg4_signaling) +GF_M2TS_Mux_Program *gf_m2ts_mux_program_add(GF_M2TS_Mux *muxer, u32 program_number, u32 pmt_pid, u32 pmt_refresh_rate, u32 pcr_offset, Bool mpeg4_signaling) { GF_M2TS_Mux_Program *program; GF_SAFEALLOC(program, GF_M2TS_Mux_Program); program->mux = muxer; program->mpeg4_signaling = mpeg4_signaling; + program->pcr_offset = pcr_offset; program->number = program_number; if (muxer->programs) { @@ -1309,7 +1600,7 @@ GF_M2TS_Mux_Program *gf_m2ts_mux_program_add(GF_M2TS_Mux *muxer, u32 program_num program->pmt->program = program; muxer->pat->table_needs_update = 1; program->pmt->process = gf_m2ts_stream_process_pmt; - program->pmt->refresh_rate_ms = pmt_refresh_rate ? pmt_refresh_rate : GF_M2TS_PSI_DEFAULT_REFRESH_RATE; + program->pmt->refresh_rate_ms = pmt_refresh_rate; return program; } @@ -1320,9 +1611,10 @@ GF_M2TS_Mux *gf_m2ts_mux_new(u32 mux_rate, u32 pat_refresh_rate, Bool real_time) GF_SAFEALLOC(muxer, GF_M2TS_Mux); muxer->pat = gf_m2ts_stream_new(GF_M2TS_PID_PAT); muxer->pat->process = gf_m2ts_stream_process_pat; - muxer->pat->refresh_rate_ms = pat_refresh_rate ? pat_refresh_rate : GF_M2TS_PSI_DEFAULT_REFRESH_RATE; + muxer->pat->refresh_rate_ms = pat_refresh_rate; muxer->real_time = real_time; muxer->bit_rate = mux_rate; + muxer->init_pcr_value = 0; if (mux_rate) muxer->fixed_rate = 1; /*format NULL packet*/ @@ -1371,6 +1663,15 @@ void gf_m2ts_mux_program_del(GF_M2TS_Mux_Program *prog) gf_m2ts_mux_stream_del(prog->streams); prog->streams = st; } + if (prog->loop_descriptors) { + while (gf_list_count(prog->loop_descriptors) ) { + GF_M2TSDescriptor *desc = gf_list_last(prog->loop_descriptors); + gf_list_rem_last(prog->loop_descriptors); + if (desc->data) gf_free(desc->data); + gf_free(desc); + } + gf_list_del(prog->loop_descriptors); + } gf_m2ts_mux_stream_del(prog->pmt); gf_free(prog); } @@ -1386,6 +1687,29 @@ void gf_m2ts_mux_del(GF_M2TS_Mux *mux) gf_free(mux); } +void gf_m2ts_mux_update_bitrate(GF_M2TS_Mux *mux) +{ + GF_M2TS_Mux_Program *prog; + if (!mux || mux->fixed_rate) return; + + mux->bit_rate = 0; + gf_m2ts_mux_table_update_bitrate(mux, mux->pat); + mux->bit_rate += mux->pat->bit_rate; + + + prog = mux->programs; + while (prog) { + GF_M2TS_Mux_Stream *stream = prog->streams; + gf_m2ts_mux_table_update_bitrate(mux, prog->pmt); + mux->bit_rate += prog->pmt->bit_rate; + while (stream) { + mux->bit_rate += stream->bit_rate; + stream = stream->next; + } + prog = prog->next; + } +} + void gf_m2ts_mux_update_config(GF_M2TS_Mux *mux, Bool reset_time) { GF_M2TS_Mux_Program *prog; @@ -1402,13 +1726,9 @@ void gf_m2ts_mux_update_config(GF_M2TS_Mux *mux, Bool reset_time) while (prog) { GF_M2TS_Mux_Stream *stream = prog->streams; while (stream) { - /*!! WATCHOUT - this is raw bitrate without PES header overhead !!*/ if (!mux->fixed_rate) { mux->bit_rate += stream->bit_rate; - /*update PCR every 100ms - we need at least 8 bytes without padding*/ - if (stream == prog->pcr) mux->bit_rate += 8*8*10; } - /*reset mux time*/ if (reset_time) stream->time.sec = stream->time.nanosec = 0; stream = stream->next; @@ -1440,6 +1760,19 @@ u32 gf_m2ts_get_ts_clock(GF_M2TS_Mux *muxer) return now-init; } +GF_Err gf_m2ts_mux_use_single_au_pes_mode(GF_M2TS_Mux *muxer, Bool strict_au_pes_mode) +{ + if (!muxer) return GF_BAD_PARAM; + muxer->one_au_per_pes = strict_au_pes_mode ? 1 : 0; + return GF_OK; +} + +GF_Err gf_m2ts_mux_set_initial_pcr(GF_M2TS_Mux *muxer, u64 init_pcr_value) +{ + if (!muxer) return GF_BAD_PARAM; + muxer->init_pcr_value = init_pcr_value; + return GF_OK; +} const char *gf_m2ts_mux_process(GF_M2TS_Mux *muxer, u32 *status) { @@ -1448,7 +1781,7 @@ const char *gf_m2ts_mux_process(GF_M2TS_Mux *muxer, u32 *status) GF_M2TS_Time time; u32 now, nb_streams, nb_streams_done; char *ret; - Bool res; + u32 res, highest_priority; nb_streams = nb_streams_done = 0; *status = GF_M2TS_STATE_IDLE; @@ -1471,11 +1804,16 @@ const char *gf_m2ts_mux_process(GF_M2TS_Mux *muxer, u32 *status) stream_to_process = NULL; time = muxer->time; + /*bitrate have changed*/ if (muxer->needs_reconfig) { gf_m2ts_mux_update_config(muxer, 0); muxer->needs_reconfig = 0; } + /*compare PAT and PMT with current mux time + if non-fixed rate, current mux time is the time of the last packet sent, time test is still valid - it will however not work + if min access unit duration from all streams is greater than the PSI refresh rate*/ + /*PAT*/ res = muxer->pat->process(muxer, muxer->pat); if (res && gf_m2ts_time_less_or_equal(&muxer->pat->time, &time) ) { @@ -1489,7 +1827,7 @@ const char *gf_m2ts_mux_process(GF_M2TS_Mux *muxer, u32 *status) program = muxer->programs; while (program) { res = program->pmt->process(muxer, program->pmt); - if (res && gf_m2ts_time_less(&program->pmt->time, &time) ) { + if (res && gf_m2ts_time_less_or_equal(&program->pmt->time, &time) ) { time = program->pmt->time; stream_to_process = program->pmt; /*force sending the PMT regardless of other streams*/ @@ -1498,49 +1836,56 @@ const char *gf_m2ts_mux_process(GF_M2TS_Mux *muxer, u32 *status) program = program->next; } + /*if non-fixed rate, just pick the earliest data on all streams*/ + if (!muxer->fixed_rate) { + time.sec = 0xFFFFFFFF; + } + +#define FORCE_PCR_FIRST 0 + +#if FORCE_PCR_FIRST + /*PCR stream, for each program (send them first to avoid PCR to never be sent)*/ program = muxer->programs; while (program) { - stream = program->streams; - while (stream) { - if (stream == program->pcr) { - nb_streams++; - res = stream->process(muxer, stream); - if (res) { - if (gf_m2ts_time_less(&stream->time, &time)) { - time = stream->time; - stream_to_process = stream; - goto send_pck; - } - } else { - if (stream->ifce->caps & GF_ESI_STREAM_IS_OVER) nb_streams_done ++; - } - - break; - } - stream = stream->next; + stream = program->pcr; + res = stream->process(muxer, stream); + if (res && gf_m2ts_time_less_or_equal(&stream->time, &time)) { + time = stream->time; + stream_to_process = stream; + goto send_pck; } program = program->next; } +#endif - /*all streams except PCR, for each program*/ + /*all streams for each program*/ + highest_priority = 0; program = muxer->programs; while (program) { stream = program->streams; while (stream) { - if (stream != program->pcr) { - nb_streams++; +#if FORCE_PCR_FIRST + if (stream != program->pcr) +#endif + { res = stream->process(muxer, stream); - if (res) { - if (gf_m2ts_time_less(&stream->time, &time)) { + if (res && gf_m2ts_time_less_or_equal(&stream->time, &time)) { + /*if same priority schedule the earliest data*/ + if (res>=highest_priority) { + highest_priority = res; time = stream->time; stream_to_process = stream; +#if FORCE_PCR_FIRST goto send_pck; +#endif } - } else { - if (stream->ifce->caps & GF_ESI_STREAM_IS_OVER) nb_streams_done ++; } } + nb_streams++; + if ((stream->ifce->caps & GF_ESI_STREAM_IS_OVER) && (!res || stream->refresh_rate_ms) ) + nb_streams_done ++; + stream = stream->next; } program = program->next; @@ -1561,34 +1906,56 @@ send_pck: ret = muxer->null_pck; muxer->tot_pad_sent++; } - /*we still need to increase the mux time, even though we're not fixed-rate*/ - else { - gf_m2ts_time_inc(&muxer->time, 1504/*188*8*/, muxer->bit_rate); - } } else { + if (stream_to_process->tables) { gf_m2ts_mux_table_get_next_packet(stream_to_process, muxer->dst_pck); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Send table from PID %d at %d:%09d - mux time %d:%09d\n", stream_to_process->pid, time.sec, time.nanosec, muxer->time.sec, muxer->time.nanosec)); } else { gf_m2ts_mux_pes_get_next_packet(stream_to_process, muxer->dst_pck); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Send PES from PID %d at %d:%09d - mux time %d:%09d\n", stream_to_process->pid, time.sec, time.nanosec, muxer->time.sec, muxer->time.nanosec)); } + ret = muxer->dst_pck; *status = GF_M2TS_STATE_DATA; + +#ifndef GPAC_DISABLE_LOG + if ((gf_log_get_level() >= GF_LOG_DEBUG) + && (gf_log_get_tools() & GF_LOG_CONTAINER) + && muxer->fixed_rate + ) { + s32 drift; + drift= muxer->time.nanosec; + drift-=time.nanosec; + drift/=1000000; + if (muxer->time.sec!=time.sec) { + drift += (muxer->time.sec - time.sec)*1000; + assert(muxer->time.sec > time.sec); + } +// fprintf(stdout, "\nMux time - Packet PID %d time: %d ms\n", stream_to_process->pid, drift); + } + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Send %s from PID %d at %d:%09d - mux time %d:%09d\n", stream_to_process->tables ? "table" : "PES", stream_to_process->pid, time.sec, time.nanosec, muxer->time.sec, muxer->time.nanosec)); +#endif + + + if (nb_streams && (nb_streams==nb_streams_done)) + *status = GF_M2TS_STATE_EOS; } if (ret) { muxer->tot_pck_sent++; /*increment time*/ - gf_m2ts_time_inc(&muxer->time, 1504/*188*8*/, muxer->bit_rate); + if (muxer->fixed_rate) { + gf_m2ts_time_inc(&muxer->time, 1504/*188*8*/, muxer->bit_rate); + } + /*if a stream was found, use it*/ + else if (stream_to_process) { + muxer->time = time; + } - if (muxer->real_time) { - muxer->pck_sent_over_br_window++; - if (now - muxer->last_br_time > 500) { - u64 size = 8*188*muxer->pck_sent_over_br_window*1000; - muxer->avg_br = (u32) (size/(now - muxer->last_br_time)); - muxer->last_br_time = now; - muxer->pck_sent_over_br_window=0; - } + muxer->pck_sent_over_br_window++; + if (now - muxer->last_br_time > 500) { + u64 size = 8*188*muxer->pck_sent_over_br_window*1000; + muxer->avg_br = (u32) (size/(now - muxer->last_br_time)); + muxer->last_br_time = now; + muxer->pck_sent_over_br_window=0; } } return ret; diff --git a/src/media_tools/m3u8.c b/src/media_tools/m3u8.c index 8095ebf..3916a46 100644 --- a/src/media_tools/m3u8.c +++ b/src/media_tools/m3u8.c @@ -1,727 +1,727 @@ -/** - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) Jean Le Feuvre 2000-2005 - * All rights reserved - * - * This file is part of GPAC - * - * 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. - * Written by Pierre Souchay for VizionR SAS - * - */ - -#define _GNU_SOURCE - -#include -#include -#include -#include - -/*#define MYLOG(xx) GF_LOG( GF_LOG_INFO, GF_LOG_CONTAINER, xx )*/ -//#define MYLOG(xx) printf xx -#define MYLOG(xx) - - -#if defined(WIN32) || defined(_WIN32_WCE) -#define bzero(a, b) memset(a, 0x0, b) -#endif - -GF_Err cleanup_list_of_elements(GF_List * list) { - GF_Err result = GF_OK; - if (list == NULL) - return result; - while (gf_list_count(list)) { - PlaylistElement * pl = (PlaylistElement *) gf_list_get(list, 0); - if (pl) - result |= playlist_element_del(pl); - gf_list_rem(list, 0); - } - gf_list_del(list); - return result; -} - -GF_Err playlist_element_del(PlaylistElement * e) { - GF_Err result = GF_OK; - if (e == NULL) - return result; - if (e->title) { - gf_free(e->title); - e->title = NULL; - } - if (e->codecs) { - gf_free(e->codecs); - e->codecs = NULL; - } - assert( e->url); - gf_free(e->url); - e->url = NULL; - - switch (e->elementType) { - case TYPE_UNKNOWN: - case TYPE_STREAM: - break; - case TYPE_PLAYLIST: - assert( e->element.playlist.elements); - result |= cleanup_list_of_elements(e->element.playlist.elements); - e->element.playlist.elements = NULL; - default: - break; - } - gf_free(e); - return result; -} - -Program * program_new(int programId) { - Program * program = (Program*)gf_malloc(sizeof(Program)); - if (program == NULL) { - return NULL; - } - program->programId = programId; - program->bitrates = gf_list_new(); - if (program->bitrates == NULL) { - gf_free(program); - return NULL; - } - return program; -} - -GF_Err program_del(Program * program) { - GF_Err e = GF_OK; - if (program == NULL) - return e; - if ( program->bitrates) { - while (gf_list_count(program->bitrates)) { - GF_List * l = gf_list_get(program->bitrates, 0); - cleanup_list_of_elements(l); - gf_list_rem(program->bitrates, 0); - } - gf_list_del(program->bitrates); - } - program->bitrates = NULL; - gf_free(program); - return e; -} - -/* -GF_Err playlist_del(Playlist * pl){ - GF_Err result = GF_OK; - if (pl == NULL) - return result; - if (pl->elements){ - result|= cleanup_list_of_elements(pl->elements); - pl->elements = NULL; - } - gf_free(pl); - return result; -}*/ - -PlaylistElement * playlist_element_new(PlaylistElementType elementType, const char * url, const char * title, const char *codecs, int durationInfo) { - PlaylistElement * e = gf_malloc(sizeof(PlaylistElement)); - bzero(e, sizeof(PlaylistElement)); - assert( url ); - if (e == NULL) - return NULL; - e->durationInfo = durationInfo; - e->title = (title ? gf_strdup(title) : NULL); - e->codecs = (codecs ? gf_strdup(codecs) : NULL); - assert( url); - e->url = gf_strdup(url); - e->bandwidth = 0; - e->elementType = elementType; - if (elementType == TYPE_PLAYLIST) { - e->element.playlist.is_ended = 0; - e->element.playlist.target_duration = durationInfo; - e->element.playlist.currentMediaSequence = 0; - e->element.playlist.mediaSequenceMin = 0; - e->element.playlist.mediaSequenceMax = 0; - e->element.playlist.elements = gf_list_new(); - if (NULL == (e->element.playlist.elements)) { - if (e->title) - gf_free(e->title); - if (e->codecs) - gf_free(e->codecs); - if (e->url) - gf_free(e->url); - e->url = NULL; - e->title = NULL; - e->codecs = NULL; - gf_free(e); - return NULL; - } - } else { - /* Nothing to do, stream is an empty structure */ - } - assert(e->bandwidth == 0); - assert(e->url); - return e; -} -/* -Playlist * playlist_new(){ - Playlist * pl = gf_malloc(sizeof(Playlist)); - if (pl == NULL) - return NULL; - pl->currentMediaSequence = 1; - pl->target_duration = 0; - pl->mediaSequenceMin = 0; - pl->mediaSequenceMax = 0; - pl->is_ended = 0; - pl->elements = gf_list_new(); - if (pl->elements == NULL){ - gf_free(pl); - return NULL; - } - return pl; -} - */ - -VariantPlaylist * variant_playlist_new () -{ - VariantPlaylist * pl = (VariantPlaylist*)gf_malloc( sizeof(VariantPlaylist) ); - if (pl == NULL) - return NULL; - pl->programs = gf_list_new(); - if (! pl->programs) { - gf_free( pl ); - return NULL; - } - pl->currentProgram = -1; - pl->playlistNeedsRefresh = 1; - return pl; -} - -GF_Err variant_playlist_del (VariantPlaylist * playlist) { - if (playlist == NULL) - return GF_OK; - assert( playlist->programs); - while (gf_list_count(playlist->programs)) { - Program * p = gf_list_get(playlist->programs, 0); - assert(p); - while (gf_list_count( p->bitrates )) { - PlaylistElement * pl = gf_list_get(p->bitrates, 0); - assert( pl ); - playlist_element_del(pl); - gf_list_rem(p->bitrates, 0); - } - gf_list_del(p->bitrates); - p->bitrates = NULL; - program_del(p); - gf_list_rem(playlist->programs, 0); - } - gf_list_del(playlist->programs); - playlist->programs = NULL; - gf_free(playlist); - return GF_OK; -} - -GF_Err playlist_element_dump(const PlaylistElement * e, int indent) { - int i; - GF_Err r = GF_OK; - for (i = 0 ; i < indent; i++) - printf(" "); - if (e == NULL) { - printf("NULL PlaylistElement\n"); - return r; - } - printf("PlayListElement[%p, title=%s, codecs=%s, duration=%d, bandwidth=%d, url=%s, type=%s]\n", - (void*)e, - e->title, - e->codecs, - e->durationInfo, - e->bandwidth, - e->url, - e->elementType == TYPE_STREAM ? "stream" : "playlist"); - if (TYPE_PLAYLIST == e->elementType) { - int sz; - assert( e->element.playlist.elements); - sz = gf_list_count(e->element.playlist.elements); - indent+=2; - for (i = 0 ; i < sz ; i++) { - PlaylistElement * el = gf_list_get(e->element.playlist.elements, i); - assert( el); - r|= playlist_element_dump( el, indent); - } - } - return r; -} - -GF_Err variant_playlist_dump(const VariantPlaylist * pl) { - int i, count; - GF_Err e = GF_OK; - if (pl == NULL) { - printf("VariantPlaylist = NULL\n"); - return e; - } - printf("VariantPlaylist = {\n"); - assert( pl->programs); - count = gf_list_count( pl->programs); - for (i = 0 ; i < count ; i++) { - int j, countj; - Program * p = gf_list_get(pl->programs, i); - assert( p ); - printf(" program[programId=%d]{\n", p->programId); - assert( p->bitrates ); - countj = gf_list_count(p->bitrates); - for (j = 0; j < countj; j++) { - PlaylistElement * el = gf_list_get(p->bitrates, j); - assert(el); - e |= playlist_element_dump( el, 4); - } - printf(" }\n"); - } - printf("}\n"); - return e; -} - -Program * variant_playlist_find_matching_program(const VariantPlaylist * pl, const u32 programId) { - u32 count, i; - assert( pl); - assert( pl->programs); - assert(programId >= 0); - count = gf_list_count(pl->programs); - for (i = 0 ; i < count ; i++) { - Program * cur = gf_list_get(pl->programs, i); - assert( cur ); - if (programId == cur->programId) { - /* We found the program */ - return cur; - } - } - return NULL; -} - -Program * variant_playlist_get_current_program(const VariantPlaylist * pl) { - assert( pl ); - return variant_playlist_find_matching_program(pl, pl->currentProgram); -} - - - -typedef struct _s_accumulated_attributes { - char * title; - int durationInSeconds; - int bandwidth; - int programId; - char * codecs; - int targetDurationInSeconds; - int minMediaSequence; - int currentMediaSequence; - Bool isVariantPlaylist; - Bool isPlaylistEnded; -} s_accumulated_attributes; - -static Bool safe_start_equals(const char * attribute, const char * line) { - size_t len, atlen; - if (line == NULL) - return 0; - len = strlen(line); - atlen = strlen(attribute); - if (len < atlen) - return 0; - return 0 == strncmp(attribute, line, atlen); -} - -static char ** extractAttributes(const char * name, const char * line, const int numberOfAttributes) { - int sz, i, currentAttribute, start; - char ** ret; - int len = strlen(line); - start = strlen(name); - if (len <= start) - return NULL; - if (!safe_start_equals(name, line)) - return NULL; - ret = gf_calloc((numberOfAttributes + 1 ), sizeof(char*)); - currentAttribute = 0; - for (i = start ; i <= len ; i++) { - if (line[i] == '\0' || line[i] == ',') { - u32 spaces = 0; - sz = 1 + i - start; - while (line[start+spaces] == ' ') spaces++; - ret[currentAttribute] = gf_calloc( (1+sz-spaces), sizeof(char)); - strncpy(ret[currentAttribute], &(line[start+spaces]), sz-spaces); - currentAttribute++; - start = i+1; - if (start == len) { - return ret; - } - } - } - if (currentAttribute == 0) { - gf_free(ret); - return NULL; - } - return ret; -} - -/** - * Parses the attributes and accumulate into the attributes structure - */ -static char ** parseAttributes(const char * line, s_accumulated_attributes * attributes) { - int intValue, i; - char ** ret; - char * endPtr; - char * utility; - if (line == NULL) - return NULL; - if (!safe_start_equals("#EXT", line)) - return NULL; - if (safe_start_equals("#EXT-X-ENDLIST", line)) { - attributes->isPlaylistEnded = 1; - return NULL; - } - ret = extractAttributes("#EXT-X-TARGETDURATION:", line, 1); - if (ret) { - /* #EXT-X-TARGETDURATION: */ - if (ret[0]) { - intValue = strtol(ret[0], &endPtr, 10); - if (endPtr != ret[0]) { - attributes->targetDurationInSeconds = intValue; - } - } - return ret; - } - ret = extractAttributes("#EXT-X-MEDIA-SEQUENCE:", line, 1); - if (ret) { - /* #EXT-X-MEDIA-SEQUENCE: */ - if (ret[0]) { - intValue = strtol(ret[0], &endPtr, 10); - if (endPtr != ret[0]) { - attributes->minMediaSequence = intValue; - attributes->currentMediaSequence = intValue; - } - } - return ret; - } - ret = extractAttributes("#EXTINF:", line, 2); - if (ret) { - /* #EXTINF:, */ - if (ret[0]) { - intValue = strtol(ret[0], &endPtr, 10); - if (endPtr != ret[0]) { - attributes->durationInSeconds = intValue; - } - } - if (ret[1]) { - attributes->title = gf_strdup(ret[1]); - } - return ret; - } - ret = extractAttributes("#EXT-X-KEY:", line, 2); - if (ret) { - /* #EXT-X-KEY:METHOD=<method>[,URI="<URI>"] */ - /* Not Supported for now */ - return ret; - } - ret = extractAttributes("#EXT-X-STREAM-INF:", line, 3); - if (ret) { - /* #EXT-X-STREAM-INF:[attribute=value][,attribute=value]* */ - i = 0; - attributes->isVariantPlaylist = 1; - while (ret[i] != NULL) { - if (safe_start_equals("BANDWIDTH=", ret[i])) { - utility = &(ret[i][10]); - intValue = strtol(utility, &endPtr, 10); - if (endPtr != utility) - attributes->bandwidth = intValue; - } else if (safe_start_equals("PROGRAM-ID=", ret[i])) { - utility = &(ret[i][11]); - intValue = strtol(utility, &endPtr, 10); - if (endPtr != utility) - attributes->programId = intValue; - } else if (safe_start_equals("CODECS=\"", ret[i])) { - intValue = strlen(ret[i]); - if (ret[i][intValue-1] == '"') { - attributes->codecs = gf_strdup(&(ret[i][7])); - } - } - i++; - } - return ret; - } - return NULL; -} - -#define M3U8_BUF_SIZE 2048 - -GF_Err parse_root_playlist(const char * file, VariantPlaylist ** playlist, const char * baseURL) -{ - return parse_sub_playlist(file, playlist, baseURL, NULL, NULL); -} - -GF_Err parse_sub_playlist(const char * file, VariantPlaylist ** playlist, const char * baseURL, Program * in_program, PlaylistElement *sub_playlist) -{ - int readen, readPointer, len, i, currentLineNumber; - FILE * f; - VariantPlaylist * pl; - char currentLine[M3U8_BUF_SIZE]; - char ** attributes = NULL; - s_accumulated_attributes attribs; - f = gf_f64_open(file, "rt"); - if (!f) { - GF_LOG( GF_LOG_ERROR, GF_LOG_CONTAINER,("[M3U8] Cannot Open m3u8 file %s for reading\n", file)); - return GF_SERVICE_ERROR; - } - if (*playlist == NULL) { - *playlist = variant_playlist_new(); - if (!(*playlist)) { - fclose(f); - return GF_OUT_OF_MEM; - } - } - pl = *playlist; - readen=0; - readPointer = 0; - currentLineNumber = 0; - bzero(&attribs, sizeof(s_accumulated_attributes)); - attribs.bandwidth = 0; - attribs.durationInSeconds = 0; - attribs.targetDurationInSeconds = 0; - attribs.isVariantPlaylist = 0; - attribs.isPlaylistEnded = 0; - attribs.minMediaSequence = 0; - attribs.currentMediaSequence = 0; - while (fgets(currentLine, sizeof(currentLine), f)) { - char * eof; - currentLineNumber++; - eof = strchr(currentLine, '\r'); - if (eof) - eof[0] = '\0'; - eof = strchr(currentLine, '\n'); - if (eof) - eof[0] = '\0'; - len = strlen( currentLine); - if (len < 1) - continue; - if (currentLineNumber == 1) { - /* Playlist MUST start with #EXTM3U */ - if (len < 7 || strncmp("#EXTM3U", currentLine, 7)!=0) { - fclose(f); - variant_playlist_del(pl); - GF_LOG( GF_LOG_ERROR, GF_LOG_CONTAINER, ("Failed to parse M3U8 File, it should start with #EXTM3U, but was : %s\n", currentLine)); - return GF_STREAM_NOT_FOUND; - } - continue; - } - if (currentLine[0] == '#') { - /* A comment or a directive */ - if (strncmp("#EXT", currentLine, 4)==0) { - attributes = parseAttributes(currentLine, &attribs); - if (attributes == NULL) { - MYLOG(("Comment at line %d : %s\n", currentLineNumber, currentLine)); - } else { - MYLOG(("Directive at line %d: \"%s\", attributes=", currentLineNumber, currentLine)); - i = 0; - while (attributes[i] != NULL) { - MYLOG((" [%d]='%s'", i, attributes[i])); - gf_free(attributes[i]); - attributes[i] = NULL; - i++; - } - MYLOG(("\n")); - gf_free(attributes); - attributes = NULL; - } - if (attribs.isPlaylistEnded) { - pl->playlistNeedsRefresh = 0; - } - } - } else { - char * fullURL = currentLine; - //printf("Line %d: '%s'\n", currentLineNumber, currentLine); - - if (gf_url_is_local(currentLine)) { - /* - if (gf_url_is_local(baseURL)){ - int num_chars = -1; - if (baseURL[strlen(baseURL)-1] == '/'){ - num_chars = asprintf(&fullURL, "%s%s", baseURL, currentLine); - } else { - num_chars = asprintf(&fullURL, "%s/%s", baseURL, currentLine); - } - if (num_chars < 0 || fullURL == NULL){ - variant_playlist_del(*playlist); - playlist = NULL; - return GF_OUT_OF_MEM; - } - } else */ { - fullURL = gf_url_concatenate(baseURL, currentLine); - } - assert( fullURL ); - /*printf("*** calculated full path = %s from %s and %s\n", fullURL, currentLine, baseURL);*/ - } - { - u32 count; - PlaylistElement * currentPlayList = sub_playlist; - /* First, we have to find the matching program */ - Program * program = in_program; - if (!in_program) program = variant_playlist_find_matching_program(pl, attribs.programId); - /* We did not found the program, we create it */ - if (program == NULL) { - program = program_new(attribs.programId); - if (program == NULL) { - /* OUT of memory */ - variant_playlist_del(*playlist); - fclose(f); - playlist = NULL; - return GF_OUT_OF_MEM; - } - gf_list_add(pl->programs, program); - if (pl->currentProgram < 0) - pl->currentProgram = program->programId; - } - - /* OK, we have a program, we have to choose the elements with same bandwidth */ - assert( program ); - assert( program->bitrates); - count = gf_list_count( program->bitrates); - - if (!currentPlayList) { - for (i = 0; i < (s32) count; i++) { - PlaylistElement * itPlayListElement = gf_list_get(program->bitrates, i); - assert( itPlayListElement ); - if (itPlayListElement->bandwidth == attribs.bandwidth) { - currentPlayList = itPlayListElement; - break; - } - } - } - - if (attribs.isVariantPlaylist) { - /* We are the Variant Playlist */ - if (currentPlayList != NULL) { - /* should not happen, it means we redefine something previsouly added */ - //assert( 0 ); - } - currentPlayList = playlist_element_new( - TYPE_UNKNOWN, - fullURL, - attribs.title, - attribs.codecs, - attribs.durationInSeconds); - if (currentPlayList == NULL) { - /* OUT of memory */ - variant_playlist_del(*playlist); - playlist = NULL; - fclose(f); - return GF_OUT_OF_MEM; - } - assert( fullURL); - currentPlayList->url = gf_strdup(fullURL); - currentPlayList->title = attribs.title ? gf_strdup(attribs.title):NULL; - currentPlayList->codecs = attribs.codecs ? gf_strdup(attribs.codecs):NULL; - gf_list_add(program->bitrates, currentPlayList); - } else { - /* Normal Playlist */ - assert( pl->programs); - if (currentPlayList == NULL) { - /* This is in facts a "normal" playlist without any element in it */ - PlaylistElement * subElement; - assert(baseURL); - currentPlayList = playlist_element_new( - TYPE_PLAYLIST, - baseURL, - attribs.title, - attribs.codecs, - attribs.durationInSeconds); - if (currentPlayList == NULL) { - /* OUT of memory */ - variant_playlist_del(*playlist); - playlist = NULL; - fclose(f); - return GF_OUT_OF_MEM; - } - assert(currentPlayList->element.playlist.elements); - assert( fullURL); - assert( currentPlayList->url); - currentPlayList->title = NULL; - currentPlayList->codecs = NULL; - subElement = playlist_element_new( - TYPE_UNKNOWN, - fullURL, - attribs.title, - attribs.codecs, - attribs.durationInSeconds); - if (subElement == NULL) { - variant_playlist_del(*playlist); - playlist_element_del(currentPlayList); - playlist = NULL; - fclose(f); - return GF_OUT_OF_MEM; - } - gf_list_add(currentPlayList->element.playlist.elements, subElement); - gf_list_add(program->bitrates, currentPlayList); - assert( program ); - assert( program->bitrates); - assert( currentPlayList); - - } else { - PlaylistElement * subElement = playlist_element_new( - TYPE_UNKNOWN, - fullURL, - attribs.title, - attribs.codecs, - attribs.durationInSeconds); - if (currentPlayList->elementType != TYPE_PLAYLIST) { - currentPlayList->elementType = TYPE_PLAYLIST; - if (!currentPlayList->element.playlist.elements) - currentPlayList->element.playlist.elements = gf_list_new(); - } - if (subElement == NULL) { - variant_playlist_del(*playlist); - playlist_element_del(currentPlayList); - playlist = NULL; - fclose(f); - return GF_OUT_OF_MEM; - } - gf_list_add(currentPlayList->element.playlist.elements, subElement); - } - } - - currentPlayList->element.playlist.currentMediaSequence = attribs.currentMediaSequence ; - /* We first set the default duration for element, aka targetDuration */ - if (attribs.targetDurationInSeconds > 0) { - currentPlayList->element.playlist.target_duration = attribs.targetDurationInSeconds; - currentPlayList->durationInfo = attribs.targetDurationInSeconds; - } - if (attribs.durationInSeconds) { - currentPlayList->durationInfo = attribs.durationInSeconds; - } - currentPlayList->element.playlist.mediaSequenceMin = attribs.minMediaSequence; - currentPlayList->element.playlist.mediaSequenceMax = attribs.currentMediaSequence++; - if (attribs.bandwidth > 1) - currentPlayList->bandwidth = attribs.bandwidth; - if (attribs.isPlaylistEnded) - currentPlayList->element.playlist.is_ended = 1; - } - /* Cleanup all line-specific fields */ - if (attribs.title) { - gf_free(attribs.title); - attribs.title = NULL; - } - attribs.durationInSeconds = 0; - attribs.bandwidth = 0; - attribs.programId = 0; - if (attribs.codecs != NULL) { - gf_free(attribs.codecs); - attribs.codecs = NULL; - } - if (fullURL != currentLine) { - gf_free(fullURL); - } - } - } - fclose(f); - return GF_OK; -} +/** +* GPAC - Multimedia Framework C SDK +* +* Copyright (c) Jean Le Feuvre 2000-2005 +* All rights reserved +* +* This file is part of GPAC +* +* 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. +* Written by Pierre Souchay for VizionR SAS +* +*/ + +#define _GNU_SOURCE + +#include <gpac/internal/m3u8.h> +#include <string.h> +#include <stdio.h> +#include <gpac/network.h> + +/*#define MYLOG(xx) GF_LOG( GF_LOG_INFO, GF_LOG_CONTAINER, xx )*/ +//#define MYLOG(xx) printf xx +#define MYLOG(xx) + + +#if defined(WIN32) || defined(_WIN32_WCE) +#define bzero(a, b) memset(a, 0x0, b) +#endif + +GF_Err cleanup_list_of_elements(GF_List * list) { + GF_Err result = GF_OK; + if (list == NULL) + return result; + while (gf_list_count(list)) { + PlaylistElement * pl = (PlaylistElement *) gf_list_get(list, 0); + if (pl) + result |= playlist_element_del(pl); + gf_list_rem(list, 0); + } + gf_list_del(list); + return result; +} + +GF_Err playlist_element_del(PlaylistElement * e) { + GF_Err result = GF_OK; + if (e == NULL) + return result; + if (e->title) { + gf_free(e->title); + e->title = NULL; + } + if (e->codecs) { + gf_free(e->codecs); + e->codecs = NULL; + } + assert( e->url); + gf_free(e->url); + e->url = NULL; + + switch (e->elementType) { + case TYPE_UNKNOWN: + case TYPE_STREAM: + break; + case TYPE_PLAYLIST: + assert( e->element.playlist.elements); + result |= cleanup_list_of_elements(e->element.playlist.elements); + e->element.playlist.elements = NULL; + default: + break; + } + gf_free(e); + return result; +} + +Program * program_new(int programId) { + Program * program = (Program*)gf_malloc(sizeof(Program)); + if (program == NULL) { + return NULL; + } + program->programId = programId; + program->bitrates = gf_list_new(); + if (program->bitrates == NULL) { + gf_free(program); + return NULL; + } + return program; +} + +GF_Err program_del(Program * program) { + GF_Err e = GF_OK; + if (program == NULL) + return e; + if ( program->bitrates) { + while (gf_list_count(program->bitrates)) { + GF_List * l = gf_list_get(program->bitrates, 0); + cleanup_list_of_elements(l); + gf_list_rem(program->bitrates, 0); + } + gf_list_del(program->bitrates); + } + program->bitrates = NULL; + gf_free(program); + return e; +} + +/* +GF_Err playlist_del(Playlist * pl){ +GF_Err result = GF_OK; +if (pl == NULL) +return result; +if (pl->elements){ +result|= cleanup_list_of_elements(pl->elements); +pl->elements = NULL; +} +gf_free(pl); +return result; +}*/ + +PlaylistElement * playlist_element_new(PlaylistElementType elementType, const char * url, const char * title, const char *codecs, int durationInfo) { + PlaylistElement * e = gf_malloc(sizeof(PlaylistElement)); + bzero(e, sizeof(PlaylistElement)); + assert( url ); + if (e == NULL) + return NULL; + e->durationInfo = durationInfo; + e->title = (title ? gf_strdup(title) : NULL); + e->codecs = (codecs ? gf_strdup(codecs) : NULL); + assert( url); + e->url = gf_strdup(url); + e->bandwidth = 0; + e->elementType = elementType; + if (elementType == TYPE_PLAYLIST) { + e->element.playlist.is_ended = 0; + e->element.playlist.target_duration = durationInfo; + e->element.playlist.currentMediaSequence = 0; + e->element.playlist.mediaSequenceMin = 0; + e->element.playlist.mediaSequenceMax = 0; + e->element.playlist.elements = gf_list_new(); + if (NULL == (e->element.playlist.elements)) { + if (e->title) + gf_free(e->title); + if (e->codecs) + gf_free(e->codecs); + if (e->url) + gf_free(e->url); + e->url = NULL; + e->title = NULL; + e->codecs = NULL; + gf_free(e); + return NULL; + } + } else { + /* Nothing to do, stream is an empty structure */ + } + assert(e->bandwidth == 0); + assert(e->url); + return e; +} +/* +Playlist * playlist_new(){ +Playlist * pl = gf_malloc(sizeof(Playlist)); +if (pl == NULL) +return NULL; +pl->currentMediaSequence = 1; +pl->target_duration = 0; +pl->mediaSequenceMin = 0; +pl->mediaSequenceMax = 0; +pl->is_ended = 0; +pl->elements = gf_list_new(); +if (pl->elements == NULL){ +gf_free(pl); +return NULL; +} +return pl; +} +*/ + +VariantPlaylist * variant_playlist_new () +{ + VariantPlaylist * pl = (VariantPlaylist*)gf_malloc( sizeof(VariantPlaylist) ); + if (pl == NULL) + return NULL; + pl->programs = gf_list_new(); + if (! pl->programs) { + gf_free( pl ); + return NULL; + } + pl->currentProgram = -1; + pl->playlistNeedsRefresh = 1; + return pl; +} + +GF_Err variant_playlist_del (VariantPlaylist * playlist) { + if (playlist == NULL) + return GF_OK; + assert( playlist->programs); + while (gf_list_count(playlist->programs)) { + Program * p = gf_list_get(playlist->programs, 0); + assert(p); + while (gf_list_count( p->bitrates )) { + PlaylistElement * pl = gf_list_get(p->bitrates, 0); + assert( pl ); + playlist_element_del(pl); + gf_list_rem(p->bitrates, 0); + } + gf_list_del(p->bitrates); + p->bitrates = NULL; + program_del(p); + gf_list_rem(playlist->programs, 0); + } + gf_list_del(playlist->programs); + playlist->programs = NULL; + gf_free(playlist); + return GF_OK; +} + +GF_Err playlist_element_dump(const PlaylistElement * e, int indent) { + int i; + GF_Err r = GF_OK; + for (i = 0 ; i < indent; i++) + printf(" "); + if (e == NULL) { + printf("NULL PlaylistElement\n"); + return r; + } + printf("PlayListElement[%p, title=%s, codecs=%s, duration=%d, bandwidth=%d, url=%s, type=%s]\n", + (void*)e, + e->title, + e->codecs, + e->durationInfo, + e->bandwidth, + e->url, + e->elementType == TYPE_STREAM ? "stream" : "playlist"); + if (TYPE_PLAYLIST == e->elementType) { + int sz; + assert( e->element.playlist.elements); + sz = gf_list_count(e->element.playlist.elements); + indent+=2; + for (i = 0 ; i < sz ; i++) { + PlaylistElement * el = gf_list_get(e->element.playlist.elements, i); + assert( el); + r|= playlist_element_dump( el, indent); + } + } + return r; +} + +GF_Err variant_playlist_dump(const VariantPlaylist * pl) { + int i, count; + GF_Err e = GF_OK; + if (pl == NULL) { + printf("VariantPlaylist = NULL\n"); + return e; + } + printf("VariantPlaylist = {\n"); + assert( pl->programs); + count = gf_list_count( pl->programs); + for (i = 0 ; i < count ; i++) { + int j, countj; + Program * p = gf_list_get(pl->programs, i); + assert( p ); + printf(" program[programId=%d]{\n", p->programId); + assert( p->bitrates ); + countj = gf_list_count(p->bitrates); + for (j = 0; j < countj; j++) { + PlaylistElement * el = gf_list_get(p->bitrates, j); + assert(el); + e |= playlist_element_dump( el, 4); + } + printf(" }\n"); + } + printf("}\n"); + return e; +} + +Program * variant_playlist_find_matching_program(const VariantPlaylist * pl, const u32 programId) { + u32 count, i; + assert( pl); + assert( pl->programs); + assert(programId >= 0); + count = gf_list_count(pl->programs); + for (i = 0 ; i < count ; i++) { + Program * cur = gf_list_get(pl->programs, i); + assert( cur ); + if (programId == cur->programId) { + /* We found the program */ + return cur; + } + } + return NULL; +} + +Program * variant_playlist_get_current_program(const VariantPlaylist * pl) { + assert( pl ); + return variant_playlist_find_matching_program(pl, pl->currentProgram); +} + + + +typedef struct _s_accumulated_attributes { + char * title; + int durationInSeconds; + int bandwidth; + int programId; + char * codecs; + int targetDurationInSeconds; + int minMediaSequence; + int currentMediaSequence; + Bool isVariantPlaylist; + Bool isPlaylistEnded; +} s_accumulated_attributes; + +static Bool safe_start_equals(const char * attribute, const char * line) { + size_t len, atlen; + if (line == NULL) + return 0; + len = strlen(line); + atlen = strlen(attribute); + if (len < atlen) + return 0; + return 0 == strncmp(attribute, line, atlen); +} + +static char ** extractAttributes(const char * name, const char * line, const int numberOfAttributes) { + int sz, i, currentAttribute, start; + char ** ret; + int len = strlen(line); + start = strlen(name); + if (len <= start) + return NULL; + if (!safe_start_equals(name, line)) + return NULL; + ret = gf_calloc((numberOfAttributes + 1 ), sizeof(char*)); + currentAttribute = 0; + for (i = start ; i <= len ; i++) { + if (line[i] == '\0' || line[i] == ',') { + u32 spaces = 0; + sz = 1 + i - start; + while (line[start+spaces] == ' ') spaces++; + ret[currentAttribute] = gf_calloc( (1+sz-spaces), sizeof(char)); + strncpy(ret[currentAttribute], &(line[start+spaces]), sz-spaces); + currentAttribute++; + start = i+1; + if (start == len) { + return ret; + } + } + } + if (currentAttribute == 0) { + gf_free(ret); + return NULL; + } + return ret; +} + +/** +* Parses the attributes and accumulate into the attributes structure +*/ +static char ** parseAttributes(const char * line, s_accumulated_attributes * attributes) { + int intValue, i; + char ** ret; + char * endPtr; + char * utility; + if (line == NULL) + return NULL; + if (!safe_start_equals("#EXT", line)) + return NULL; + if (safe_start_equals("#EXT-X-ENDLIST", line)) { + attributes->isPlaylistEnded = 1; + return NULL; + } + ret = extractAttributes("#EXT-X-TARGETDURATION:", line, 1); + if (ret) { + /* #EXT-X-TARGETDURATION:<seconds> */ + if (ret[0]) { + intValue = strtol(ret[0], &endPtr, 10); + if (endPtr != ret[0]) { + attributes->targetDurationInSeconds = intValue; + } + } + return ret; + } + ret = extractAttributes("#EXT-X-MEDIA-SEQUENCE:", line, 1); + if (ret) { + /* #EXT-X-MEDIA-SEQUENCE:<number> */ + if (ret[0]) { + intValue = strtol(ret[0], &endPtr, 10); + if (endPtr != ret[0]) { + attributes->minMediaSequence = intValue; + attributes->currentMediaSequence = intValue; + } + } + return ret; + } + ret = extractAttributes("#EXTINF:", line, 2); + if (ret) { + /* #EXTINF:<duration>,<title> */ + if (ret[0]) { + intValue = strtol(ret[0], &endPtr, 10); + if (endPtr != ret[0]) { + attributes->durationInSeconds = intValue; + } + } + if (ret[1]) { + attributes->title = gf_strdup(ret[1]); + } + return ret; + } + ret = extractAttributes("#EXT-X-KEY:", line, 2); + if (ret) { + /* #EXT-X-KEY:METHOD=<method>[,URI="<URI>"] */ + /* Not Supported for now */ + return ret; + } + ret = extractAttributes("#EXT-X-STREAM-INF:", line, 3); + if (ret) { + /* #EXT-X-STREAM-INF:[attribute=value][,attribute=value]* */ + i = 0; + attributes->isVariantPlaylist = 1; + while (ret[i] != NULL) { + if (safe_start_equals("BANDWIDTH=", ret[i])) { + utility = &(ret[i][10]); + intValue = strtol(utility, &endPtr, 10); + if (endPtr != utility) + attributes->bandwidth = intValue; + } else if (safe_start_equals("PROGRAM-ID=", ret[i])) { + utility = &(ret[i][11]); + intValue = strtol(utility, &endPtr, 10); + if (endPtr != utility) + attributes->programId = intValue; + } else if (safe_start_equals("CODECS=\"", ret[i])) { + intValue = strlen(ret[i]); + if (ret[i][intValue-1] == '"') { + attributes->codecs = gf_strdup(&(ret[i][7])); + } + } + i++; + } + return ret; + } + return NULL; +} + +#define M3U8_BUF_SIZE 2048 + +GF_Err parse_root_playlist(const char * file, VariantPlaylist ** playlist, const char * baseURL) +{ + return parse_sub_playlist(file, playlist, baseURL, NULL, NULL); +} + +GF_Err parse_sub_playlist(const char * file, VariantPlaylist ** playlist, const char * baseURL, Program * in_program, PlaylistElement *sub_playlist) +{ + int readen, readPointer, len, i, currentLineNumber; + FILE * f; + VariantPlaylist * pl; + char currentLine[M3U8_BUF_SIZE]; + char ** attributes = NULL; + s_accumulated_attributes attribs; + f = gf_f64_open(file, "rt"); + if (!f) { + GF_LOG( GF_LOG_ERROR, GF_LOG_CONTAINER,("[M3U8] Cannot Open m3u8 file %s for reading\n", file)); + return GF_SERVICE_ERROR; + } + if (*playlist == NULL) { + *playlist = variant_playlist_new(); + if (!(*playlist)) { + fclose(f); + return GF_OUT_OF_MEM; + } + } + pl = *playlist; + readen=0; + readPointer = 0; + currentLineNumber = 0; + bzero(&attribs, sizeof(s_accumulated_attributes)); + attribs.bandwidth = 0; + attribs.durationInSeconds = 0; + attribs.targetDurationInSeconds = 0; + attribs.isVariantPlaylist = 0; + attribs.isPlaylistEnded = 0; + attribs.minMediaSequence = 0; + attribs.currentMediaSequence = 0; + while (fgets(currentLine, sizeof(currentLine), f)) { + char * eof; + currentLineNumber++; + eof = strchr(currentLine, '\r'); + if (eof) + eof[0] = '\0'; + eof = strchr(currentLine, '\n'); + if (eof) + eof[0] = '\0'; + len = strlen( currentLine); + if (len < 1) + continue; + if (currentLineNumber == 1) { + /* Playlist MUST start with #EXTM3U */ + if (len < 7 || strncmp("#EXTM3U", currentLine, 7)!=0) { + fclose(f); + variant_playlist_del(pl); + GF_LOG( GF_LOG_ERROR, GF_LOG_CONTAINER, ("Failed to parse M3U8 File, it should start with #EXTM3U, but was : %s\n", currentLine)); + return GF_STREAM_NOT_FOUND; + } + continue; + } + if (currentLine[0] == '#') { + /* A comment or a directive */ + if (strncmp("#EXT", currentLine, 4)==0) { + attributes = parseAttributes(currentLine, &attribs); + if (attributes == NULL) { + MYLOG(("Comment at line %d : %s\n", currentLineNumber, currentLine)); + } else { + MYLOG(("Directive at line %d: \"%s\", attributes=", currentLineNumber, currentLine)); + i = 0; + while (attributes[i] != NULL) { + MYLOG((" [%d]='%s'", i, attributes[i])); + gf_free(attributes[i]); + attributes[i] = NULL; + i++; + } + MYLOG(("\n")); + gf_free(attributes); + attributes = NULL; + } + if (attribs.isPlaylistEnded) { + pl->playlistNeedsRefresh = 0; + } + } + } else { + char * fullURL = currentLine; + //printf("Line %d: '%s'\n", currentLineNumber, currentLine); + + if (gf_url_is_local(currentLine)) { + /* + if (gf_url_is_local(baseURL)){ + int num_chars = -1; + if (baseURL[strlen(baseURL)-1] == '/'){ + num_chars = asprintf(&fullURL, "%s%s", baseURL, currentLine); + } else { + num_chars = asprintf(&fullURL, "%s/%s", baseURL, currentLine); + } + if (num_chars < 0 || fullURL == NULL){ + variant_playlist_del(*playlist); + playlist = NULL; + return GF_OUT_OF_MEM; + } + } else */ { + fullURL = gf_url_concatenate(baseURL, currentLine); + } + assert( fullURL ); + /*printf("*** calculated full path = %s from %s and %s\n", fullURL, currentLine, baseURL);*/ + } + { + u32 count; + PlaylistElement * currentPlayList = sub_playlist; + /* First, we have to find the matching program */ + Program * program = in_program; + if (!in_program) program = variant_playlist_find_matching_program(pl, attribs.programId); + /* We did not found the program, we create it */ + if (program == NULL) { + program = program_new(attribs.programId); + if (program == NULL) { + /* OUT of memory */ + variant_playlist_del(*playlist); + fclose(f); + playlist = NULL; + return GF_OUT_OF_MEM; + } + gf_list_add(pl->programs, program); + if (pl->currentProgram < 0) + pl->currentProgram = program->programId; + } + + /* OK, we have a program, we have to choose the elements with same bandwidth */ + assert( program ); + assert( program->bitrates); + count = gf_list_count( program->bitrates); + + if (!currentPlayList) { + for (i = 0; i < (s32) count; i++) { + PlaylistElement * itPlayListElement = gf_list_get(program->bitrates, i); + assert( itPlayListElement ); + if (itPlayListElement->bandwidth == attribs.bandwidth) { + currentPlayList = itPlayListElement; + break; + } + } + } + + if (attribs.isVariantPlaylist) { + /* We are the Variant Playlist */ + if (currentPlayList != NULL) { + /* should not happen, it means we redefine something previsouly added */ + //assert( 0 ); + } + currentPlayList = playlist_element_new( + TYPE_UNKNOWN, + fullURL, + attribs.title, + attribs.codecs, + attribs.durationInSeconds); + if (currentPlayList == NULL) { + /* OUT of memory */ + variant_playlist_del(*playlist); + playlist = NULL; + fclose(f); + return GF_OUT_OF_MEM; + } + assert( fullURL); + currentPlayList->url = gf_strdup(fullURL); + currentPlayList->title = attribs.title ? gf_strdup(attribs.title):NULL; + currentPlayList->codecs = attribs.codecs ? gf_strdup(attribs.codecs):NULL; + gf_list_add(program->bitrates, currentPlayList); + } else { + /* Normal Playlist */ + assert( pl->programs); + if (currentPlayList == NULL) { + /* This is in facts a "normal" playlist without any element in it */ + PlaylistElement * subElement; + assert(baseURL); + currentPlayList = playlist_element_new( + TYPE_PLAYLIST, + baseURL, + attribs.title, + attribs.codecs, + attribs.durationInSeconds); + if (currentPlayList == NULL) { + /* OUT of memory */ + variant_playlist_del(*playlist); + playlist = NULL; + fclose(f); + return GF_OUT_OF_MEM; + } + assert(currentPlayList->element.playlist.elements); + assert( fullURL); + assert( currentPlayList->url); + currentPlayList->title = NULL; + currentPlayList->codecs = NULL; + subElement = playlist_element_new( + TYPE_UNKNOWN, + fullURL, + attribs.title, + attribs.codecs, + attribs.durationInSeconds); + if (subElement == NULL) { + variant_playlist_del(*playlist); + playlist_element_del(currentPlayList); + playlist = NULL; + fclose(f); + return GF_OUT_OF_MEM; + } + gf_list_add(currentPlayList->element.playlist.elements, subElement); + gf_list_add(program->bitrates, currentPlayList); + assert( program ); + assert( program->bitrates); + assert( currentPlayList); + + } else { + PlaylistElement * subElement = playlist_element_new( + TYPE_UNKNOWN, + fullURL, + attribs.title, + attribs.codecs, + attribs.durationInSeconds); + if (currentPlayList->elementType != TYPE_PLAYLIST) { + currentPlayList->elementType = TYPE_PLAYLIST; + if (!currentPlayList->element.playlist.elements) + currentPlayList->element.playlist.elements = gf_list_new(); + } + if (subElement == NULL) { + variant_playlist_del(*playlist); + playlist_element_del(currentPlayList); + playlist = NULL; + fclose(f); + return GF_OUT_OF_MEM; + } + gf_list_add(currentPlayList->element.playlist.elements, subElement); + } + } + + currentPlayList->element.playlist.currentMediaSequence = attribs.currentMediaSequence ; + /* We first set the default duration for element, aka targetDuration */ + if (attribs.targetDurationInSeconds > 0) { + currentPlayList->element.playlist.target_duration = attribs.targetDurationInSeconds; + currentPlayList->durationInfo = attribs.targetDurationInSeconds; + } + if (attribs.durationInSeconds) { + currentPlayList->durationInfo = attribs.durationInSeconds; + } + currentPlayList->element.playlist.mediaSequenceMin = attribs.minMediaSequence; + currentPlayList->element.playlist.mediaSequenceMax = attribs.currentMediaSequence++; + if (attribs.bandwidth > 1) + currentPlayList->bandwidth = attribs.bandwidth; + if (attribs.isPlaylistEnded) + currentPlayList->element.playlist.is_ended = 1; + } + /* Cleanup all line-specific fields */ + if (attribs.title) { + gf_free(attribs.title); + attribs.title = NULL; + } + attribs.durationInSeconds = 0; + attribs.bandwidth = 0; + attribs.programId = 0; + if (attribs.codecs != NULL) { + gf_free(attribs.codecs); + attribs.codecs = NULL; + } + if (fullURL != currentLine) { + gf_free(fullURL); + } + } + } + fclose(f); + return GF_OK; +} diff --git a/src/media_tools/media_export.c b/src/media_tools/media_export.c index f60ba62..c907da8 100644 --- a/src/media_tools/media_export.c +++ b/src/media_tools/media_export.c @@ -1717,7 +1717,7 @@ GF_Err gf_media_export_nhml(GF_MediaExporter *dumper, Bool dims_doc) samp->data[pos+2+size] = 0; - fprintf(nhml, "<DIMSUnit time=\""LLD"\"", LLD_CAST samp->DTS); + fprintf(nhml, "<DIMSUnit time=\""LLU"\"", LLU_CAST samp->DTS); /*DIMS flags*/ if (flags & GF_DIMS_UNIT_S) fprintf(nhml, " is-Scene=\"yes\""); if (flags & GF_DIMS_UNIT_M) fprintf(nhml, " is-RAP=\"yes\""); @@ -1764,8 +1764,8 @@ GF_Err gf_media_export_nhml(GF_MediaExporter *dumper, Bool dims_doc) gf_bs_del(bs); } else { - fprintf(nhml, "<NHNTSample DTS=\""LLD"\" dataLength=\"%d\" ", LLD_CAST samp->DTS, samp->dataLength); - if (full_dump || samp->CTS_Offset) fprintf(nhml, "CTSOffset=\"%d\" ", samp->CTS_Offset); + fprintf(nhml, "<NHNTSample DTS=\""LLU"\" dataLength=\"%d\" ", LLU_CAST samp->DTS, samp->dataLength); + if (full_dump || samp->CTS_Offset) fprintf(nhml, "CTSOffset=\"%u\" ", samp->CTS_Offset); if (samp->IsRAP==1) fprintf(nhml, "isRAP=\"yes\" "); else if (samp->IsRAP==2) fprintf(nhml, "isSyncShadow=\"yes\" "); else if (full_dump) fprintf(nhml, "isRAP=\"no\" "); diff --git a/src/media_tools/media_import.c b/src/media_tools/media_import.c index 7b0cd80..b76406e 100644 --- a/src/media_tools/media_import.c +++ b/src/media_tools/media_import.c @@ -34,9 +34,8 @@ /*since 0.2.2, we use zlib for xmt/x3d reading to handle gz files*/ #include <zlib.h> -#ifndef GPAC_DISABLE_MEDIA_IMPORT -#define GF_IMPORT_DEFAULT_FPS 25.0 +#ifndef GPAC_DISABLE_MEDIA_IMPORT GF_Err gf_import_message(GF_MediaImporter *import, GF_Err e, char *format, ...) @@ -793,7 +792,8 @@ static GF_Err gf_import_cmp(GF_MediaImporter *import, Bool mpeg12) max_size = 4096; samp->data = (char*)gf_malloc(sizeof(char)*max_size); /*no auto frame-rate detection*/ - if (import->video_fps == 10000.0) import->video_fps = 25.0; + if (import->video_fps == GF_IMPORT_AUTO_FPS) + import->video_fps = GF_IMPORT_DEFAULT_FPS; PL = dsi.VideoPL; if (!PL) { @@ -1104,7 +1104,8 @@ static GF_Err gf_import_avi_video(GF_MediaImporter *import) goto exit; } /*no auto frame-rate detection*/ - if (import->video_fps == 10000.0) import->video_fps = 25.0; + if (import->video_fps == GF_IMPORT_AUTO_FPS) + import->video_fps = GF_IMPORT_DEFAULT_FPS; FPS = AVI_frame_rate(in); if (import->video_fps) FPS = (Double) import->video_fps; @@ -1703,6 +1704,9 @@ GF_Err gf_import_isomedia(GF_MediaImporter *import) } if (e) goto exit; import->final_trackID = gf_isom_get_track_id(import->dest, track); + if (import->esd && import->esd->dependsOnESID) { + gf_isom_set_track_reference(import->dest, track, GF_ISOM_REF_DECODE, import->esd->dependsOnESID); + } switch (mtype) { case GF_ISOM_MEDIA_VISUAL: @@ -1810,7 +1814,8 @@ GF_Err gf_import_mpeg_ps_video(GF_MediaImporter *import) return gf_import_message(import, GF_NOT_SUPPORTED, "Cannot use data referencing with MPEG-1/2 files"); /*no auto frame-rate detection*/ - if (import->video_fps == 10000.0) import->video_fps = 25.0; + if (import->video_fps == GF_IMPORT_AUTO_FPS) + import->video_fps = GF_IMPORT_DEFAULT_FPS; ps = mpeg2ps_init(import->in_name); if (!ps) return gf_import_message(import, GF_NON_COMPLIANT_BITSTREAM, "Failed to open MPEG file %s", import->in_name); @@ -2835,10 +2840,11 @@ GF_Err gf_import_nhml_dims(GF_MediaImporter *import, Bool dims_doc) while ( (att = (GF_XMLAttribute *)gf_list_enum(node->attributes, &j))) { if (!stricmp(att->name, "DTS") || !stricmp(att->name, "time")) { u32 h, m, s, ms; - if (sscanf(att->value, "%u:%u:%u.%u", &h, &m, &s, &ms) == 4) { - samp->DTS = (u64) ( (Double) ( ((h*3600 + m*60 + s)*1000 + ms) / 1000.0) * timescale ); - } else { - samp->DTS = atoi(att->value); + u64 dst_val; + if (strchr(att->value, ':') && sscanf(att->value, "%u:%u:%u.%u", &h, &m, &s, &ms) == 4) { + samp->DTS = (u64) ( (Double) ( ((h*3600.0 + m*60.0 + s)*1000 + ms) / 1000.0) * timescale ); + } else if (sscanf(att->value, ""LLU, &dst_val)==1) { + samp->DTS = dst_val; } } else if (!stricmp(att->name, "CTSOffset")) samp->CTS_Offset = atoi(att->value); @@ -3584,7 +3590,8 @@ GF_Err gf_import_h263(GF_MediaImporter *import) goto exit; } /*no auto frame-rate detection*/ - if (import->video_fps == 10000.0) import->video_fps = 25.0; + if (import->video_fps == GF_IMPORT_AUTO_FPS) + import->video_fps = GF_IMPORT_DEFAULT_FPS; FPS = (Double) import->video_fps; /*for H263 we use 15 fps by default!!*/ @@ -3688,11 +3695,12 @@ exit: fclose(mdia); return e; } -static void avc_rewrite_samples(GF_ISOFile *file, u32 track, u32 prev_size, u32 new_size) + +GF_Err gf_media_avc_rewrite_samples(GF_ISOFile *file, u32 track, u32 prev_size, u32 new_size) { u32 i, count, di, remain, msize; char *buffer; - + msize = 4096; buffer = (char*)gf_malloc(sizeof(char)*msize); count = gf_isom_get_sample_count(file, track); @@ -3723,6 +3731,7 @@ static void avc_rewrite_samples(GF_ISOFile *file, u32 track, u32 prev_size, u32 gf_isom_sample_del(&samp); } gf_free(buffer); + return GF_OK; } #ifndef GPAC_DISABLE_AV_PARSERS @@ -3740,12 +3749,13 @@ GF_Err gf_import_h264(GF_MediaImporter *import) GF_AVCConfig *avccfg, *svccfg, *dstcfg; GF_BitStream *bs; GF_BitStream *sample_data; - Bool flush_sample, sample_is_rap, first_nal, slice_is_ref, has_cts_offset, detect_fps, is_paff; + Bool flush_sample, sample_is_rap, first_nal, slice_is_ref, has_cts_offset, detect_fps, is_paff, set_subsamples; u32 ref_frame, pred_frame, timescale, copy_size, size_length, dts_inc; s32 last_poc, max_last_poc, max_last_b_poc, poc_diff, prev_last_poc, min_poc, poc_shift; Bool first_avc; u32 last_svc_sps; - u32 prev_nalu_prefix_size; + u32 prev_nalu_prefix_size, res_prev_nalu_prefix; + u8 priority_prev_nalu_prefix; Double FPS; char *buffer; u32 max_size = 4096; @@ -3758,16 +3768,21 @@ GF_Err gf_import_h264(GF_MediaImporter *import) return GF_OK; } + set_subsamples = (import->flags & GF_IMPORT_SET_SUBSAMPLES) ? 1 : 0; + mdia = gf_f64_open(import->in_name, "rb"); if (!mdia) return gf_import_message(import, GF_URL_ERROR, "Cannot find file %s", import->in_name); detect_fps = 1; - if (import->video_fps == 10000.0) { - import->video_fps = 25.0; - } - FPS = (Double) import->video_fps; - if (!FPS) FPS = GF_IMPORT_DEFAULT_FPS; + if (!FPS) { + FPS = GF_IMPORT_DEFAULT_FPS; + } else { + if (import->video_fps == GF_IMPORT_AUTO_FPS) + import->video_fps = GF_IMPORT_DEFAULT_FPS; /*fps=auto is handled as auto-detection is h264*/ + else + detect_fps = 0; /*fps is forced by the caller*/ + } get_video_timing(FPS, ×cale, &dts_inc); poc_diff = 0; @@ -3809,6 +3824,9 @@ restart_import: gf_isom_set_track_enabled(import->dest, track, 1); if (import->esd && !import->esd->ESID) import->esd->ESID = gf_isom_get_track_id(import->dest, track); import->final_trackID = gf_isom_get_track_id(import->dest, track); + if (import->esd && import->esd->dependsOnESID) { + gf_isom_set_track_reference(import->dest, track, GF_ISOM_REF_DECODE, import->esd->dependsOnESID); + } e = gf_isom_avc_config_new(import->dest, track, avccfg, NULL, NULL, &di); if (e) goto exit; @@ -3833,6 +3851,8 @@ restart_import: min_poc = 0; poc_shift = 0; prev_nalu_prefix_size = 0; + res_prev_nalu_prefix = 0; + priority_prev_nalu_prefix = 0; while (gf_bs_available(bs)) { u8 nal_hdr, skip_nal, is_subseq, add_sps; @@ -3963,6 +3983,8 @@ restart_import: } last_svc_sps = idx; } + /* prevent from adding the subseq PS to the samples */ + copy_size = 0; } else { if (first_avc) { first_avc = 0; @@ -4011,10 +4033,8 @@ restart_import: case GF_AVC_NALU_SEI: if (avc.sps_active_idx != -1) { copy_size = AVC_ReformatSEI_NALU(buffer, nal_size, &avc); - if (copy_size) { - nal_size = copy_size; /*nal_size has been modified in memory*/ + if (copy_size) nb_sei++; - } } break; @@ -4091,17 +4111,32 @@ restart_import: sample_data = NULL; if (prev_nalu_prefix_size) { + u32 size, reserved, nb_subs; + u8 priority; + Bool discardable; + samp->dataLength -= size_length/8 + prev_nalu_prefix_size; - /*remove last subsample entry!*/ - gf_isom_add_subsample(import->dest, track, cur_samp+1, 0, 0, 0); + if (set_subsamples) { + /* determine the number of subsamples */ + nb_subs = gf_isom_sample_has_subsamples(import->dest, track, cur_samp+1); + if (nb_subs) { + /* fetch size, priority, reserved and discardable info for last subsample */ + gf_isom_sample_get_subsample(import->dest, track, cur_samp+1, nb_subs, &size, &priority, &reserved, &discardable); + + /*remove last subsample entry!*/ + gf_isom_add_subsample(import->dest, track, cur_samp+1, 0, 0, 0, 0); + } + } /*rewrite last NALU prefix at the beginning of next sample*/ sample_data = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_data(sample_data, samp->data + samp->dataLength, size_length/8 + prev_nalu_prefix_size); - - /*add subsample entry to next sample*/ - gf_isom_add_subsample(import->dest, track, cur_samp+2, size_length/8 + prev_nalu_prefix_size, 1, 1); + + if (set_subsamples) { + /*add subsample entry to next sample*/ + gf_isom_add_subsample(import->dest, track, cur_samp+2, size_length/8 + prev_nalu_prefix_size, priority, reserved, discardable); + } prev_nalu_prefix_size = 0; } @@ -4129,7 +4164,7 @@ restart_import: if (size_length+diff_size == 24) diff_size+=8; gf_import_message(import, GF_OK, "Adjusting AVC SizeLength to %d bits", size_length+diff_size); - avc_rewrite_samples(import->dest, track, size_length, size_length+diff_size); + gf_media_avc_rewrite_samples(import->dest, track, size_length, size_length+diff_size); /*rewrite current sample*/ if (sample_data) { @@ -4161,11 +4196,37 @@ restart_import: /*fixme - we need finer grain for priority*/ if ((nal_type==GF_AVC_NALU_SVC_PREFIX_NALU) || (nal_type==GF_AVC_NALU_SVC_SLICE)) { - gf_isom_add_subsample(import->dest, track, cur_samp+1, copy_size+size_length, 1, 1); - } else { - gf_isom_add_subsample(import->dest, track, cur_samp+1, copy_size+size_length, 0, 0); - } + u32 res = 0; + u8 prio; + unsigned char *p = buffer; + res |= (p[0] & 0x60) ? 0x80000000 : 0; // RefPicFlag + res |= 0 ? 0x40000000 : 0; // RedPicFlag TODO: not supported, would require to parse NAL unit payload + res |= (1<=nal_type && nal_type<=5) || (nal_type==GF_AVC_NALU_SVC_PREFIX_NALU) || (nal_type==GF_AVC_NALU_SVC_SLICE) ? 0x20000000 : 0; // VclNALUnitFlag + res |= p[1] << 16; // use values of IdrFlag and PriorityId directly from SVC extension header + res |= p[2] << 8; // use values of DependencyId and QualityId directly from SVC extension header + res |= p[3] & 0xFC; // use values of TemporalId and UseRefBasePicFlag directly from SVC extension header + res |= 0 ? 0x00000002 : 0; // StoreBaseRepFlag TODO: SVC FF mentions a store_base_rep_flag which cannot be found in SVC spec + + // priority_id (6 bits) in SVC has inverse meaning -> lower value means higher priority - invert it and scale it to 8 bits + prio = (63 - (p[1] & 0x3F)) << 2; + + if (set_subsamples) { + gf_isom_add_subsample(import->dest, track, cur_samp+1, copy_size+size_length/8, prio, res, 1); + } + if (nal_type==GF_AVC_NALU_SVC_PREFIX_NALU) { + /* remember reserved and priority value */ + res_prev_nalu_prefix = res; + priority_prev_nalu_prefix = prio; + } + } else if (set_subsamples) { + /* use the res and priority value of last prefix NALU */ + gf_isom_add_subsample(import->dest, track, cur_samp+1, copy_size+size_length/8, priority_prev_nalu_prefix, res_prev_nalu_prefix, 0); + } + if (nal_type!=GF_AVC_NALU_SVC_PREFIX_NALU) { + res_prev_nalu_prefix = 0; + priority_prev_nalu_prefix = 0; + } if (nal_type != GF_AVC_NALU_SVC_PREFIX_NALU) { prev_nalu_prefix_size = 0; @@ -4175,7 +4236,6 @@ restart_import: switch (nal_type) { case GF_AVC_NALU_SVC_SLICE: - nal_size = nal_size; case GF_AVC_NALU_NON_IDR_SLICE: case GF_AVC_NALU_DP_A_SLICE: case GF_AVC_NALU_DP_B_SLICE: @@ -4273,7 +4333,7 @@ restart_import: /*consume next start code*/ nal_start = AVC_NextStartCode(bs); if (nal_start) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[avc-h264] invalid nal_size? Skipping "LLU" bytes to reach next start code\n", nal_start)); + GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[avc-h264] invalid nal_size (%u)? Skipping "LLU" bytes to reach next start code\n", nal_size, nal_start)); gf_bs_skip_bytes(bs, nal_start); } nal_start = AVC_IsStartCode(bs); @@ -5598,6 +5658,7 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) esd->decoderConfig->decoderSpecificInfo->data = NULL; gf_odf_desc_del((GF_Descriptor *)esd); tsimp->stream_setup = 1; + gf_isom_set_audio_info(import->dest, tsimp->track, 1, ((GF_M2TS_PES_PCK*)par)->stream->aud_sr, ((GF_M2TS_PES_PCK*)par)->stream->aud_nb_ch, 8); } } break; @@ -5731,6 +5792,10 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) if (pck->flags & GF_M2TS_PES_PCK_I_FRAME) tsimp->nb_i++; if (pck->flags & GF_M2TS_PES_PCK_P_FRAME) tsimp->nb_p++; if (pck->flags & GF_M2TS_PES_PCK_B_FRAME) tsimp->nb_b++; + + if (pck->flags & GF_M2TS_PES_PCK_RAP) { + e = gf_isom_set_sample_rap(import->dest, tsimp->track); + } return; } @@ -5748,8 +5813,8 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) case GF_M2TS_AUDIO_MPEG2: gf_import_message(import, GF_OK, "MPEG-2 Audio import - SampleRate %d Channels %d Language %s (TS PID %d)", pck->stream->aud_sr, pck->stream->aud_nb_ch, gf_4cc_to_str(pck->stream->lang), pck->stream->pid); break; case GF_M2TS_AUDIO_AAC: gf_import_message(import, GF_OK, "MPEG-4 AAC Audio import - SampleRate %d Channels %d Language %s (TS PID %d)", pck->stream->aud_sr, pck->stream->aud_nb_ch, gf_4cc_to_str(pck->stream->lang), pck->stream->pid); break; } - - gf_isom_set_media_language(import->dest, tsimp->track, (char *) gf_4cc_to_str(pck->stream->lang)+1); + if (pck->stream->lang) + gf_isom_set_media_language(import->dest, tsimp->track, (char *) gf_4cc_to_str(pck->stream->lang)+1); } if (!tsimp->stream_setup) { if (pck->stream->aud_sr) { @@ -6056,7 +6121,8 @@ GF_Err gf_import_vobsub(GF_MediaImporter *import) GF_Err err = GF_OK; GF_ISOSample *samp = NULL; GF_List *subpic; - u32 total, last_samp_dur = 0; + u64 last_dts = 0; + u32 total, last_samp_dur = 0; unsigned char buf[0x800]; strcpy(filename, import->in_name); @@ -6178,6 +6244,7 @@ GF_Err gf_import_vobsub(GF_MediaImporter *import) subpic = vobsub->langs[trackID].subpos; total = gf_list_count(subpic); + last_dts = 0; for (c = 0; c < total; c++) { u32 i, left, size, psize, dsize, hsize, duration; @@ -6252,12 +6319,18 @@ GF_Err gf_import_vobsub(GF_MediaImporter *import) samp->data = packet; samp->dataLength = psize; samp->DTS = pos->start * 90; + + if (last_dts && (last_dts >= samp->DTS)) { + err = gf_import_message(import, GF_CORRUPTED_DATA, "Out of order timestamps in vobsub file"); + goto error; + } err = gf_isom_add_sample(import->dest, track, di, samp); if (err) goto error; gf_free(packet); gf_set_progress("Importing VobSub", c, total); + last_dts = samp->DTS; if (import->flags & GF_IMPORT_DO_ABORT) { break; diff --git a/src/media_tools/mpd.c b/src/media_tools/mpd.c index 1af5912..5722f9d 100644 --- a/src/media_tools/mpd.c +++ b/src/media_tools/mpd.c @@ -1,719 +1,742 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Cyril Concolato - * Copyright (c) Telecom ParisTech 2010- - * All rights reserved - * - * This file is part of GPAC / 3GPP/MPEG Media Presentation Description input module - * - * 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 <gpac/internal/mpd.h> -#include <gpac/download.h> -#include <gpac/internal/m3u8.h> -#include <gpac/network.h> - -static u32 gf_mpd_parse_duration(char *duration) { - u32 i; - if (!duration) return 0; - i = 0; - while (1) { - if (duration[i] == ' ') i++; - else if (duration[i] == 0) return 0; - else { - break; - } - } - if (duration[i] == 'P') { - if (duration[i+1] == 0) return 0; - else if (duration[i+1] != 'T') return 0; - else { - char *sep1, *sep2; - u32 h, m; - double s; - h = m = 0; - s = 0; - if (NULL != (sep1 = strchr(duration+i+2, 'H'))) { - *sep1 = 0; - h = atoi(duration+i+2); - *sep1 = 'H'; - sep1++; - } else { - sep1 = duration+i+2; - } - if (NULL != (sep2 = strchr(sep1, 'M'))) { - *sep2 = 0; - m = atoi(sep1); - *sep2 = 'M'; - sep2++; - } else { - sep2 = sep1; - } - if (NULL != (sep1 = strchr(sep2, 'S'))) { - *sep1 = 0; - s = atof(sep2); - *sep1 = 'S'; - } - return (u32)((h*3600+m*60+s)*1000); - } - } else { - return 0; - } -} - -static GF_Err gf_mpd_parse_rep_cp(GF_XMLNode *root, GF_MPD_Representation *rep) -{ - u32 att_index; - GF_XMLAttribute *att; - att_index = 0; - while (1) { - att = gf_list_get(root->attributes, att_index); - if (!att) { - break; - } else if (!strcmp(att->name, "SchemeInformation")) { - rep->content_protection_type = gf_strdup(att->value); - } else if (!strcmp(att->name, "schemeIdUri")) { - rep->content_protection_uri = gf_strdup(att->value); - } - att_index++; - } - - return GF_OK; -} - -static GF_Err gf_mpd_parse_rep_trickmode(GF_XMLNode *root, GF_MPD_Representation *rep) -{ - u32 att_index; - GF_XMLAttribute *att; - att_index = 0; - while (1) { - att = gf_list_get(root->attributes, att_index); - if (!att) { - break; - } else if (!strcmp(att->name, "alternatePlayoutRate")) { - rep->alternatePlayoutRate = atof(att->value); - } - att_index++; - } - - return GF_OK; -} - -static GF_Err gf_mpd_parse_rep_initseg(GF_XMLNode *root, GF_MPD_Representation *rep, const char * baseURL) -{ - u32 att_index; - GF_XMLAttribute *att; - - att_index = 0; - while (1) { - att = gf_list_get(root->attributes, att_index); - if (!att) { - break; - } else if (!strcmp(att->name, "sourceURL")) { - GF_URL_Info info; - GF_Err e; - gf_dm_url_info_init(&info); - e = gf_dm_get_url_info(att->value, &info, baseURL); - assert( e == GF_OK ); - assert( info.canonicalRepresentation); - rep->init_url = gf_strdup(info.canonicalRepresentation); - gf_dm_url_info_del(&info); - } else if (!strcmp(att->name, "range")) { - rep->init_use_range = 1; - sscanf(att->value, "%d-%d", &rep->init_byterange_start, &rep->init_byterange_end); - } - att_index++; - } - return GF_OK; -} - -static GF_Err gf_mpd_parse_rep_urltemplate(GF_XMLNode *root, GF_MPD_Representation *rep) -{ - u32 att_index; - GF_XMLAttribute *att; - - att_index = 0; - while (1) { - att = gf_list_get(root->attributes, att_index); - if (!att) { - break; - } else if (!strcmp(att->name, "sourceURL")) { - rep->url_template = gf_strdup(att->value); - } else if (!strcmp(att->name, "id")) { - rep->id = gf_strdup(att->value); - } else if (!strcmp(att->name, "startIndex")) { - rep->startIndex = atoi(att->value)-1; - } else if (!strcmp(att->name, "endIndex")) { - rep->endIndex = atoi(att->value)-1; - } - att_index++; - } - return GF_OK; -} - -static GF_Err gf_mpd_parse_rep_urlelt(GF_XMLNode *root, GF_MPD_SegmentInfo *seg, const char * baseURL) -{ - u32 att_index; - GF_XMLAttribute *att; - - att_index = 0; - while (1) { - att = gf_list_get(root->attributes, att_index); - if (!att) { - break; - } else if (!strcmp(att->name, "sourceURL")) { - GF_URL_Info info; - GF_Err e; - gf_dm_url_info_init(&info); - e = gf_dm_get_url_info(att->value, &info, baseURL); - assert( e == GF_OK ); - assert( info.canonicalRepresentation); - seg->url = gf_strdup(info.canonicalRepresentation); - gf_dm_url_info_del(&info); - } else if (!strcmp(att->name, "range")) { - seg->use_byterange = 1; - sscanf(att->value, "%d-%d", &seg->byterange_start, &seg->byterange_end); - } - att_index++; - } - return GF_OK; -} - -static GF_Err gf_mpd_parse_rep_segmentinfo(GF_XMLNode *root, GF_MPD_Representation *rep) -{ - u32 att_index, child_index; - u32 nb_urlelements; - GF_XMLAttribute *att; - GF_XMLNode *child; - - att_index = 0; - while (1) { - att = gf_list_get(root->attributes, att_index); - if (!att) { - break; - } else if (!strcmp(att->name, "duration")) { - rep->default_segment_duration = gf_mpd_parse_duration(att->value); - } else if (!strcmp(att->name, "baseURL")) { - rep->default_base_url = gf_strdup(att->value); - } - att_index++; - } - - child_index = 0; - nb_urlelements = 0; - while (1) { - child = gf_list_get(root->content, child_index); - if (!child) { - break; - } else if (child->type == GF_XML_NODE_TYPE) { - if (!strcmp(child->name, "InitialisationSegmentURL")) { - gf_mpd_parse_rep_initseg(child, rep, rep->default_base_url); - } else if (!strcmp(child->name, "UrlTemplate")) { - gf_mpd_parse_rep_urltemplate(child, rep); - } else if (!strcmp(child->name, "Url")) { - nb_urlelements++; - } - } - child_index++; - } - - /* We assume that URL Template has precedence over URL elements */ - if (rep->url_template) { - /* TODO: expand the template to create segment urls*/ - } else if (nb_urlelements) { - u32 urlelt_index = 0; - assert( !rep->segments ); - rep->segments = gf_list_new(); - - child_index = 0; - while (1) { - child = gf_list_get(root->content, child_index); - if (!child) { - break; - } else if (child->type == GF_XML_NODE_TYPE) { - if (!strcmp(child->name, "Url")) { - GF_MPD_SegmentInfo *seg_info; - GF_SAFEALLOC(seg_info, GF_MPD_SegmentInfo); - if (!seg_info) - return GF_OUT_OF_MEM; - memset(seg_info, 0, sizeof(GF_MPD_SegmentInfo)); - seg_info->byterange_end = 0; - seg_info->byterange_start = 0; - seg_info->use_byterange = 0; - seg_info->url = NULL; - gf_mpd_parse_rep_urlelt(child, seg_info, rep->default_base_url); - gf_list_add(rep->segments, seg_info); - urlelt_index++; - } - } - child_index++; - } - } - return GF_OK; -} - -static GF_Err gf_mpd_parse_representation(GF_XMLNode *root, GF_MPD_Representation *rep) -{ - u32 att_index, child_index; - GF_XMLAttribute *att; - GF_XMLNode *child; - - att_index = 0; - while (1) { - att = gf_list_get(root->attributes, att_index); - if (!att) { - break; - } else if (!strcmp(att->name, "bandwidth")) { - rep->bandwidth = atoi(att->value); - } else if (!strcmp(att->name, "width")) { - rep->width = atoi(att->value); - } else if (!strcmp(att->name, "height")) { - rep->height = atoi(att->value); - } else if (!strcmp(att->name, "lang")) { - rep->lang = gf_strdup(att->value); - } else if (!strcmp(att->name, "mimeType")) { - rep->mime = gf_strdup(att->value); - } else if (!strcmp(att->name, "group")) { - rep->groupID = atoi(att->value); - } else if (!strcmp(att->name, "startWithRAP")) { - if (!strcmp(att->value, "true")) rep->startWithRap = 1; - } else if (!strcmp(att->name, "qualityRanking")) { - rep->qualityRanking = atoi(att->value); - } - att_index++; - } - - child_index = 0; - while (1) { - child = gf_list_get(root->content, child_index); - if (!child) { - break; - } else if (child->type == GF_XML_NODE_TYPE) { - if (!strcmp(child->name, "ContentProtection")) { - gf_mpd_parse_rep_cp(child, rep); - } else if (!strcmp(child->name, "TrickMode")) { - gf_mpd_parse_rep_trickmode(child, rep); - } else if (!strcmp(child->name, "SegmentInfo")) { - gf_mpd_parse_rep_segmentinfo(child, rep); - } - } - child_index++; - } - return GF_OK; -} - -static GF_Err gf_mpd_parse_segment_info_default(GF_XMLNode *root, GF_MPD_Period *period) -{ - u32 att_index; - GF_XMLAttribute *att; - - att_index = 0; - while (1) { - att = gf_list_get(root->attributes, att_index); - if (!att) { - break; - } else if (!strcmp(att->name, "duration")) { - period->default_segment_duration = gf_mpd_parse_duration(att->value); - } else if (!strcmp(att->name, "baseURL")) { - period->default_base_url = gf_strdup(att->value); - } else if (!strcmp(att->name, "sourceUrlTemplatePeriod")) { - period->url_template = gf_strdup(att->value); - } - att_index++; - } - - return GF_OK; -} - -static GF_Err gf_mpd_parse_period(GF_XMLNode *root, GF_MPD_Period *period) -{ - u32 att_index, child_index; - GF_XMLAttribute *att; - GF_XMLNode *child; - - att_index = 0; - while (1) { - att = gf_list_get(root->attributes, att_index); - if (!att) { - break; - } else if (!strcmp(att->name, "start")) { - } else if (!strcmp(att->name, "segmentAlignmentFlag")) { - if (!strcmp(att->value, "true")) { - period->segment_alignment_flag = 1; - } - } else if (!strcmp(att->name, "bitstreamSwitchingFlag")) { - if (!strcmp(att->value, "true")) { - period->segment_alignment_flag = 1; - } - } - att_index++; - } - - child_index = 0; - while (1) { - child = gf_list_get(root->content, child_index); - if (!child) { - break; - } else if (child->type == GF_XML_NODE_TYPE) { - if (!strcmp(child->name, "SegmentInfoDefault")) { - gf_mpd_parse_segment_info_default(child, period); - } else if (!strcmp(child->name, "Representation")) { - GF_MPD_Representation *rep; - GF_SAFEALLOC(rep, GF_MPD_Representation); - if (!rep) - return GF_OUT_OF_MEM; - memset( rep, 0, sizeof(GF_MPD_Representation)); - gf_mpd_parse_representation(child, rep); - gf_list_add(period->representations, rep); - } - } - child_index++; - } - - return GF_OK; -} - -static GF_Err gf_mpd_parse_program_info(GF_XMLNode *root, GF_MPD *mpd) -{ - u32 att_index, child_index; - GF_XMLAttribute *att; - GF_XMLNode *child; - - att_index = 0; - while (1) { - att = gf_list_get(root->attributes, att_index); - if (!att) { - break; - } else if (!strcmp(att->name, "moreInformationURL")) { - mpd->more_info_url = gf_strdup(att->value); - } - att_index++; - } - - child_index = 0; - while (1) { - child = gf_list_get(root->content, child_index); - if (!child) { - break; - } else if (child->type == GF_XML_NODE_TYPE) { - if (!strcmp(child->name, "Title")) { - GF_XMLNode *data_node = gf_list_get(child->content, 0); - if (data_node && data_node->type == GF_XML_TEXT_TYPE) { - mpd->title = gf_strdup(data_node->name); - } - } else if (!strcmp(child->name, "Source")) { - GF_XMLNode *data_node = gf_list_get(child->content, 0); - if (data_node && data_node->type == GF_XML_TEXT_TYPE) { - mpd->source = gf_strdup(data_node->name); - } - } else if (!strcmp(child->name, "Copyright")) { - GF_XMLNode *data_node = gf_list_get(child->content, 0); - if (data_node && data_node->type == GF_XML_TEXT_TYPE) { - mpd->copyright = gf_strdup(data_node->name); - } - } - } - child_index++; - } - return GF_OK; -} - -GF_MPD *gf_mpd_new() -{ - GF_MPD *mpd; - GF_SAFEALLOC(mpd, GF_MPD); - if (mpd){ - memset(mpd, 0, sizeof(GF_MPD)); - } - return mpd; -} - -void gf_mpd_del(GF_MPD *mpd) -{ - while (gf_list_count(mpd->periods)) { - GF_MPD_Period *period = gf_list_get(mpd->periods, 0); - gf_list_rem(mpd->periods, 0); - while (gf_list_count(period->representations)) { - GF_MPD_Representation *rep = gf_list_get(period->representations, 0); - gf_list_rem(period->representations, 0); - - while (gf_list_count(rep->segments)) { - GF_MPD_SegmentInfo *seg = gf_list_get(rep->segments, 0); - gf_list_rem(rep->segments, 0); - if (seg->url) gf_free(seg->url); - gf_free(seg); - } - if (rep->content_protection_type) gf_free(rep->content_protection_type); - rep->content_protection_type = NULL; - if (rep->content_protection_uri) gf_free(rep->content_protection_uri); - rep->content_protection_uri = NULL; - if (rep->default_base_url) gf_free(rep->default_base_url); - rep->default_base_url = NULL; - if (rep->id) gf_free(rep->id); - rep->id = NULL; - if (rep->init_url) gf_free(rep->init_url); - rep->init_url = NULL; - if (rep->lang) gf_free(rep->lang); - rep->lang = NULL; - if (rep->mime) gf_free(rep->mime); - rep->mime = NULL; - if (rep->url_template) gf_free(rep->url_template); - rep->url_template = NULL; - if (rep->segments) gf_list_del(rep->segments); - rep->segments = NULL; - gf_free(rep); - } - gf_list_del(period->representations); - period->representations = NULL; - if (period->default_base_url) gf_free(period->default_base_url); - if (period->url_template) gf_free(period->url_template); - - gf_free(period); - } - gf_list_del(mpd->periods); - mpd->periods = NULL; - if (mpd->base_url) gf_free(mpd->base_url); - mpd->base_url = NULL; - if (mpd->title) gf_free(mpd->title); - mpd->title = NULL; - if (mpd->source) gf_free(mpd->source); - mpd->source = NULL; - if (mpd->copyright) gf_free(mpd->copyright); - mpd->copyright = NULL; - if (mpd->more_info_url) gf_free(mpd->more_info_url); - mpd->more_info_url = NULL; - gf_free(mpd); -} - -GF_Err gf_mpd_init_from_dom(GF_XMLNode *root, GF_MPD *mpd) -{ - u32 att_index, child_index; - GF_XMLAttribute *att; - GF_XMLNode *child; - - if (!root || !mpd) return GF_BAD_PARAM; - - assert( !mpd->periods ); - mpd->periods = gf_list_new(); - - att_index = 0; - child_index = gf_list_count(root->attributes); - for (att_index = 0 ; att_index < child_index; att_index++) { - att = gf_list_get(root->attributes, att_index); - if (!att) { - continue; - } else if (!strcmp(att->name, "type")) { - if (!strcmp(att->value, "OnDemand")) mpd->type = GF_MPD_TYPE_ON_DEMAND; - else if (!strcmp(att->value, "Live")) mpd->type = GF_MPD_TYPE_LIVE; - } else if (!strcmp(att->name, "availabilityStartTime")) { - } else if (!strcmp(att->name, "availabilityEndTime")) { - } else if (!strcmp(att->name, "mediaPresentationDuration")) { - mpd->duration = gf_mpd_parse_duration(att->value); - } else if (!strcmp(att->name, "minimumUpdatePeriodMPD")) { - mpd->min_update_time = gf_mpd_parse_duration(att->value); - } else if (!strcmp(att->name, "minBufferTime")) { - mpd->min_buffer_time = gf_mpd_parse_duration(att->value); - } else if (!strcmp(att->name, "timeShiftBufferDepth")) { - mpd->time_shift_buffer_depth = gf_mpd_parse_duration(att->value); - } else if (!strcmp(att->name, "baseURL")) { - } - } - - child_index = 0; - while (1) { - child = gf_list_get(root->content, child_index); - if (!child) { - break; - } else if (child->type == GF_XML_NODE_TYPE) { - if (!strcmp(child->name, "ProgramInformation")) { - gf_mpd_parse_program_info(child, mpd); - } else if (!strcmp(child->name, "Period")) { - GF_MPD_Period *period; - GF_SAFEALLOC(period, GF_MPD_Period); - if (!period) - return GF_OUT_OF_MEM; - period->representations = gf_list_new(); - gf_mpd_parse_period(child, period); - gf_list_add(mpd->periods, period); - } - } - child_index++; - } - return GF_OK; -} - -GF_Err gf_m3u8_to_mpd(GF_ClientService *service, const char *m3u8_file, const char *base_url, - const char *mpd_file, - u32 reload_count, char *mimeTypeForM3U8Segments) -{ - GF_Err e; - u32 i, count; - Double update_interval; - VariantPlaylist * pl = NULL; - Program *prog; - PlaylistElement *pe; - FILE *fmpd; - Bool is_end; - - e = parse_root_playlist(m3u8_file, &pl, base_url); - if (e) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M3U8] Failed to parse root playlist '%s', error = %s\n", m3u8_file, gf_error_to_string(e))); - if (pl) variant_playlist_del(pl); - pl = NULL; - return e; - } - if (mpd_file == NULL){ - gf_delete_file(m3u8_file); - mpd_file = m3u8_file; - } - is_end = !pl->playlistNeedsRefresh; - i=0; - assert( pl ); - assert( pl->programs ); - while ((prog = gf_list_enum(pl->programs, &i))) { - u32 j=0; - while (NULL != (pe = gf_list_enum(prog->bitrates, &j))) { - if (pe->url && strstr(pe->url, ".m3u8")) { - char *suburl = gf_url_concatenate(base_url, pe->url); - if (!strcmp(base_url, suburl)) { - gf_free(suburl); - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD Generator] Not downloading, programs are identical for %s...\n", pe->url)); - continue; - } - if (service) { - GF_DownloadSession *sess = gf_term_download_new(service, suburl, GF_NETIO_SESSION_NOT_THREADED, NULL, NULL); - if (!sess) { - gf_free(suburl); - break; - } - e = gf_dm_sess_process(sess); - if (e==GF_OK) { - e = parse_sub_playlist(gf_dm_sess_get_cache_name(sess), &pl, suburl, prog, pe); - } - gf_term_download_del(sess); - gf_free(suburl); - } else { /* for use in MP4Box */ - extern GF_Err gf_dm_wget(const char *url, const char *filename); - e = gf_dm_wget(suburl, "tmp.m3u8"); - if (e==GF_OK) { - e = parse_sub_playlist("tmp.m3u8", &pl, suburl, prog, pe); - } - gf_delete_file("tmp.m3u8"); - } - } - } - } - - update_interval = 0; - prog = gf_list_get(pl->programs, 0); - assert( prog ); - pe = gf_list_last(prog->bitrates); - assert( pe ); - /*update interval is set to the duration of the last media file with rules defined in http live streaming RFC section 6.3.4*/ - switch (reload_count) { - case 0: - update_interval = pe->durationInfo; - break; - case 1: - update_interval = pe->durationInfo/2; - break; - case 2: - update_interval = 3*(pe->durationInfo/2); - break; - default: - update_interval = 3*(pe->durationInfo); - break; - } - if (is_end || ((pe->elementType == TYPE_PLAYLIST) && pe->element.playlist.is_ended)) { - update_interval = 0; - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD Generator] NO NEED to refresh playlist !\n")); - } else { - GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD Generator] Playlist will be refreshed every %g seconds, len=%d\n", update_interval, pe->durationInfo)); - } - - assert( mpd_file ); - fmpd = gf_f64_open(mpd_file, "wt"); - if (!fmpd){ - GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD Generator] Cannot write to temp file %s!\n", mpd_file)); - variant_playlist_del(pl); - return GF_IO_ERR; - } - fprintf(fmpd, "<MPD type=\"Live\" xmlns=\"urn:mpeg:mpegB:schema:DASH:MPD:DIS2011\" profiles=\"urn:mpeg:mpegB:profile:dash:full:2011\""); - if (update_interval) fprintf(fmpd, " minimumUpdatePeriodMPD=\"PT%02.2gS\"", update_interval); - fprintf(fmpd, ">\n"); - - fprintf(fmpd, " <ProgramInformation moreInformationURL=\"http://gpac.sourceforge.net\">\n"); - { - char * title = pe->title; - if (!title || strlen(title) < 2) - title = pe->url; - fprintf(fmpd, " <Title>%s\n", title ); - } - fprintf(fmpd, " Generated from URL %s\n", base_url ); - fprintf(fmpd, " Generated by GPAC %s from %s\n", GPAC_FULL_VERSION, base_url); - - fprintf(fmpd, " \n"); - fprintf(fmpd, " \n"); - - count = gf_list_count(pl->programs); - for (i=0; iprograms, i); - count2 = gf_list_count(prog->bitrates); - for (j = 0; jbitrates, j); - if (pe->elementType == TYPE_PLAYLIST) { - u32 k, count3; - char *base_url = gf_strdup(pe->url); - char *sep = strrchr(base_url, '/'); - if (sep) *(sep+1) = 0; - if (pe->codecs && (pe->codecs[0] = '\"')) { - u32 len = strlen(pe->codecs); - strncpy(pe->codecs, pe->codecs+1, len-1); - pe->codecs[len-2] = 0; - } - /* SOUCHAY : if mime-type is still unknown, do not try to add codec information since it would be wrong */ - if (!strcmp(M3U8_UNKOWN_MIME_TYPE, mimeTypeForM3U8Segments)){ - fprintf(fmpd, " \n", mimeTypeForM3U8Segments, pe->bandwidth); - } else { - fprintf(fmpd, " \n", mimeTypeForM3U8Segments, (pe->codecs ? ";codecs=":""), (pe->codecs ? pe->codecs:""), pe->bandwidth); - } - fprintf(fmpd, "\n \n", pe->durationInfo, base_url); - count3 = gf_list_count(pe->element.playlist.elements); - update_interval = (count3 - 1) * pe->durationInfo * 1000; - for (k=0; kelement.playlist.elements, k); - while (base_url[cmp] == elt->url[cmp]) cmp++; - fprintf(fmpd, " \n", elt->url+cmp); - } - fprintf(fmpd, " \n"); - fprintf(fmpd, " \n"); - gf_free(base_url); - } else if (pe->elementType == TYPE_STREAM) { - fprintf(stdout, "NOT SUPPORTED: M3U8 Stream\n"); - } - } - } - fprintf(fmpd, " \n"); - fprintf(fmpd, ""); - fclose(fmpd); - variant_playlist_del(pl); - return GF_OK; -} - +/* +* GPAC - Multimedia Framework C SDK +* +* Authors: Cyril Concolato +* Copyright (c) Telecom ParisTech 2010- +* All rights reserved +* +* This file is part of GPAC / 3GPP/MPEG Media Presentation Description input module +* +* 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 +#include +#include +#include + +static u32 gf_mpd_parse_duration(char *duration) { + u32 i; + if (!duration) return 0; + i = 0; + while (1) { + if (duration[i] == ' ') i++; + else if (duration[i] == 0) return 0; + else { + break; + } + } + if (duration[i] == 'P') { + if (duration[i+1] == 0) return 0; + else if (duration[i+1] != 'T') return 0; + else { + char *sep1, *sep2; + u32 h, m; + double s; + h = m = 0; + s = 0; + if (NULL != (sep1 = strchr(duration+i+2, 'H'))) { + *sep1 = 0; + h = atoi(duration+i+2); + *sep1 = 'H'; + sep1++; + } else { + sep1 = duration+i+2; + } + if (NULL != (sep2 = strchr(sep1, 'M'))) { + *sep2 = 0; + m = atoi(sep1); + *sep2 = 'M'; + sep2++; + } else { + sep2 = sep1; + } + if (NULL != (sep1 = strchr(sep2, 'S'))) { + *sep1 = 0; + s = atof(sep2); + *sep1 = 'S'; + } + return (u32)((h*3600+m*60+s)*1000); + } + } else { + return 0; + } +} + +static GF_Err gf_mpd_parse_rep_cp(GF_XMLNode *root, GF_MPD_Representation *rep) +{ + u32 att_index; + GF_XMLAttribute *att; + att_index = 0; + while (1) { + att = gf_list_get(root->attributes, att_index); + if (!att) { + break; + } else if (!strcmp(att->name, "SchemeInformation")) { + rep->content_protection_type = gf_strdup(att->value); + } else if (!strcmp(att->name, "schemeIdUri")) { + rep->content_protection_uri = gf_strdup(att->value); + } + att_index++; + } + + return GF_OK; +} + +static GF_Err gf_mpd_parse_rep_trickmode(GF_XMLNode *root, GF_MPD_Representation *rep) +{ + u32 att_index; + GF_XMLAttribute *att; + att_index = 0; + while (1) { + att = gf_list_get(root->attributes, att_index); + if (!att) { + break; + } else if (!strcmp(att->name, "alternatePlayoutRate")) { + rep->alternatePlayoutRate = atof(att->value); + } + att_index++; + } + + return GF_OK; +} + +static GF_Err gf_mpd_parse_rep_initseg(GF_XMLNode *root, GF_MPD_Representation *rep, const char * baseURL) +{ + u32 att_index; + GF_XMLAttribute *att; + + att_index = 0; + while (1) { + att = gf_list_get(root->attributes, att_index); + if (!att) { + break; + } else if (!strcmp(att->name, "sourceURL")) { + GF_URL_Info info; + GF_Err e; + gf_dm_url_info_init(&info); + e = gf_dm_get_url_info(att->value, &info, baseURL); + assert( e == GF_OK ); + assert( info.canonicalRepresentation); + rep->init_url = gf_strdup(info.canonicalRepresentation); + gf_dm_url_info_del(&info); + } else if (!strcmp(att->name, "range")) { + rep->init_use_range = 1; + sscanf(att->value, "%d-%d", &rep->init_byterange_start, &rep->init_byterange_end); + } + att_index++; + } + return GF_OK; +} + +static GF_Err gf_mpd_parse_rep_urltemplate(GF_XMLNode *root, GF_MPD_Representation *rep) +{ + u32 att_index; + GF_XMLAttribute *att; + + att_index = 0; + while (1) { + att = gf_list_get(root->attributes, att_index); + if (!att) { + break; + } else if (!strcmp(att->name, "sourceURL")) { + rep->url_template = gf_strdup(att->value); + } else if (!strcmp(att->name, "id")) { + rep->id = gf_strdup(att->value); + } else if (!strcmp(att->name, "startIndex")) { + rep->startIndex = atoi(att->value)-1; + } else if (!strcmp(att->name, "endIndex")) { + rep->endIndex = atoi(att->value)-1; + } + att_index++; + } + return GF_OK; +} + +static GF_Err gf_mpd_parse_rep_urlelt(GF_XMLNode *root, GF_MPD_SegmentInfo *seg, const char * baseURL) +{ + u32 att_index; + GF_XMLAttribute *att; + + att_index = 0; + while (1) { + att = gf_list_get(root->attributes, att_index); + if (!att) { + break; + } else if (!strcmp(att->name, "sourceURL")) { + GF_URL_Info info; + GF_Err e; + gf_dm_url_info_init(&info); + e = gf_dm_get_url_info(att->value, &info, baseURL); + assert( e == GF_OK ); + assert( info.canonicalRepresentation); + seg->url = gf_strdup(info.canonicalRepresentation); + gf_dm_url_info_del(&info); + } else if (!strcmp(att->name, "range")) { + seg->use_byterange = 1; + sscanf(att->value, "%d-%d", &seg->byterange_start, &seg->byterange_end); + } + att_index++; + } + return GF_OK; +} + +static GF_Err gf_mpd_parse_rep_segmentinfo(GF_XMLNode *root, GF_MPD_Representation *rep) +{ + u32 att_index, child_index; + u32 nb_urlelements; + GF_XMLAttribute *att; + GF_XMLNode *child; + + att_index = 0; + while (1) { + att = gf_list_get(root->attributes, att_index); + if (!att) { + break; + } else if (!strcmp(att->name, "duration")) { + rep->default_segment_duration = gf_mpd_parse_duration(att->value); + } else if (!strcmp(att->name, "baseURL")) { + rep->default_base_url = gf_strdup(att->value); + } + att_index++; + } + + child_index = 0; + nb_urlelements = 0; + while (1) { + child = gf_list_get(root->content, child_index); + if (!child) { + break; + } else if (child->type == GF_XML_NODE_TYPE) { + if (!strcmp(child->name, "InitialisationSegmentURL")) { + gf_mpd_parse_rep_initseg(child, rep, rep->default_base_url); + } else if (!strcmp(child->name, "UrlTemplate")) { + gf_mpd_parse_rep_urltemplate(child, rep); + } else if (!strcmp(child->name, "Url")) { + nb_urlelements++; + } + } + child_index++; + } + + /* We assume that URL Template has precedence over URL elements */ + if (rep->url_template) { + /* TODO: expand the template to create segment urls*/ + } else if (nb_urlelements) { + u32 urlelt_index = 0; + assert( !rep->segments ); + rep->segments = gf_list_new(); + + child_index = 0; + while (1) { + child = gf_list_get(root->content, child_index); + if (!child) { + break; + } else if (child->type == GF_XML_NODE_TYPE) { + if (!strcmp(child->name, "Url")) { + GF_MPD_SegmentInfo *seg_info; + GF_SAFEALLOC(seg_info, GF_MPD_SegmentInfo); + if (!seg_info) return GF_OUT_OF_MEM; + seg_info->byterange_end = 0; + seg_info->byterange_start = 0; + seg_info->use_byterange = 0; + seg_info->url = NULL; + gf_mpd_parse_rep_urlelt(child, seg_info, rep->default_base_url); + gf_list_add(rep->segments, seg_info); + urlelt_index++; + } + } + child_index++; + } + } + return GF_OK; +} + +static GF_Err gf_mpd_parse_representation(GF_XMLNode *root, GF_MPD_Representation *rep) +{ + u32 att_index, child_index; + GF_XMLAttribute *att; + GF_XMLNode *child; + + att_index = 0; + while (1) { + att = gf_list_get(root->attributes, att_index); + if (!att) { + break; + } else if (!strcmp(att->name, "bandwidth")) { + rep->bandwidth = atoi(att->value); + } else if (!strcmp(att->name, "width")) { + rep->width = atoi(att->value); + } else if (!strcmp(att->name, "height")) { + rep->height = atoi(att->value); + } else if (!strcmp(att->name, "lang")) { + rep->lang = gf_strdup(att->value); + } else if (!strcmp(att->name, "mimeType")) { + rep->mime = gf_strdup(att->value); + } else if (!strcmp(att->name, "group")) { + rep->groupID = atoi(att->value); + } else if (!strcmp(att->name, "startWithRAP")) { + if (!strcmp(att->value, "true")) rep->startWithRap = 1; + } else if (!strcmp(att->name, "qualityRanking")) { + rep->qualityRanking = atoi(att->value); + } + att_index++; + } + + child_index = 0; + while (1) { + child = gf_list_get(root->content, child_index); + if (!child) { + break; + } else if (child->type == GF_XML_NODE_TYPE) { + if (!strcmp(child->name, "ContentProtection")) { + gf_mpd_parse_rep_cp(child, rep); + } else if (!strcmp(child->name, "TrickMode")) { + gf_mpd_parse_rep_trickmode(child, rep); + } else if (!strcmp(child->name, "SegmentInfo")) { + gf_mpd_parse_rep_segmentinfo(child, rep); + } + } + child_index++; + } + return GF_OK; +} + +static GF_Err gf_mpd_parse_segment_info_default(GF_XMLNode *root, GF_MPD_Period *period) +{ + u32 att_index; + GF_XMLAttribute *att; + + att_index = 0; + while (1) { + att = gf_list_get(root->attributes, att_index); + if (!att) { + break; + } else if (!strcmp(att->name, "duration")) { + period->default_segment_duration = gf_mpd_parse_duration(att->value); + } else if (!strcmp(att->name, "baseURL")) { + period->default_base_url = gf_strdup(att->value); + } else if (!strcmp(att->name, "sourceUrlTemplatePeriod")) { + period->url_template = gf_strdup(att->value); + } + att_index++; + } + + return GF_OK; +} + +static GF_Err gf_mpd_parse_period(GF_XMLNode *root, GF_MPD_Period *period, const char *default_base_url) +{ + u32 att_index, child_index; + GF_XMLAttribute *att; + GF_XMLNode *child; + + att_index = 0; + while (1) { + att = gf_list_get(root->attributes, att_index); + if (!att) { + break; + } else if (!strcmp(att->name, "start")) { + } else if (!strcmp(att->name, "segmentAlignmentFlag")) { + if (!strcmp(att->value, "true")) { + period->segment_alignment_flag = 1; + } + } else if (!strcmp(att->name, "bitstreamSwitchingFlag")) { + if (!strcmp(att->value, "true")) { + period->segment_alignment_flag = 1; + } + } + att_index++; + } + + child_index = 0; + while (1) { + child = gf_list_get(root->content, child_index); + if (!child) { + break; + } else if (child->type == GF_XML_NODE_TYPE) { + if (!strcmp(child->name, "SegmentInfoDefault")) { + gf_mpd_parse_segment_info_default(child, period); + } else if (!strcmp(child->name, "Representation")) { + GF_MPD_Representation *rep; + GF_SAFEALLOC(rep, GF_MPD_Representation); + if (!rep) + return GF_OUT_OF_MEM; + if (default_base_url) { + rep->default_base_url = gf_strdup(default_base_url); + } + gf_mpd_parse_representation(child, rep); + gf_list_add(period->representations, rep); + } + } + child_index++; + } + + return GF_OK; +} + +static GF_Err gf_mpd_parse_program_info(GF_XMLNode *root, GF_MPD *mpd) +{ + u32 att_index, child_index; + GF_XMLAttribute *att; + GF_XMLNode *child; + + att_index = 0; + while (1) { + att = gf_list_get(root->attributes, att_index); + if (!att) { + break; + } else if (!strcmp(att->name, "moreInformationURL")) { + mpd->more_info_url = gf_strdup(att->value); + } + att_index++; + } + + child_index = 0; + while (1) { + child = gf_list_get(root->content, child_index); + if (!child) { + break; + } else if (child->type == GF_XML_NODE_TYPE) { + if (!strcmp(child->name, "Title")) { + GF_XMLNode *data_node = gf_list_get(child->content, 0); + if (data_node && data_node->type == GF_XML_TEXT_TYPE) { + mpd->title = gf_strdup(data_node->name); + } + } else if (!strcmp(child->name, "Source")) { + GF_XMLNode *data_node = gf_list_get(child->content, 0); + if (data_node && data_node->type == GF_XML_TEXT_TYPE) { + mpd->source = gf_strdup(data_node->name); + } + } else if (!strcmp(child->name, "Copyright")) { + GF_XMLNode *data_node = gf_list_get(child->content, 0); + if (data_node && data_node->type == GF_XML_TEXT_TYPE) { + mpd->copyright = gf_strdup(data_node->name); + } + } + } + child_index++; + } + return GF_OK; +} + +GF_MPD *gf_mpd_new() +{ + GF_MPD *mpd; + GF_SAFEALLOC(mpd, GF_MPD); + return mpd; +} + +void gf_mpd_del(GF_MPD *mpd) +{ + while (gf_list_count(mpd->periods)) { + GF_MPD_Period *period = gf_list_get(mpd->periods, 0); + gf_list_rem(mpd->periods, 0); + while (gf_list_count(period->representations)) { + GF_MPD_Representation *rep = gf_list_get(period->representations, 0); + gf_list_rem(period->representations, 0); + + while (gf_list_count(rep->segments)) { + GF_MPD_SegmentInfo *seg = gf_list_get(rep->segments, 0); + gf_list_rem(rep->segments, 0); + if (seg->url) gf_free(seg->url); + gf_free(seg); + } + if (rep->content_protection_type) gf_free(rep->content_protection_type); + rep->content_protection_type = NULL; + if (rep->content_protection_uri) gf_free(rep->content_protection_uri); + rep->content_protection_uri = NULL; + if (rep->default_base_url) gf_free(rep->default_base_url); + rep->default_base_url = NULL; + if (rep->id) gf_free(rep->id); + rep->id = NULL; + if (rep->init_url) gf_free(rep->init_url); + rep->init_url = NULL; + if (rep->lang) gf_free(rep->lang); + rep->lang = NULL; + if (rep->mime) gf_free(rep->mime); + rep->mime = NULL; + if (rep->url_template) gf_free(rep->url_template); + rep->url_template = NULL; + if (rep->segments) gf_list_del(rep->segments); + rep->segments = NULL; + gf_free(rep); + } + gf_list_del(period->representations); + period->representations = NULL; + if (period->default_base_url) gf_free(period->default_base_url); + if (period->url_template) gf_free(period->url_template); + + gf_free(period); + } + gf_list_del(mpd->periods); + mpd->periods = NULL; + if (mpd->base_url) gf_free(mpd->base_url); + mpd->base_url = NULL; + if (mpd->title) gf_free(mpd->title); + mpd->title = NULL; + if (mpd->source) gf_free(mpd->source); + mpd->source = NULL; + if (mpd->copyright) gf_free(mpd->copyright); + mpd->copyright = NULL; + if (mpd->more_info_url) gf_free(mpd->more_info_url); + mpd->more_info_url = NULL; + gf_free(mpd); +} + +GF_Err gf_mpd_init_from_dom(GF_XMLNode *root, GF_MPD *mpd, const char *default_base_url) +{ + u32 att_index, child_index; + GF_XMLAttribute *att; + GF_XMLNode *child; + + if (!root || !mpd) return GF_BAD_PARAM; + + assert( !mpd->periods ); + mpd->periods = gf_list_new(); + + att_index = 0; + child_index = gf_list_count(root->attributes); + for (att_index = 0 ; att_index < child_index; att_index++) { + att = gf_list_get(root->attributes, att_index); + if (!att) { + continue; + } else if (!strcmp(att->name, "type")) { + if (!strcmp(att->value, "OnDemand")) mpd->type = GF_MPD_TYPE_ON_DEMAND; + else if (!strcmp(att->value, "Live")) mpd->type = GF_MPD_TYPE_LIVE; + } else if (!strcmp(att->name, "availabilityStartTime")) { + } else if (!strcmp(att->name, "availabilityEndTime")) { + } else if (!strcmp(att->name, "mediaPresentationDuration")) { + mpd->duration = gf_mpd_parse_duration(att->value); + } else if (!strcmp(att->name, "minimumUpdatePeriodMPD")) { + mpd->min_update_time = gf_mpd_parse_duration(att->value); + } else if (!strcmp(att->name, "minBufferTime")) { + mpd->min_buffer_time = gf_mpd_parse_duration(att->value); + } else if (!strcmp(att->name, "timeShiftBufferDepth")) { + mpd->time_shift_buffer_depth = gf_mpd_parse_duration(att->value); + } else if (!strcmp(att->name, "baseURL")) { + } + } + + child_index = 0; + while (1) { + child = gf_list_get(root->content, child_index); + if (!child) { + break; + } else if (child->type == GF_XML_NODE_TYPE) { + if (!strcmp(child->name, "ProgramInformation")) { + gf_mpd_parse_program_info(child, mpd); + } else if (!strcmp(child->name, "Period")) { + GF_MPD_Period *period; + GF_SAFEALLOC(period, GF_MPD_Period); + if (!period) + return GF_OUT_OF_MEM; + period->representations = gf_list_new(); + gf_mpd_parse_period(child, period, default_base_url); + gf_list_add(mpd->periods, period); + } + } + child_index++; + } + return GF_OK; +} + +GF_Err gf_m3u8_to_mpd(GF_ClientService *service, const char *m3u8_file, const char *base_url, + const char *mpd_file, + u32 reload_count, char *mimeTypeForM3U8Segments) +{ + GF_Err e; + u32 i, count; + Double update_interval; + VariantPlaylist * pl = NULL; + Program *prog; + PlaylistElement *pe, *the_pe; + FILE *fmpd; + Bool is_end; + + e = parse_root_playlist(m3u8_file, &pl, base_url); + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M3U8] Failed to parse root playlist '%s', error = %s\n", m3u8_file, gf_error_to_string(e))); + if (pl) variant_playlist_del(pl); + pl = NULL; + return e; + } + if (mpd_file == NULL){ + gf_delete_file(m3u8_file); + mpd_file = m3u8_file; + } + the_pe = NULL; + is_end = !pl->playlistNeedsRefresh; + i=0; + assert( pl ); + assert( pl->programs ); + while ((prog = gf_list_enum(pl->programs, &i))) { + u32 j=0; + while (NULL != (pe = gf_list_enum(prog->bitrates, &j))) { + Bool found = 0; + u32 k; + char *suburl; + + if (!pe->url || !strstr(pe->url, ".m3u8")) + continue; + + /*filter out duplicated entries (seen on M6 m3u8)*/ + for (k=0; kbitrates, k); + if (a_pe->url && pe->url && !strcmp(a_pe->url, pe->url)) { + found = 1; + break; + } + } + if (found) continue; + + the_pe = pe; + suburl = gf_url_concatenate(base_url, pe->url); + if (!strcmp(base_url, suburl)) { + gf_free(suburl); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD Generator] Not downloading, programs are identical for %s...\n", pe->url)); + continue; + } + if (service) { + GF_DownloadSession *sess = gf_term_download_new(service, suburl, GF_NETIO_SESSION_NOT_THREADED, NULL, NULL); + if (!sess) { + gf_free(suburl); + break; + } + e = gf_dm_sess_process(sess); + if (e==GF_OK) { + e = parse_sub_playlist(gf_dm_sess_get_cache_name(sess), &pl, suburl, prog, pe); + } + gf_term_download_del(sess); + gf_free(suburl); + } else { /* for use in MP4Box */ + extern GF_Err gf_dm_wget(const char *url, const char *filename); + e = gf_dm_wget(suburl, "tmp.m3u8"); + if (e==GF_OK) { + e = parse_sub_playlist("tmp.m3u8", &pl, suburl, prog, pe); + } + gf_delete_file("tmp.m3u8"); + } + } + } + + assert(the_pe); + + update_interval = 0; + /*update interval is set to the duration of the last media file with rules defined in http live streaming RFC section 6.3.4*/ + switch (reload_count) { + case 0: + update_interval = the_pe->durationInfo; + break; + case 1: + update_interval = the_pe->durationInfo/2; + break; + case 2: + update_interval = 3*(the_pe->durationInfo/2); + break; + default: + update_interval = 3*(the_pe->durationInfo); + break; + } + if (is_end || ((the_pe->elementType == TYPE_PLAYLIST) && the_pe->element.playlist.is_ended)) { + update_interval = 0; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD Generator] NO NEED to refresh playlist !\n")); + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[MPD Generator] Playlist will be refreshed every %g seconds, len=%d\n", update_interval, the_pe->durationInfo)); + } + + assert( mpd_file ); + fmpd = gf_f64_open(mpd_file, "wt"); + if (!fmpd){ + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[MPD Generator] Cannot write to temp file %s!\n", mpd_file)); + variant_playlist_del(pl); + return GF_IO_ERR; + } + fprintf(fmpd, "\n"); + + fprintf(fmpd, " \n"); + { + char * title = the_pe->title; + if (!title || strlen(title) < 2) + title = the_pe->url; + fprintf(fmpd, " %s\n", title ); + } + fprintf(fmpd, " Generated from URL %s\n", base_url ); + fprintf(fmpd, " Generated by GPAC %s from %s\n", GPAC_FULL_VERSION, base_url); + + fprintf(fmpd, " \n"); + fprintf(fmpd, " \n"); + + count = gf_list_count(pl->programs); + for (i=0; iprograms, i); + count2 = gf_list_count(prog->bitrates); + for (j = 0; jbitrates, j); + if (pe->elementType == TYPE_PLAYLIST) { + u32 k, count3; + char *base_url = gf_strdup(pe->url); + char *sep = strrchr(base_url, '/'); + if (sep) *(sep+1) = 0; + if (pe->codecs && (pe->codecs[0] = '\"')) { + u32 len = strlen(pe->codecs); + strncpy(pe->codecs, pe->codecs+1, len-1); + pe->codecs[len-2] = 0; + } + /* SOUCHAY : if mime-type is still unknown, do not try to add codec information since it would be wrong */ + if (!strcmp(M3U8_UNKOWN_MIME_TYPE, mimeTypeForM3U8Segments)){ + fprintf(fmpd, " \n", mimeTypeForM3U8Segments, pe->bandwidth); + } else { + fprintf(fmpd, " \n", mimeTypeForM3U8Segments, (pe->codecs ? ";codecs=":""), (pe->codecs ? pe->codecs:""), pe->bandwidth); + } + fprintf(fmpd, "\n \n", pe->durationInfo, base_url); + count3 = gf_list_count(pe->element.playlist.elements); + update_interval = (count3 - 1) * pe->durationInfo * 1000; + for (k=0; kelement.playlist.elements, k); + + /*remove protocol scheme and try to find the common part in baseURL and segment URL - this avoids copying the entire url*/ + src_url = strstr(base_url, "://"); + if (src_url) src_url += 3; + else src_url = base_url; + + seg_url = strstr(elt->url, "://"); + if (seg_url) seg_url += 3; + else seg_url = elt->url; + + while (src_url[cmp] == seg_url[cmp]) cmp++; + fprintf(fmpd, " \n", cmp ? (seg_url + cmp) : elt->url); + } + fprintf(fmpd, " \n"); + fprintf(fmpd, " \n"); + gf_free(base_url); + } else if (pe->elementType == TYPE_STREAM) { + fprintf(stdout, "NOT SUPPORTED: M3U8 Stream\n"); + } + } + } + fprintf(fmpd, " \n"); + fprintf(fmpd, ""); + fclose(fmpd); + variant_playlist_del(pl); + return GF_OK; +} + diff --git a/src/media_tools/mpegts.c b/src/media_tools/mpegts.c index 8557eff..eb052cd 100644 --- a/src/media_tools/mpegts.c +++ b/src/media_tools/mpegts.c @@ -24,12 +24,17 @@ #include +#include + + #ifndef GPAC_DISABLE_MPEG2TS #include #include #include #include +#include +#include #define DUMP_MPE_IP_DATAGRAMS //#define FORCE_DISABLE_MPEG4SL_OVER_MPEG2TS @@ -64,7 +69,7 @@ const char *gf_m2ts_get_stream_name(u32 streamType) } } -static void gf_m2ts_reframe_default(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u64 PTS, unsigned char *data, u32 data_len) +static u32 gf_m2ts_reframe_default(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u64 PTS, unsigned char *data, u32 data_len) { GF_M2TS_PES_PCK pck; pck.flags = 0; @@ -84,9 +89,11 @@ static void gf_m2ts_reframe_default(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 D pck.data_len = data_len; pck.stream = pes; ts->on_event(ts, GF_M2TS_EVT_PES_PCK, &pck); + /*we consumed all data*/ + return 0; } -static void gf_m2ts_reframe_avc_h264(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u64 PTS, unsigned char *data, u32 data_len) +static u32 gf_m2ts_reframe_avc_h264(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u64 PTS, unsigned char *data, u32 data_len) { Bool force_new_au=0; Bool start_code_found = 0; @@ -114,6 +121,9 @@ static void gf_m2ts_reframe_avc_h264(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 unsigned char *start = (unsigned char *)memchr(data+sc_pos, 0, data_len-sc_pos); if (!start) break; sc_pos = start - data; + /*not enough space to test for start code, don't check it*/ + if (data_len - sc_pos < 5) + break; /*0x00000001 start code*/ if (!start[1] && !start[2] && (start[3]==1)) { @@ -201,7 +211,14 @@ static void gf_m2ts_reframe_avc_h264(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 } } } - if (data_len && start_code_found) { + /*we did not consume all data*/ + if (!start_code_found) { + /*if not enough data to locate start code, store it*/ + if (data_len<5) return data_len; + /*otherwise this is the middle of a frame, let's dispatch it*/ + } + + if (data_len) { pck.flags = 0; pck.data = data; pck.data_len = data_len; @@ -222,12 +239,13 @@ static void gf_m2ts_reframe_avc_h264(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 pck.flags |= GF_M2TS_PES_PCK_AU_START; force_new_au = 0; } - ts->on_event(ts, GF_M2TS_EVT_PES_PCK, &pck); } + /*we consumed all data*/ + return 0; } -void gf_m2ts_reframe_mpeg_video(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u64 PTS, unsigned char *data, u32 data_len) +static u32 gf_m2ts_reframe_mpeg_video(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u64 PTS, unsigned char *data, u32 data_len) { u32 sc_pos = 0; u32 to_send = data_len; @@ -308,6 +326,8 @@ void gf_m2ts_reframe_mpeg_video(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, pck.data = data; pck.data_len = data_len; ts->on_event(ts, GF_M2TS_EVT_PES_PCK, &pck); + /*we consumed all data*/ + return 0; } #ifndef GPAC_DISABLE_AV_PARSERS @@ -330,12 +350,14 @@ typedef struct u32 profile, sr_idx, nb_ch, frame_size; } ADTSHeader; -static void gf_m2ts_reframe_aac_adts(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u64 PTS, unsigned char *data, u32 data_len) +static u32 gf_m2ts_reframe_aac_adts(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u64 PTS, unsigned char *data, u32 data_len) { ADTSHeader hdr; u32 sc_pos = 0; u32 start = 0; u32 hdr_size = 0; + Bool first = 1; + u32 remain; GF_M2TS_PES_PCK pck; if (PTS) { @@ -348,7 +370,10 @@ static void gf_m2ts_reframe_aac_adts(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 pck.DTS = pes->DTS; pck.PTS = pes->PTS; pck.flags = 0; + remain = pes->frame_state; + pes->frame_state = 0; + /*fixme - we need to test this with more ADTS sources were PES framing is on any boundaries*/ while (sc_pos+2on_event(ts, GF_M2TS_EVT_PES_PCK, &pck); + remain = 0; } bs = gf_bs_new(data + sc_pos + 1, 9, GF_BITSTREAM_READ); @@ -388,13 +415,24 @@ static void gf_m2ts_reframe_aac_adts(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 gf_bs_del(bs); + /*make sure we are sync if we have more data following*/ + if (sc_pos + hdr.frame_size < data_len) { + if ((data[sc_pos + hdr.frame_size]!=0xFF) || ((data[sc_pos+hdr.frame_size+1] & 0xF0) != 0xF0)) { + sc_pos++; + continue; + } + } else if (first && (hdr.frame_size + sc_pos > data_len)) { + sc_pos++; + continue; + } + if (pes->aud_sr != GF_M4ASampleRates[hdr.sr_idx]) { GF_M4ADecSpecInfo cfg; pck.stream = pes; memset(&cfg, 0, sizeof(GF_M4ADecSpecInfo)); cfg.base_object_type = hdr.profile; - cfg.base_sr = GF_M4ASampleRates[hdr.sr_idx]; - cfg.nb_chan = hdr.nb_ch; + pes->aud_sr = cfg.base_sr = GF_M4ASampleRates[hdr.sr_idx]; + pes->aud_nb_ch = cfg.nb_chan = hdr.nb_ch; cfg.sbr_object_type = 0; gf_m4a_write_config(&cfg, &pck.data, &pck.data_len); ts->on_event(ts, GF_M2TS_EVT_AAC_CFG, &pck); @@ -411,18 +449,28 @@ static void gf_m2ts_reframe_aac_adts(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 pck.data = data + sc_pos + hdr_size; pck.data_len = hdr.frame_size - hdr_size; + if (pck.data_len > data_len - sc_pos - hdr_size) { + /*remember how much we have to send*/ + pes->frame_state = pck.data_len - (data_len - sc_pos - hdr_size); + pck.data_len = data_len - sc_pos - hdr_size; + } + ts->on_event(ts, GF_M2TS_EVT_PES_PCK, &pck); - sc_pos += hdr.frame_size; + sc_pos += pck.data_len + hdr_size; start = sc_pos; + /*update PTS in case we don't get any update*/ if (pes->aud_sr) { size = 1024*90000/pes->aud_sr; pes->PTS += size; } + first = 0; } + /*we consumed all data*/ + return 0; } -static void gf_m2ts_reframe_aac_latm(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u64 PTS, unsigned char *data, u32 data_len) +static u32 gf_m2ts_reframe_aac_latm(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u64 PTS, unsigned char *data, u32 data_len) { u32 sc_pos = 0; u32 start = 0; @@ -439,6 +487,7 @@ static void gf_m2ts_reframe_aac_latm(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 pck.PTS = pes->PTS; pck.flags = 0; + /*fixme - we need to test this with more LATM sources were PES framing is on any boundaries*/ while (sc_pos+2aud_sr) { pck.stream = pes; + pes->aud_sr = cfg.base_sr; + pes->aud_nb_ch = cfg.nb_chan; gf_m4a_write_config(&cfg, &pck.data, &pck.data_len); ts->on_event(ts, GF_M2TS_EVT_AAC_CFG, &pck); gf_free(pck.data); - pes->aud_sr = cfg.base_sr; - pes->aud_nb_ch = cfg.nb_chan; } } frameLengthType = gf_bs_read_int(bs, 3); @@ -556,12 +605,14 @@ static void gf_m2ts_reframe_aac_latm(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 start = sc_pos; } + /*we consumed all data*/ + return 0; } #endif #ifndef GPAC_DISABLE_AV_PARSERS -static void gf_m2ts_reframe_mpeg_audio(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u64 PTS, unsigned char *data, u32 data_len) +static u32 gf_m2ts_reframe_mpeg_audio(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u64 PTS, unsigned char *data, u32 data_len) { GF_M2TS_PES_PCK pck; u32 pos, frame_size, remain; @@ -570,41 +621,34 @@ static void gf_m2ts_reframe_mpeg_audio(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u6 pck.stream = pes; remain = pes->frame_state; + if (remain) { + /*dispatch end of prev frame*/ + pck.DTS = pck.PTS = pes->PTS; + pck.data = data; + pck.data_len = (remain>data_len) ? data_len : remain; + ts->on_event(ts, GF_M2TS_EVT_PES_PCK, &pck); + if (remain>data_len) { + pes->frame_state = remain - data_len; + /*we consumed all data*/ + return 0; + } + data += remain; + data_len -= remain; + remain=0; + } + pes->frame_state = gf_mp3_get_next_header_mem(data, data_len, &pos); if (!pes->frame_state) { - if (remain) { - /*dispatch end of prev frame*/ - pck.DTS = pck.PTS = pes->PTS; - pck.data = data; - pck.data_len = (remain>data_len) ? data_len : remain; - ts->on_event(ts, GF_M2TS_EVT_PES_PCK, &pck); - if (remain>data_len) pes->frame_state = remain - data_len; - } - return; + /*we did not consumed all data*/ + return data_len; } assert((pes->frame_state & 0xffe00000) == 0xffe00000); - /*resync*/ - if (pos) { - if (remain) { - /*sync error!!*/ - if (remain>pos) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] sync error - start code @ %d - remaining from last frame %d\n", pos, remain) ); - remain = pos; - } - /*dispatch end of prev frame*/ - pck.DTS = pck.PTS = pes->PTS; - pck.data = data; - pck.data_len = remain; - ts->on_event(ts, GF_M2TS_EVT_PES_PCK, &pck); - } - data += pos; - data_len -= pos; - } + if (!pes->PTS) { pes->aud_sr = gf_mp3_sampling_rate(pes->frame_state); pes->aud_nb_ch = gf_mp3_num_channels(pes->frame_state); } - /*we may get a PTS for aither the previous or the current frame*/ + /*we may get a PTS for either the previous or the current frame*/ if (PTS>=pes->PTS) pes->PTS = PTS; pck.flags = GF_M2TS_PES_PCK_RAP | GF_M2TS_PES_PCK_AU_START; @@ -624,8 +668,8 @@ static void gf_m2ts_reframe_mpeg_audio(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u6 pes->frame_state = gf_mp3_get_next_header_mem(data, data_len, &pos); /*resync (ID3 or error)*/ if (!pes->frame_state) { - data_len = 0; - break; + /*we did not consumed all data*/ + return data_len; } /*resync (ID3 or error)*/ if (pos) { @@ -645,6 +689,8 @@ static void gf_m2ts_reframe_mpeg_audio(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u6 } else { pes->frame_state = 0; } + /*we consumed all data*/ + return 0; } #endif /*GPAC_DISABLE_AV_PARSERS*/ @@ -732,6 +778,7 @@ void gf_m2ts_es_del(GF_M2TS_ES *es) } else if (es->pid!=es->program->pmt_pid) { GF_M2TS_PES *pes = (GF_M2TS_PES *)es; if (pes->data) gf_free(pes->data); + if (pes->prev_data) gf_free(pes->prev_data); if (pes->buf) gf_free(pes->buf); } if (es->slcfg) gf_free(es->slcfg); @@ -752,14 +799,19 @@ static void gf_m2ts_reset_sdt(GF_M2TS_Demuxer *ts) static void gf_m2ts_section_complete(GF_M2TS_Demuxer *ts, GF_M2TS_SectionFilter *sec, GF_M2TS_SECTION_ES *ses) { if (!sec->process_section) { - if (ts->on_mpe_event && ((ses && (ses->flags & GF_M2TS_EVT_DVB_MPE)) || (sec->section[0]==GF_M2TS_TABLE_ID_INT)) ) { + if ((ts->on_event && (sec->section[0]==GF_M2TS_TABLE_ID_AIT)) ) { + GF_M2TS_SL_PCK pck; + pck.data_len = sec->length; + pck.data = sec->section; + pck.stream = (GF_M2TS_ES *)ses; + ts->on_event(ts, GF_M2TS_EVT_AIT_FOUND, &pck); + } else if (ts->on_mpe_event && ((ses && (ses->flags & GF_M2TS_EVT_DVB_MPE)) || (sec->section[0]==GF_M2TS_TABLE_ID_INT)) ) { GF_M2TS_SL_PCK pck; pck.data_len = sec->length; pck.data = sec->section; pck.stream = (GF_M2TS_ES *)ses; ts->on_mpe_event(ts, GF_M2TS_EVT_DVB_MPE, &pck); - } - else if (ts->on_event) { + } else if (ts->on_event) { GF_M2TS_SL_PCK pck; pck.data_len = sec->length; pck.data = sec->section; @@ -782,12 +834,22 @@ static void gf_m2ts_section_complete(GF_M2TS_Demuxer *ts, GF_M2TS_SectionFilter /*look for proper table*/ table_id = data[0]; - if ((table_id == GF_M2TS_TABLE_ID_PAT || table_id == GF_M2TS_TABLE_ID_SDT_ACTUAL || table_id == GF_M2TS_TABLE_ID_PMT || table_id == GF_M2TS_TABLE_ID_NIT_ACTUAL) && ts->on_event) { - GF_M2TS_SL_PCK pck; - pck.data_len = sec->length; - pck.data = sec->section; - pck.stream = (GF_M2TS_ES *)ses; - ts->on_event(ts, GF_M2TS_EVT_DVB_GENERAL, &pck); + if (ts->on_event) { + switch (table_id) { + case GF_M2TS_TABLE_ID_PAT: + case GF_M2TS_TABLE_ID_SDT_ACTUAL: + case GF_M2TS_TABLE_ID_PMT: + case GF_M2TS_TABLE_ID_NIT_ACTUAL: + case GF_M2TS_TABLE_ID_TDT: + case GF_M2TS_TABLE_ID_TOT: + { + GF_M2TS_SL_PCK pck; + pck.data_len = sec->length; + pck.data = sec->section; + pck.stream = (GF_M2TS_ES *)ses; + ts->on_event(ts, GF_M2TS_EVT_DVB_GENERAL, &pck); + } + } } has_syntax_indicator = (data[1] & 0x80) ? 1 : 0; @@ -919,6 +981,7 @@ static Bool gf_m2ts_is_long_section(u8 table_id) switch (table_id) { case GF_M2TS_TABLE_ID_MPEG4_BIFS: case GF_M2TS_TABLE_ID_MPEG4_OD: + case GF_M2TS_TABLE_ID_INT: case GF_M2TS_TABLE_ID_EIT_ACTUAL_PF: case GF_M2TS_TABLE_ID_EIT_OTHER_PF: case GF_M2TS_TABLE_ID_ST: @@ -1064,7 +1127,7 @@ static void gf_m2ts_process_sdt(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *ses, GF nb_sections = gf_list_count(sections); if (nb_sections > 1) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("SDT on multiple sections not supported\n")); + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] SDT on multiple sections not supported\n")); } section = (GF_M2TS_Section *)gf_list_get(sections, 0); @@ -1156,13 +1219,125 @@ static void gf_m2ts_process_mpeg4section(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES static void gf_m2ts_process_nit(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *nit_es, GF_List *sections, u8 table_id, u16 ex_table_id, u8 version_number, u8 last_section_number, u32 status) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] NIT table processing (not yet implemented)")); +} + +extern void dvb_decode_mjd_date(u32 date, u16 *year, u8 *month, u8 *day); +static void gf_m2ts_process_tdt_tot(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *tdt_tot_es, GF_List *sections, u8 table_id, u16 ex_table_id, u8 version_number, u8 last_section_number, u32 status) +{ + unsigned char *data; + u32 data_size, nb_sections; + GF_M2TS_Section *section; + GF_M2TS_TDT_TOT *time_table; + const char *table_name; + + /*wait for the last section */ + if ( !(status & GF_M2TS_TABLE_END) ) + return; + + switch (table_id) { + case GF_M2TS_TABLE_ID_TDT: + table_name = "TDT"; + break; + case GF_M2TS_TABLE_ID_TOT: + table_name = "TOT"; + break; + default: + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] Unimplemented table_id %u for PID %u\n", table_id, GF_M2TS_PID_TDT_TOT_ST)); + return; + } + + nb_sections = gf_list_count(sections); + if (nb_sections > 1) { + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] %s on multiple sections not supported\n", table_name)); + } + + section = (GF_M2TS_Section *)gf_list_get(sections, 0); + data = section->data; + data_size = section->data_size; + /*TOT only contains 40 bits of UTC_time; TDT add descriptors and a CRC*/ + assert(table_id!=GF_M2TS_TABLE_ID_TDT || data_size == 5); /**/ + GF_SAFEALLOC(time_table, GF_M2TS_TDT_TOT); + /*UTC_time - see annex C of DVB-SI ETSI EN 300468*/ + dvb_decode_mjd_date(data[0]*256 + data[1], &(time_table->year), &(time_table->month), &(time_table->day)); + time_table->hour = 10*((data[2]&0xf0)>>4) + (data[2]&0x0f); + time_table->minute = 10*((data[3]&0xf0)>>4) + (data[3]&0x0f); + time_table->second = 10*((data[4]&0xf0)>>4) + (data[4]&0x0f); + assert(time_table->hour<24 && time_table->minute<60 && time_table->second<60); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] Stream UTC time is %u/%02u/%02u %02u:%02u:%02u\n", time_table->year, time_table->month, time_table->day, time_table->hour, time_table->minute, time_table->second)); + + switch (table_id) { + case GF_M2TS_TABLE_ID_TDT: + if (ts->TDT_time) gf_free(ts->TDT_time); + ts->TDT_time = time_table; + if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_TDT, time_table); + break; + case GF_M2TS_TABLE_ID_TOT: +#if 0 + { + u32 pos, loop_len; + loop_len = ((data[5]&0x0f) << 8) | (data[6] & 0xff); + data += 7; + pos = 0; + while (pos < loop_len) { + u8 tag = data[pos]; + pos += 2; + if (tag == GF_M2TS_DVB_LOCAL_TIME_OFFSET_DESCRIPTOR) { + char tmp_time[10]; + u16 offset_hours, offset_minutes; + now->country_code[0] = data[pos]; + now->country_code[1] = data[pos+1]; + now->country_code[2] = data[pos+2]; + now->country_region_id = data[pos+3]>>2; + + sprintf(tmp_time, "%02x", data[pos+4]); + offset_hours = atoi(tmp_time); + sprintf(tmp_time, "%02x", data[pos+5]); + offset_minutes = atoi(tmp_time); + now->local_time_offset_seconds = (offset_hours * 60 + offset_minutes) * 60; + if (data[pos+3] & 1) now->local_time_offset_seconds *= -1; + + dvb_decode_mjd_to_unix_time(data+pos+6, &now->unix_next_toc); + + sprintf(tmp_time, "%02x", data[pos+11]); + offset_hours = atoi(tmp_time); + sprintf(tmp_time, "%02x", data[pos+12]); + offset_minutes = atoi(tmp_time); + now->next_time_offset_seconds = (offset_hours * 60 + offset_minutes) * 60; + if (data[pos+3] & 1) now->next_time_offset_seconds *= -1; + pos+= 13; + } + } + /*TODO: check lengths are ok*/ + if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_TOT, time_table); + } +#endif + /*check CRC32*/ + if (!gf_m2ts_crc32_check(ts->tdt_tot->section, ts->tdt_tot->length-4)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] corrupted %s table (CRC32 failed)\n", table_name)); + goto error_exit; + } + if (ts->TDT_time) gf_free(ts->TDT_time); + ts->TDT_time = time_table; + if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_TOT, time_table); + break; + default: + assert(0); + goto error_exit; + } + + return; /*success*/ + +error_exit: + gf_free(time_table); + return; } static void gf_m2ts_process_pmt(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *pmt, GF_List *sections, u8 table_id, u16 ex_table_id, u8 version_number, u8 last_section_number, u32 status) { - u32 info_length, pos, desc_len, evt_type, nb_es; + u32 info_length, pos, desc_len, evt_type, nb_es,i; u32 nb_sections; u32 data_size; unsigned char *data; @@ -1210,6 +1385,8 @@ static void gf_m2ts_process_pmt(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *pmt, GF iod_bs = gf_bs_new(data+8, len-2, GF_BITSTREAM_READ); if (pmt->program->pmt_iod) gf_odf_desc_del((GF_Descriptor *)pmt->program->pmt_iod); gf_odf_parse_descriptor(iod_bs , (GF_Descriptor **) &pmt->program->pmt_iod, &size); + /*remember program number for service/program selection*/ + if (pmt->program->pmt_iod) pmt->program->pmt_iod->ServiceID = pmt->program->number; gf_bs_del(iod_bs ); } else { #else @@ -1224,6 +1401,16 @@ static void gf_m2ts_process_pmt(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *pmt, GF data += 4 + info_length; data_size -= 4 + info_length; pos = 0; + + /* count de number of program related PMT received */ + for(i=0;iprograms);i++){ + GF_M2TS_Program *prog = (GF_M2TS_Program *)gf_list_get(ts->programs,i); + if(prog->pmt_pid == pmt->pid){ + ts->nb_prog_pmt_received++; + break; + } + } + while (posprogram->number); + ses = (GF_M2TS_SECTION_ES *)es; + ses->sec = gf_m2ts_section_filter_new(NULL, 0); + break; + case GF_M2TS_13818_6_ANNEX_D: GF_SAFEALLOC(ses, GF_M2TS_SECTION_ES); es = (GF_M2TS_ES *)ses; - es->flags |= GF_M2TS_ES_IS_SECTION; - if (stream_type == GF_M2TS_13818_6_ANNEX_D) - printf("stream type DSM CC user private section: pid = %d \n", pid); - else - printf("unknown private section: pid = %d \n", pid); + es->flags |= GF_M2TS_ES_IS_SECTION; + printf("stream type DSM CC user private section: pid = %d \n", pid); /* NULL means: trigger the call to on_event with DVB_GENERAL type and the raw section as payload */ ses->sec = gf_m2ts_section_filter_new(NULL, 1); break; @@ -1351,7 +1543,7 @@ static void gf_m2ts_process_pmt(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *pmt, GF case GF_M2TS_DVB_DATA_BROADCAST_ID_DESCRIPTOR: { u32 id = data[2]<<8 | data[3]; - if (id == 0xB) { + if ((id == 0xB) && ses && !ses->sec) { ses->sec = gf_m2ts_section_filter_new(NULL, 1); } } @@ -1428,7 +1620,11 @@ static void gf_m2ts_process_pmt(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *pmt, GF nb_es++; } } + if (nb_es) { + if(ts->nb_prog_pmt_received == gf_list_count(ts->programs)){ + ts->all_prog_pmt_received = 1; + } evt_type = (status&GF_M2TS_TABLE_FOUND) ? GF_M2TS_EVT_PMT_FOUND : GF_M2TS_EVT_PMT_UPDATE; if (ts->on_event) ts->on_event(ts, evt_type, pmt->program); } else { @@ -1461,19 +1657,19 @@ static void gf_m2ts_process_pat(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *ses, GF if (nb_sections > 1) { GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("PAT on multiple sections not supported\n")); } - + section = (GF_M2TS_Section *)gf_list_get(sections, 0); data = section->data; data_size = section->data_size; - nb_progs = data_size / 4; + nb_progs = data_size / 4; for (i=0; init) { ts->nit = gf_m2ts_section_filter_new(gf_m2ts_process_nit, 0); } @@ -1494,7 +1690,7 @@ static void gf_m2ts_process_pat(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *ses, GF } evt_type = (status&GF_M2TS_TABLE_UPDATE) ? GF_M2TS_EVT_PAT_UPDATE : GF_M2TS_EVT_PAT_FOUND; - if (ts->on_event) ts->on_event(ts, evt_type, NULL); + if (ts->on_event) ts->on_event(ts, evt_type, NULL); } static void gf_m2ts_process_cat(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *ses, GF_List *sections, u8 table_id, u16 ex_table_id, u8 version_number, u8 last_section_number, u32 status) @@ -1624,26 +1820,110 @@ static void gf_m2ts_pes_header(GF_M2TS_PES *pes, unsigned char *data, u32 data_s } } +static void gf_m2ts_flush_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, GF_M2TS_Header *hdr) +{ + GF_M2TS_PESHeader pesh; + + /*we need at least a full, valid start code !!*/ + if ((pes->data_len >= 4) && !pes->data[0] && !pes->data[1] && (pes->data[2]==0x1)) { + u32 len; + u32 stream_id = pes->data[3] | 0x100; + if ((stream_id >= 0x1c0 && stream_id <= 0x1df) || + (stream_id >= 0x1e0 && stream_id <= 0x1ef) || + (stream_id == 0x1bd)) { + + /*OK read header*/ + gf_m2ts_pes_header(pes, pes->data+3, pes->data_len-3, &pesh); + { + GF_M2TS_PES_PCK pck; + memset(&pck, 0, sizeof(GF_M2TS_PES_PCK)); + pck.PTS = pesh.PTS; + pck.DTS = pesh.DTS; + pck.stream = pes; + if (pes->rap) pck.flags |= GF_M2TS_PES_PCK_RAP; + pes->pes_end_packet_number = ts->pck_number; + if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_PES_TIMING, &pck); + } + + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d Got PES header PTS %d\n", pes->pid, pesh.PTS)); + /*3-byte start-code + 6 bytes header + hdr extensions*/ + len = 9 + pesh.hdr_data_len; + if (pes->reframe) { + u32 remain; + u32 offset = len; + + if (pes->prev_data_len) { + assert(pes->prev_data_len < len); + offset = len - pes->prev_data_len; + memcpy(pes->data + offset, pes->prev_data, pes->prev_data_len); + } + remain = pes->reframe(ts, pes, pesh.DTS, pesh.PTS, pes->data+offset, pes->data_len-offset); + + if (pes->prev_data) gf_free(pes->prev_data); + pes->prev_data = NULL; + pes->prev_data_len = 0; + if (remain) { + pes->prev_data = gf_malloc(sizeof(char)*remain); + memcpy(pes->prev_data, pes->data + pes->data_len - remain, remain); + pes->prev_data_len = remain; + } + } + } + /*SL-packetized stream*/ + else if ((u8) pes->data[3]==0xfa) { + GF_M2TS_SL_PCK sl_pck; + /*read header*/ + gf_m2ts_pes_header(pes, pes->data+3, pes->data_len-3, &pesh); + + /*3-byte start-code + 6 bytes header + hdr extensions*/ + len = 9 + pesh.hdr_data_len; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] SL Packet in PES for %d - ES ID %d\n", pes->pid, pes->mpeg4_es_id)); + if (pes->data_len > len) { + sl_pck.data = pes->data + len; + sl_pck.data_len = pes->data_len - len; + sl_pck.stream = (GF_M2TS_ES *)pes; + if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_SL_PCK, &sl_pck); + } else { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Bad SL Packet size: (%d indicated < %d header)\n", pes->pid, pes->data_len, len)); + } + } else { + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PES %d: unknown stream ID %08X\n", pes->pid, stream_id)); + } + } else { + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PES %d: Bad PES Header, discarding packet (maybe stream is encrypted ?)\n", hdr->pid)); + } + if (pes->data) gf_free(pes->data); + pes->data = NULL; + pes->data_len = 0; + pes->pes_len = 0; + pes->rap = 0; +} static void gf_m2ts_process_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, GF_M2TS_Header *hdr, unsigned char *data, u32 data_size, GF_M2TS_AdaptationField *paf) { + u8 expect_cc; + Bool disc; Bool flush_pes = 0; -#if 0 - u8 expect_cc = (pes->cc<0) ? hdr->continuity_counter : (pes->cc + 1) & 0xf; - Bool disc = (expect_cc == hdr->continuity_counter) ? 0 : 1; - pes->cc = expect_cc; + /*duplicated packet, NOT A DISCONTINUITY, discard the packet*/ + if (hdr->continuity_counter==pes->cc) return; + + expect_cc = (pes->cc<0) ? hdr->continuity_counter : (pes->cc + 1) & 0xf; + disc = (expect_cc == hdr->continuity_counter) ? 0 : 1; + pes->cc = hdr->continuity_counter; if (disc) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] PES %d: Packet discontinuity (%d expected - got %d- - trashing PES packet\n", pes->pid, expect_cc, hdr->continuity_counter)); if (pes->data) { gf_free(pes->data); pes->data = NULL; } pes->data_len = 0; pes->pes_len = 0; + pes->cc = -1; return; } -#endif if (!pes->reframe) return; @@ -1668,66 +1948,7 @@ static void gf_m2ts_process_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, GF_M2TS_H /*PES first fragment: flush previous packet*/ if (flush_pes && pes->data) { - GF_M2TS_PESHeader pesh; - - /*we need at least a full, valid start code !!*/ - if ((pes->data_len >= 4) && !pes->data[0] && !pes->data[1] && (pes->data[2]==0x1)) { - u32 len; - u32 stream_id = pes->data[3] | 0x100; - if ((stream_id >= 0x1c0 && stream_id <= 0x1df) || - (stream_id >= 0x1e0 && stream_id <= 0x1ef) || - (stream_id == 0x1bd)) { - - /*OK read header*/ - gf_m2ts_pes_header(pes, pes->data+3, pes->data_len-3, &pesh); - { - GF_M2TS_PES_PCK pck; - memset(&pck, 0, sizeof(GF_M2TS_PES_PCK)); - pck.PTS = pesh.PTS; - pck.DTS = pesh.DTS; - pck.stream = pes; - if (pes->rap) pck.flags |= GF_M2TS_PES_PCK_RAP; - pes->pes_end_packet_number = ts->pck_number; - if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_PES_TIMING, &pck); - } - - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d Got PES header PTS %d\n", pes->pid, pesh.PTS)); - /*3-byte start-code + 6 bytes header + hdr extensions*/ - len = 9 + pesh.hdr_data_len; - if (pes->reframe) - pes->reframe(ts, pes, pesh.DTS, pesh.PTS, pes->data+len, pes->data_len-len); - } - /*SL-packetized stream*/ - else if ((u8) pes->data[3]==0xfa) { - GF_M2TS_SL_PCK sl_pck; - /*read header*/ - gf_m2ts_pes_header(pes, pes->data+3, pes->data_len-3, &pesh); - - /*3-byte start-code + 6 bytes header + hdr extensions*/ - len = 9 + pesh.hdr_data_len; - - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] SL Packet in PES for %d - ES ID %d\n", pes->pid, pes->mpeg4_es_id)); - if (pes->data_len > len) { - sl_pck.data = pes->data + len; - sl_pck.data_len = pes->data_len - len; - sl_pck.stream = (GF_M2TS_ES *)pes; - if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_SL_PCK, &sl_pck); - } else { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Bad SL Packet size: (%d indicated < %d header)\n", pes->pid, pes->data_len, len)); - } - } else { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PES %d: unknown stream ID %08X\n", pes->pid, stream_id)); - } - } else { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] PES %d: Bad PES Header, discarding packet (maybe stream is encrypted ?)\n", hdr->pid)); - } - if (pes->data) { - gf_free(pes->data); - pes->data = NULL; - pes->data_len = 0; - pes->pes_len = 0; - } - pes->rap = 0; + gf_m2ts_flush_pes(ts, pes, hdr); if (!data_size) return; } /*we need to wait for first packet of PES*/ @@ -1749,6 +1970,10 @@ static void gf_m2ts_process_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, GF_M2TS_H if (hdr->payload_start && !pes->pes_len && (pes->data_len>=6)) { pes->pes_len = (pes->data[4]<<8) | pes->data[5]; GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d: Got PES packet len %d\n", pes->pid, pes->pes_len)); + + if (pes->pes_len + 6 == pes->data_len) { + gf_m2ts_flush_pes(ts, pes, hdr); + } } } @@ -1810,7 +2035,7 @@ static void gf_m2ts_process_packet(GF_M2TS_Demuxer *ts, unsigned char *data) //#if DEBUG_TS_PACKET GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] Packet PID %d\n", hdr.pid)); //#endif - + //printf("[MPEG-2 TS] Packet PID %d\n", hdr.pid); paf = NULL; payload_size = 184; pos = 4; @@ -1839,6 +2064,8 @@ static void gf_m2ts_process_packet(GF_M2TS_Demuxer *ts, unsigned char *data) memset(paf, 0, sizeof(GF_M2TS_AdaptationField)); gf_m2ts_get_adaptation_field(ts, paf, data+5, af_size, hdr.pid); payload_size = 0; + /*no payload and no PCR, return*/ + if (! paf->PCR_flag) return; break; /*reserved*/ case 0: @@ -1872,19 +2099,17 @@ static void gf_m2ts_process_packet(GF_M2TS_Demuxer *ts, unsigned char *data) gf_m2ts_gather_section(ts, ts->eit, NULL, &hdr, data, payload_size); return; } else if (hdr.pid == GF_M2TS_PID_TDT_TOT_ST) { - gf_m2ts_gather_section(ts, ts->tdt_tot_st, NULL, &hdr, data, payload_size); + gf_m2ts_gather_section(ts, ts->tdt_tot, NULL, &hdr, data, payload_size); } else { /* ignore packet */ } } else if (es->flags & GF_M2TS_ES_IS_SECTION) { /* The stream uses sections to carry its payload */ GF_M2TS_SECTION_ES *ses = (GF_M2TS_SECTION_ES *)es; - //fprintf(stderr, "000000000000000000000000000000000000000000000\n\n\n\n\n\n\n\n"); if (ses->sec) gf_m2ts_gather_section(ts, ses->sec, ses, &hdr, data, payload_size); - //fprintf(stderr, "callback: %x %x\n", ses->sec->process_section, gf_m2ts_process_pmt); } else { GF_M2TS_PES *pes = (GF_M2TS_PES *)es; /* regular stream using PES packets */ - if (pes->reframe) gf_m2ts_process_pes(ts, pes, &hdr, data, payload_size, paf); + if (pes->reframe && payload_size) gf_m2ts_process_pes(ts, pes, &hdr, data, payload_size, paf); } } if (paf && paf->PCR_flag && es) { @@ -1948,7 +2173,7 @@ GF_Err gf_m2ts_process_data(GF_M2TS_Demuxer *ts, char *data, u32 data_size) } return GF_OK; } - /*process*/ + /*process*/ gf_m2ts_process_packet(ts, ts->buffer+pos); pos += 188; } @@ -2014,11 +2239,19 @@ void gf_m2ts_reset_parsers(GF_M2TS_Demuxer *ts) } else { GF_M2TS_PES *pes = (GF_M2TS_PES *)es; if (!pes || (pes->pid==pes->program->pmt_pid)) continue; + pes->cc = -1; pes->frame_state = 0; if (pes->data) gf_free(pes->data); pes->data = NULL; pes->data_len = 0; + if (pes->prev_data) gf_free(pes->prev_data); + pes->prev_data = NULL; + pes->prev_data_len = 0; pes->PTS = pes->DTS = 0; + pes->pes_len = pes->pes_end_packet_number = pes->pes_start_packet_number = 0; + if (pes->buf) gf_free(pes->buf); + pes->buf = NULL; + pes->buf_len = 0; } // gf_free(es); // ts->ess[i] = NULL; @@ -2072,6 +2305,11 @@ GF_Err gf_m2ts_set_pes_framing(GF_M2TS_PES *pes, u32 mode) pes->data = NULL; } pes->data_len = 0; + if (pes->prev_data) { + gf_free(pes->prev_data); + pes->prev_data = NULL; + } + pes->prev_data_len = 0; pes->pes_len = 0; pes->reframe = NULL; break; @@ -2124,12 +2362,17 @@ GF_M2TS_Demuxer *gf_m2ts_demux_new() ts->sdt = gf_m2ts_section_filter_new(gf_m2ts_process_sdt, 1); ts->nit = gf_m2ts_section_filter_new(gf_m2ts_process_nit, 0); ts->eit = gf_m2ts_section_filter_new(NULL/*gf_m2ts_process_eit*/, 1); - ts->tdt_tot_st = gf_m2ts_section_filter_new(NULL/*gf_m2ts_process_tdt_tot_st*/, 1); + ts->tdt_tot = gf_m2ts_section_filter_new(gf_m2ts_process_tdt_tot, 1); #ifdef DUMP_MPE_IP_DATAGRAMS gf_dvb_mpe_init(ts); #endif + ts->requested_progs = gf_list_new(); + ts->requested_pids = gf_list_new(); + ts->demux_and_play = 0; + ts->nb_prog_pmt_received = 0; + return ts; } @@ -2141,9 +2384,9 @@ void gf_m2ts_demux_del(GF_M2TS_Demuxer *ts) if (ts->sdt) gf_m2ts_section_filter_del(ts->sdt); if (ts->nit) gf_m2ts_section_filter_del(ts->nit); if (ts->eit) gf_m2ts_section_filter_del(ts->eit); - if (ts->tdt_tot_st) gf_m2ts_section_filter_del(ts->tdt_tot_st); + if (ts->tdt_tot) gf_m2ts_section_filter_del(ts->tdt_tot); - for (i=0; i<8192; i++) { + for (i=0; iess[i]) gf_m2ts_es_del(ts->ess[i]); } if (ts->buffer) gf_free(ts->buffer); @@ -2161,7 +2404,9 @@ void gf_m2ts_demux_del(GF_M2TS_Demuxer *ts) } gf_list_del(ts->programs); + if (ts->TDT_time) gf_free(ts->TDT_time); gf_m2ts_reset_sdt(ts); + if (ts->tdt_tot) gf_list_del(ts->SDTs); #ifdef DUMP_MPE_IP_DATAGRAMS @@ -2178,4 +2423,493 @@ void gf_m2ts_print_info(GF_M2TS_Demuxer *ts) #endif } + +/* DVB fonction */ + +static u32 TSDemux_DemuxRun(void *_p) +{ + GF_Err e; + char data[UDP_BUFFER_SIZE]; +#ifdef GPAC_HAS_LINUX_DVB + char dvbts[DVB_BUFFER_SIZE]; +#endif + u32 size; + //u32 i; + GF_M2TS_Demuxer *ts = _p; + + ts->run_state = 1; + + gf_m2ts_reset_parsers(ts); + +#ifdef GPAC_HAS_LINUX_DVB + if (ts->tuner) { + // in case of DVB + while (ts->run_state) { + s32 ts_size = read(ts->tuner->ts_fd, dvbts, DVB_BUFFER_SIZE); + if (ts_size>0) gf_m2ts_process_data(ts, dvbts, (u32) ts_size); + } + } else +#endif + if (ts->sock) { + Bool first_run, is_rtp; + first_run = 1; + is_rtp = 0; + while (ts->run_state) { + size = 0; + /*m2ts chunks by chunks*/ + e = gf_sk_receive(ts->sock, data, UDP_BUFFER_SIZE, 0, &size); + if (!size || e) { + gf_sleep(1); + continue; + } + if (first_run) { + first_run = 0; + /*FIXME: we assume only simple RTP packaging (no CSRC nor extensions)*/ + if ((data[0] != 0x47) && ((data[1] & 0x7F) == 33) ) { + is_rtp = 1; + } + } + /*process chunk*/ + if (is_rtp) { + gf_m2ts_process_data(ts, data+12, size-12); + } else { + gf_m2ts_process_data(ts, data, size); + } + } + } else if (ts->dnload) { + while (ts->run_state) { + gf_dm_sess_process(ts->dnload); + gf_sleep(1); + } + } else if (ts->file) { + u32 pos = 0; + if (ts->start_range && ts->duration) { + Double perc = ts->start_range / (1000 * ts->duration); + pos = (u32) (s64) (perc * ts->file_size); + /*align to TS packet size*/ + while (pos%188) pos++; + if (pos>=ts->file_size) { + ts->start_range = 0; + pos = 0; + } + } + gf_f64_seek(ts->file, pos, SEEK_SET); + +restart_file: + + while (ts->run_state && !feof(ts->file)) { + /*m2ts chunks by chunks*/ + size = fread(data, 1, 188, ts->file); + if (!size && (ts->loop_demux == 1)) { + gf_f64_seek(ts->file, pos, SEEK_SET); + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[M2TSDemux] Loop \n")); + gf_sleep(500); + size = fread(data, 1, 188, ts->file); + } + if (!size) break; + if (size != 188) { + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[M2TS In] %u bytes read from file instead of 188.\n", size)); + } + /*process chunk*/ + gf_m2ts_process_data(ts, data, size); + + ts->nb_pck++; + //fprintf(stderr, "TS packet #%d\r", ts->nb_pck); + + //gf_sleep(0); + /*if asked to regulate, wait until we get a play request*/ + while (ts->run_state && !ts->nb_playing && ts->file_regulate) { + gf_sleep(50); + continue; + } + + if(feof(ts->file) && ts->loop_demux == 1){ + gf_f64_seek(ts->file, pos, SEEK_SET); + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[M2TSDemux] Loop \n")); + gf_sleep(3000); + } + } + if (feof(ts->file)) GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[M2TSDemux] EOS reached\n")); + + if (ts->run_state && ts->query_next) { + const char *next_url = ts->query_next(ts->udta_query); + if (next_url) { + fclose(ts->file); + ts->file = gf_f64_open(next_url, "rb"); + if (ts->file) goto restart_file; + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M2TSDemux] Cannot open next file %s\n", next_url)); + } + } + } + ts->run_state = 2; + return 0; +} + + +static GF_Err TSDemux_SetupLive(GF_M2TS_Demuxer *ts, char *url) +{ + GF_Err e = GF_OK; + char *str; + u16 port; + u32 sock_type = 0; + + if (!strnicmp(url, "udp://", 6) || !strnicmp(url, "mpegts-udp://", 13)) { + sock_type = GF_SOCK_TYPE_UDP; + } else if (!strnicmp(url, "mpegts-tcp://", 13) ) { + sock_type = GF_SOCK_TYPE_TCP; + } else { + e = GF_NOT_SUPPORTED; + return e; + } + + url = strchr(url, ':'); + url += 3; + + ts->sock = gf_sk_new(sock_type); + if (!ts->sock) { + return e = GF_IO_ERR; + } + + /*setup port and src*/ + port = 1234; + str = strrchr(url, ':'); + /*take care of IPv6 address*/ + if (str && strchr(str, ']')) str = strchr(url, ':'); + if (str) { + port = atoi(str+1); + str[0] = 0; + } + + /*do we have a source ?*/ + if (strlen(url) && strcmp(url, "localhost") ) { + const char *mob_ip = NULL; + if (ts->MobileIPEnabled){ + mob_ip = ts->network_type; + } + + if (gf_sk_is_multicast_address(url)) { + mob_ip = ts->network_type; + gf_sk_setup_multicast(ts->sock, url, port, 0, 0, (char*)mob_ip); + } else { + gf_sk_bind(ts->sock, (char*)mob_ip, port, url, 0, GF_SOCK_REUSE_PORT); + } + } + if (str) str[0] = ':'; + + gf_sk_set_buffer_size(ts->sock, 0, UDP_BUFFER_SIZE); + gf_sk_set_block_mode(ts->sock, 0); + + //gf_th_set_priority(ts->th, GF_THREAD_PRIORITY_HIGHEST); + return TSDemux_DemuxPlay(ts); + +} + +#ifdef GPAC_HAS_LINUX_DVB + +static GF_Err gf_dvb_tune(GF_Tuner *tuner, const char *url, const char *chan_path) { + struct dmx_pes_filter_params pesFilterParams; + struct dvb_frontend_parameters frp; + int demux1, front1; + FILE *chanfile; + char line[255], chan_name_t[255]; + char freq_str[255], inv[255], bw[255], lcr[255], hier[255], cr[255], + mod[255], transm[255], gi[255], apid_str[255], vpid_str[255]; + const char *chan_conf = ":%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:"; + char *chan_name; + char *tmp; + char frontend_name[100], demux_name[100], dvr_name[100]; + u32 adapter_num; + + chanfile = gf_f64_open(chan_path, "r"); + if (!chanfile) return GF_BAD_PARAM; + + chan_name = (char *) url+6; // 6 = strlen("dvb://") + + // support for multiple frontends + tmp = strchr(chan_name, '@'); + if (tmp) { + adapter_num = atoi(tmp+1); + tmp[0] = 0; + } else { + adapter_num = 0; + } + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("Channel name %s\n", chan_name)); + + while(!feof(chanfile)) { + if ( fgets(line, 255, chanfile) != NULL) { + if (line[0]=='#') continue; + if (line[0]=='\r') continue; + if (line[0]=='\n') continue; + + strncpy(chan_name_t, line, index(line, ':')-line); + if (strncmp(chan_name,chan_name_t,strlen(chan_name))==0) { + sscanf(strstr(line,":"), chan_conf, freq_str, inv, bw, lcr, cr, mod, transm, gi, hier, apid_str, vpid_str); + tuner->freq = (uint32_t) atoi(freq_str); + tuner->apid = (uint16_t) atoi(apid_str); + tuner->vpid = (uint16_t) atoi(vpid_str); + //Inversion + if(! strcmp(inv, "INVERSION_ON")) tuner->specInv = INVERSION_ON; + else if(! strcmp(inv, "INVERSION_OFF")) tuner->specInv = INVERSION_OFF; + else tuner->specInv = INVERSION_AUTO; + //LP Code Rate + if(! strcmp(lcr, "FEC_1_2")) tuner->LP_CodeRate =FEC_1_2; + else if(! strcmp(lcr, "FEC_2_3")) tuner->LP_CodeRate =FEC_2_3; + else if(! strcmp(lcr, "FEC_3_4")) tuner->LP_CodeRate =FEC_3_4; + else if(! strcmp(lcr, "FEC_4_5")) tuner->LP_CodeRate =FEC_4_5; + else if(! strcmp(lcr, "FEC_6_7")) tuner->LP_CodeRate =FEC_6_7; + else if(! strcmp(lcr, "FEC_8_9")) tuner->LP_CodeRate =FEC_8_9; + else if(! strcmp(lcr, "FEC_5_6")) tuner->LP_CodeRate =FEC_5_6; + else if(! strcmp(lcr, "FEC_7_8")) tuner->LP_CodeRate =FEC_7_8; + else if(! strcmp(lcr, "FEC_NONE")) tuner->LP_CodeRate =FEC_NONE; + else tuner->LP_CodeRate =FEC_AUTO; + //HP Code Rate + if(! strcmp(cr, "FEC_1_2")) tuner->HP_CodeRate =FEC_1_2; + else if(! strcmp(cr, "FEC_2_3")) tuner->HP_CodeRate =FEC_2_3; + else if(! strcmp(cr, "FEC_3_4")) tuner->HP_CodeRate =FEC_3_4; + else if(! strcmp(cr, "FEC_4_5")) tuner->HP_CodeRate =FEC_4_5; + else if(! strcmp(cr, "FEC_6_7")) tuner->HP_CodeRate =FEC_6_7; + else if(! strcmp(cr, "FEC_8_9")) tuner->HP_CodeRate =FEC_8_9; + else if(! strcmp(cr, "FEC_5_6")) tuner->HP_CodeRate =FEC_5_6; + else if(! strcmp(cr, "FEC_7_8")) tuner->HP_CodeRate =FEC_7_8; + else if(! strcmp(cr, "FEC_NONE")) tuner->HP_CodeRate =FEC_NONE; + else tuner->HP_CodeRate =FEC_AUTO; + //Modulation + if(! strcmp(mod, "QAM_128")) tuner->modulation = QAM_128; + else if(! strcmp(mod, "QAM_256")) tuner->modulation = QAM_256; + else if(! strcmp(mod, "QAM_64")) tuner->modulation = QAM_64; + else if(! strcmp(mod, "QAM_32")) tuner->modulation = QAM_32; + else if(! strcmp(mod, "QAM_16")) tuner->modulation = QAM_16; + //Bandwidth + if(! strcmp(bw, "BANDWIDTH_6_MHZ")) tuner->bandwidth = BANDWIDTH_6_MHZ; + else if(! strcmp(bw, "BANDWIDTH_7_MHZ")) tuner->bandwidth = BANDWIDTH_7_MHZ; + else if(! strcmp(bw, "BANDWIDTH_8_MHZ")) tuner->bandwidth = BANDWIDTH_8_MHZ; + //Transmission Mode + if(! strcmp(transm, "TRANSMISSION_MODE_2K")) tuner->TransmissionMode = TRANSMISSION_MODE_2K; + else if(! strcmp(transm, "TRANSMISSION_MODE_8K")) tuner->TransmissionMode = TRANSMISSION_MODE_8K; + //Guard Interval + if(! strcmp(gi, "GUARD_INTERVAL_1_32")) tuner->guardInterval = GUARD_INTERVAL_1_32; + else if(! strcmp(gi, "GUARD_INTERVAL_1_16")) tuner->guardInterval = GUARD_INTERVAL_1_16; + else if(! strcmp(gi, "GUARD_INTERVAL_1_8")) tuner->guardInterval = GUARD_INTERVAL_1_8; + else tuner->guardInterval = GUARD_INTERVAL_1_4; + //Hierarchy + if(! strcmp(hier, "HIERARCHY_1")) tuner->hierarchy = HIERARCHY_1; + else if(! strcmp(hier, "HIERARCHY_2")) tuner->hierarchy = HIERARCHY_2; + else if(! strcmp(hier, "HIERARCHY_4")) tuner->hierarchy = HIERARCHY_4; + else if(! strcmp(hier, "HIERARCHY_AUTO")) tuner->hierarchy = HIERARCHY_AUTO; + else tuner->hierarchy = HIERARCHY_NONE; + + break; + } + } + } + fclose(chanfile); + + sprintf(frontend_name, "/dev/dvb/adapter%d/frontend0", adapter_num); + sprintf(demux_name, "/dev/dvb/adapter%d/demux0", adapter_num); + sprintf(dvr_name, "/dev/dvb/adapter%d/dvr0", adapter_num); + + // Open frontend + if((front1 = open(frontend_name,O_RDWR|O_NONBLOCK)) < 0){ + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Cannot open frontend %s.\n", frontend_name)); + return GF_IO_ERR; + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("Frontend %s opened.\n", frontend_name)); + } + // Open demuxes + if ((demux1=open(demux_name, O_RDWR|O_NONBLOCK)) < 0){ + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Cannot open demux %s\n", demux_name)); + return GF_IO_ERR; + } else { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Demux %s opened.\n", demux_name)); + } + // Set FrontendParameters - DVB-T + frp.frequency = tuner->freq; + frp.inversion = tuner->specInv; + frp.u.ofdm.bandwidth = tuner->bandwidth; + frp.u.ofdm.code_rate_HP = tuner->HP_CodeRate; + frp.u.ofdm.code_rate_LP = tuner->LP_CodeRate; + frp.u.ofdm.constellation = tuner->modulation; + frp.u.ofdm.transmission_mode = tuner->TransmissionMode; + frp.u.ofdm.guard_interval = tuner->guardInterval; + frp.u.ofdm.hierarchy_information = tuner->hierarchy; + // Set frontend + if (ioctl(front1, FE_SET_FRONTEND, &frp) < 0){ + return GF_IO_ERR; + } + // Set dumex + pesFilterParams.pid = 0x2000; // Linux-DVB API take PID=2000 for FULL/RAW TS flag + pesFilterParams.input = DMX_IN_FRONTEND; + pesFilterParams.output = DMX_OUT_TS_TAP; + pesFilterParams.pes_type = DMX_PES_OTHER; + pesFilterParams.flags = DMX_IMMEDIATE_START; + if (ioctl(demux1, DMX_SET_PES_FILTER, &pesFilterParams) < 0){ + return GF_IO_ERR; + } + /* The following code differs from mplayer and alike because the device is opened in blocking mode */ + if ((tuner->ts_fd = open(dvr_name, O_RDONLY/*|O_NONBLOCK*/)) < 0){ + return GF_IO_ERR; + } + return GF_OK; +} + +u32 gf_dvb_get_freq_from_url(const char *channels_config_path, const char *url) +{ + FILE *channels_config_file; + char line[255], *tmp, *channel_name; + + u32 freq; + + /* get rid of trailing @ */ + tmp = strchr(url, '@'); + if (tmp) tmp[0] = 0; + + channel_name = (char *)url+6; + + channels_config_file = gf_f64_open(channels_config_path, "r"); + if (!channels_config_file) return GF_BAD_PARAM; + + freq = 0; + while(!feof(channels_config_file)) { + if ( fgets(line, 255, channels_config_file) != NULL) { + if (line[0]=='#') continue; + if (line[0]=='\r') continue; + if (line[0]=='\n') continue; + + tmp = strchr(line, ':'); + tmp[0] = 0; + if (!strcmp(line, channel_name)) { + char *tmp2; + tmp++; + tmp2 = strchr(tmp, ':'); + if (tmp2) tmp2[0] = 0; + freq = (u32)atoi(tmp); + break; + } + } + } + return freq; +} + +GF_Err TSDemux_SetupDVB(GF_M2TS_Demuxer *ts, const char *url) +{ + GF_Err e = GF_OK; + + if (! ts->dvb_channels_conf_path) return GF_BAD_PARAM; + + if (strnicmp(url, "dvb://", 6)) return GF_NOT_SUPPORTED; + + if (!ts->tuner) GF_SAFEALLOC(ts->tuner, GF_Tuner); + + if (ts->tuner->freq != 0 && ts->tuner->freq == gf_dvb_get_freq_from_url(ts->dvb_channels_conf_path, url)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M2TSDemux] Tuner already tuned to that frequency\n")); + return GF_OK; + } + + e = gf_dvb_tune(ts->tuner, url, ts->dvb_channels_conf_path); + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[M2TSDemux] Unable to tune to frequency\n")); + return GF_SERVICE_ERROR; + } + + return TSDemux_DemuxPlay(ts); +} + +#endif + +static GF_Err TSDemux_SetupFile(GF_M2TS_Demuxer *ts, char *url) +{ + if (ts->file && !strcmp(ts->filename, url)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[TSDemux] TS file already being processed: %s\n", url)); + return GF_IO_ERR; + } + + ts->file = gf_f64_open(url, "rb"); + if (!ts->file) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[TSDemux] Could not open TS file: %s\n", url)); + return GF_IO_ERR; + } + strcpy(ts->filename, url); + + gf_f64_seek(ts->file, 0, SEEK_END); + ts->file_size = gf_f64_tell(ts->file); + + /* reinitialization for seek */ + ts->end_range = ts->start_range = 0; + ts->nb_playing = 0; + + return TSDemux_DemuxPlay(ts); + +} + +GF_Err TSDemux_Demux_Setup(GF_M2TS_Demuxer *ts, const char *url, Bool loop) +{ + char szURL[2048]; + char *frag; + + if(!url){ + return GF_IO_ERR; + } + strcpy(szURL, url); + frag = strrchr(szURL, '#'); + if (frag) frag[0] = 0; + + ts->file_regulate = 0; + ts->duration = 0; + + if(loop == 1){ + ts->loop_demux = 1; + printf("Loop Mode activated \n"); + } + + if (!strnicmp(url, "udp://", 6) + || !strnicmp(url, "mpegts-udp://", 13) + || !strnicmp(url, "mpegts-tcp://", 13) + ) { + return TSDemux_SetupLive(ts, (char *) szURL); + } +#ifdef GPAC_HAS_LINUX_DVB + else if (!strnicmp(url, "dvb://", 6)) { + return TSDemux_SetupDVB(ts, (char *) szURL); + } +#endif + else { + return TSDemux_SetupFile(ts, (char *) szURL); + } + + return GF_NOT_SUPPORTED; +} + +GF_Err TSDemux_CloseDemux(GF_M2TS_Demuxer *ts) +{ + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[TSDemux] Destroying demuxer\n")); + if (ts->th) { + if (ts->run_state == 1) { + ts->run_state = 0; + while (ts->run_state!=2) gf_sleep(0); + } + gf_th_del(ts->th); + ts->th = NULL; + } + + if (ts->file) fclose(ts->file); + ts->file = NULL; + + return GF_OK; +} + + +GF_Err TSDemux_DemuxPlay(GF_M2TS_Demuxer *ts){ + + if(ts->th){ + /*start playing for tune-in*/ + return gf_th_run(ts->th, TSDemux_DemuxRun, ts); + }else{ + return TSDemux_DemuxRun(ts); + } + +} + + + #endif /*GPAC_DISABLE_MPEG2TS*/ + diff --git a/src/media_tools/text_import.c b/src/media_tools/text_import.c index b58cadd..00d4ce3 100644 --- a/src/media_tools/text_import.c +++ b/src/media_tools/text_import.c @@ -569,18 +569,11 @@ static GF_Err gf_text_import_srt(GF_MediaImporter *import) if (duration && (start >= duration)) break; } - /*final flush*/ - if (end && !(import->flags & GF_IMPORT_NO_TEXT_FLUSH ) ) { - gf_isom_text_reset(samp); - s = gf_isom_text_to_sample(samp); - s->DTS = (u64) ((timescale*end)/1000); - s->IsRAP = 1; - gf_isom_add_sample(import->dest, track, 1, s); - gf_isom_sample_del(&s); - nb_samp++; - } gf_isom_delete_text_sample(samp); - gf_isom_set_last_sample_duration(import->dest, track, 0); + /*do not add any empty sample at the end since it modifies track duration and is not needed - it is the player job + to figure out when to stop displaying the last text sample + However update the last sample duration*/ + gf_isom_set_last_sample_duration(import->dest, track, (u32) (end-start) ); gf_set_progress("Importing SRT", nb_samp, nb_samp); exit: @@ -615,7 +608,7 @@ static GF_Err gf_text_import_sub(GF_MediaImporter *import) return gf_import_message(import, GF_NOT_SUPPORTED, "Unsupported SUB UTF encoding"); } - FPS = 25.0; + FPS = GF_IMPORT_DEFAULT_FPS; if (import->video_fps) FPS = import->video_fps; cfg = NULL; @@ -805,18 +798,12 @@ static GF_Err gf_text_import_sub(GF_MediaImporter *import) gf_set_progress("Importing SUB", gf_f64_tell(sub_in), file_size); if (duration && (end >= duration)) break; } - /*final flush*/ - if (end && !(import->flags & GF_IMPORT_NO_TEXT_FLUSH ) ) { - gf_isom_text_reset(samp); - s = gf_isom_text_to_sample(samp); - s->DTS = (u64)(FPS*(s64)end); - gf_isom_add_sample(import->dest, track, 1, s); - gf_isom_sample_del(&s); - nb_samp++; - } - gf_isom_delete_text_sample(samp); - - gf_isom_set_last_sample_duration(import->dest, track, 0); + gf_isom_delete_text_sample(samp); + /*do not add any empty sample at the end since it modifies track duration and is not needed - it is the player job + to figure out when to stop displaying the last text sample + However update the last sample duration*/ + + gf_isom_set_last_sample_duration(import->dest, track, (u32) (end-start) ); gf_set_progress("Importing SUB", nb_samp, nb_samp); exit: diff --git a/src/odf/ipmpx_parse.c b/src/odf/ipmpx_parse.c index c83a001..9e8e6ce 100644 --- a/src/odf/ipmpx_parse.c +++ b/src/odf/ipmpx_parse.c @@ -251,7 +251,7 @@ GF_Err GF_IPMPX_ParseEventType(char *val, u8 *eventType, u8 *eventTypeCount) if (j) { szVal[j] = 0; if (!strnicmp(szVal, "0x", 2)) { sscanf(szVal, "%x", &v); eventType[*eventTypeCount] = v; } - else { sscanf(szVal, "%ud", &v); eventType[*eventTypeCount] = v; } + else { sscanf(szVal, "%u", &v); eventType[*eventTypeCount] = v; } j=0; (*eventTypeCount) += 1; if (*eventTypeCount == 9) return GF_OK; @@ -282,7 +282,7 @@ GF_Err gf_ipmpx_data_parse_16(char *val, u16 **outData, u16 *outDataSize) if (j) { szVal[j] = 0; if (!strnicmp(szVal, "0x", 2)) { sscanf(szVal, "%x", &v); data[count] = v; } - else { sscanf(szVal, "%ud", &v); data[count] = v; } + else { sscanf(szVal, "%u", &v); data[count] = v; } j=0; count += 1; if (count == alloc) { diff --git a/src/odf/odf_code.c b/src/odf/odf_code.c index b2f9ee6..9ffd547 100644 --- a/src/odf/odf_code.c +++ b/src/odf/odf_code.c @@ -583,7 +583,8 @@ GF_Err gf_odf_write_iod(GF_BitStream *bs, GF_InitialObjectDescriptor *iod) GF_Descriptor *gf_odf_new_od() { - GF_ObjectDescriptor *newDesc = (GF_ObjectDescriptor *) gf_malloc(sizeof(GF_ObjectDescriptor)); + GF_ObjectDescriptor *newDesc; + GF_SAFEALLOC(newDesc, GF_ObjectDescriptor); if (!newDesc) return NULL; newDesc->URLString = NULL; diff --git a/src/scene_manager/encode_isom.c b/src/scene_manager/encode_isom.c index c40b73a..ab80aad 100644 --- a/src/scene_manager/encode_isom.c +++ b/src/scene_manager/encode_isom.c @@ -111,11 +111,12 @@ static GF_Err gf_sm_import_ui_stream(GF_ISOFile *mp4, GF_ESD *src, Bool rewrite_ static GF_Err gf_sm_import_stream(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_ESD *src, Double imp_time, char *mediaSource, Bool od_sample_rap) { - u32 track, di; + u32 track, di, i; GF_Err e; Bool isAudio, isVideo; char szName[1024]; char *ext; + GF_Descriptor *d; GF_MediaImporter import; GF_MuxInfo *mux = NULL; @@ -261,6 +262,14 @@ static GF_Err gf_sm_import_stream(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_ESD e = gf_media_import(&import); if (e) return e; + i=0; + while ((d = gf_list_enum(src->extensionDescriptors, &i))) { + if (d->tag == GF_ODF_AUX_VIDEO_DATA) { + gf_isom_add_user_data(mp4, gf_isom_get_track_by_id(mp4, import.final_trackID), GF_4CC('A','U','X','V'), 0, NULL, 0); + gf_list_rem(src->extensionDescriptors, i-1); + gf_odf_desc_del(d); + } + } /*if desired delete input*/ if (mux->delete_file) gf_delete_file(mux->file_name); return e; diff --git a/src/scene_manager/loader_bt.c b/src/scene_manager/loader_bt.c index c945e54..70e9f20 100644 --- a/src/scene_manager/loader_bt.c +++ b/src/scene_manager/loader_bt.c @@ -884,9 +884,9 @@ void gf_bt_sffield(GF_BTParser *parser, GF_FieldInfo *info, GF_Node *n) if (!strnicmp(str, "od://", 5)) odstr += 5; else if (!strnicmp(str, "od:", 3)) odstr += 3; /*be carefull, an url like "11-regression-test.mp4" will return 1 on sscanf :)*/ - if (sscanf(odstr, "%ud", &id) == 1) { + if (sscanf(odstr, "%u", &id) == 1) { char szURL[20]; - sprintf(szURL, "%ud", id); + sprintf(szURL, "%u", id); if (strcmp(szURL, odstr)) id=0; } if (id) { @@ -1077,7 +1077,7 @@ u32 gf_bt_get_def_id(GF_BTParser *parser, char *defName) { GF_Node *n; u32 ID; - if (sscanf(defName, "N%ud", &ID) == 1) { + if (sscanf(defName, "N%u", &ID) == 1) { ID ++; n = gf_sg_find_node(parser->load->scene_graph, ID); /*if an existing node use*/ @@ -1778,9 +1778,9 @@ next_field: str = gf_bt_get_next(parser, 0); gf_sg_vrml_mf_append(&proto->ExternProto, GF_SG_VRML_MFURL, (void **) &url); if (!strnicmp(str, "od:", 3)) { - sscanf(str, "od:%ud", &url->OD_ID); + sscanf(str, "od:%u", &url->OD_ID); } else { - if (!sscanf(str, "%ud", &url->OD_ID)) { + if (!sscanf(str, "%u", &url->OD_ID)) { url->url = gf_strdup(str); } else { char szURL[20]; @@ -3239,7 +3239,7 @@ GF_Err gf_bt_loader_run_intern(GF_BTParser *parser, GF_Command *init_com, Bool i if (str[0] == 'D') { parser->au_time += atoi(&str[1]); } else { - if (sscanf(str, "%ud", &parser->au_time) != 1) { + if (sscanf(str, "%u", &parser->au_time) != 1) { gf_bt_report(parser, GF_BAD_PARAM, "Number expected got %s", str); break; } diff --git a/src/scene_manager/loader_xmt.c b/src/scene_manager/loader_xmt.c index 9c4f00d..4275e01 100644 --- a/src/scene_manager/loader_xmt.c +++ b/src/scene_manager/loader_xmt.c @@ -184,9 +184,9 @@ static void xmt_new_od_link(GF_XMTParser *parser, GF_ObjectDescriptor *od, char if (!strnicmp(name, "od", 2)) ID = atoi(name + 2); else if (!strnicmp(name, "iod", 3)) ID = atoi(name+ 3); /*be carefull, an url like "11-regression-test.mp4" will return 1 on sscanf :)*/ - else if (sscanf(name, "%ud", &ID) == 1) { + else if (sscanf(name, "%u", &ID) == 1) { char szURL[20]; - sprintf(szURL, "%ud", ID); + sprintf(szURL, "%u", ID); if (strcmp(szURL, name)) { ID = 0; } else { @@ -242,9 +242,9 @@ static void xmt_new_od_link_from_node(GF_XMTParser *parser, char *name, MFURL *u if (!strnicmp(name, "od", 2)) ID = atoi(name + 2); else if (!strnicmp(name, "iod", 3)) ID = atoi(name + 3); /*be carefull, an url like "11-regression-test.mp4" will return 1 on sscanf :)*/ - else if (sscanf(name, "%ud", &ID) == 1) { + else if (sscanf(name, "%u", &ID) == 1) { char szURL[20]; - sprintf(szURL, "%ud", ID); + sprintf(szURL, "%u", ID); if (strcmp(szURL, name)) { ID = 0; } else { @@ -346,7 +346,7 @@ static u32 xmt_get_od_id(GF_XMTParser *parser, char *od_name) { u32 i, ID; XMT_ODLink *l; - if (sscanf(od_name, "%ud", &ID)==1) return ID; + if (sscanf(od_name, "%u", &ID)==1) return ID; i=0; while ((l = (XMT_ODLink*)gf_list_enum(parser->od_links, &i))) { @@ -360,7 +360,7 @@ static u32 xmt_get_esd_id(GF_XMTParser *parser, char *esd_name) { u32 i, ID; XMT_ESDLink *l; - if (sscanf(esd_name, "%ud", &ID)==1) return ID; + if (sscanf(esd_name, "%u", &ID)==1) return ID; i=0; while ((l = (XMT_ESDLink *)gf_list_enum(parser->esd_links, &i))) { @@ -607,7 +607,7 @@ static u32 xmt_get_node_id(GF_XMTParser *parser, char *name) { GF_Node *n; u32 ID; - if (sscanf(name, "N%ud", &ID) == 1) { + if (sscanf(name, "N%u", &ID) == 1) { ID ++; n = gf_sg_find_node(parser->load->scene_graph, ID); if (n) { @@ -940,7 +940,7 @@ static u32 xmt_parse_sf_field(GF_XMTParser *parser, GF_FieldInfo *info, GF_Node char *name = "pixels"; XMT_GET_ONE_VAL if (strstr(value, "0x")) sscanf(value, "%x", &v); - else sscanf(value, "%ud", &v); + else sscanf(value, "%u", &v); switch (img->numComponents) { case 1: img->pixels[k] = (char) v; diff --git a/src/scene_manager/scene_dump.c b/src/scene_manager/scene_dump.c index 4dd5dd1..37a41d7 100644 --- a/src/scene_manager/scene_dump.c +++ b/src/scene_manager/scene_dump.c @@ -2608,7 +2608,7 @@ static GF_Err DumpLSRDelete(GF_SceneDumper *sdump, GF_Command *com) fprintf(sdump->trace, "/>\n"); return GF_OK; } -#ifdef UNUSED_FUNC +#ifdef GPAC_UNUSED_FUNC static GF_Err DumpLSRInsert(GF_SceneDumper *sdump, GF_Command *com) { return GF_OK; @@ -2619,7 +2619,7 @@ static GF_Err SD_SetSceneGraph(GF_SceneDumper *sdump, GF_SceneGraph *sg) if (sdump) sdump->sg = sg; return GF_OK; } -#endif /* UNUSED_FUNC */ +#endif /*GPAC_UNUSED_FUNC*/ static GF_Err DumpLSRRestore(GF_SceneDumper *sdump, GF_Command *com) { @@ -3213,11 +3213,11 @@ static void ReorderAUContext(GF_List *sample_list, GF_AUContext *au, Bool lsr_du au->timing = (u64) (au->timing_sec * au->owner->timeScale); } - autime = au->timing + au->owner->dump_time_offset; + autime = au->timing + au->owner->imp_exp_time; has_base = 0; i=0; while ((ptr = (GF_AUContext*)gf_list_enum(sample_list, &i))) { - time = ptr->timing + ptr->owner->dump_time_offset; + time = ptr->timing + ptr->owner->imp_exp_time; if ( /*time ordered*/ (time > autime) diff --git a/src/scene_manager/scene_manager.c b/src/scene_manager/scene_manager.c index da45b53..2f041e0 100644 --- a/src/scene_manager/scene_manager.c +++ b/src/scene_manager/scene_manager.c @@ -175,7 +175,7 @@ GF_AUContext *gf_sm_stream_au_new(GF_StreamContext *stream, u64 timing, Double t u64 tmp_timing; tmp_timing = timing ? timing : (u64) (time_sec*1000); - if (stream->last_au_time >= tmp_timing) { + if (stream->imp_exp_time >= tmp_timing) { /*look for existing AU*/ i=0; while ((tmp = (GF_AUContext *)gf_list_enum(stream->AUs, &i))) { @@ -203,7 +203,7 @@ GF_AUContext *gf_sm_stream_au_new(GF_StreamContext *stream, u64 timing, Double t tmp->owner = stream; if (stream->disable_aggregation) tmp->flags |= GF_SM_AU_NOT_AGGREGATED; gf_list_add(stream->AUs, tmp); - stream->last_au_time = tmp_timing; + stream->imp_exp_time = tmp_timing; return tmp; } diff --git a/src/scene_manager/swf_bifs.c b/src/scene_manager/swf_bifs.c index 1e5a063..a939f42 100644 --- a/src/scene_manager/swf_bifs.c +++ b/src/scene_manager/swf_bifs.c @@ -1310,7 +1310,7 @@ static GF_Err swf_bifs_define_sprite(SWFReader *read, u32 nb_frames) /*create new BIFS stream*/ read->bifs_es = gf_sm_stream_new(read->load->ctx, esd->ESID, GF_STREAM_SCENE, 1); read->bifs_es->timeScale = prev_sc->timeScale; - read->bifs_es->dump_time_offset = prev_sc->dump_time_offset + prev_au->timing; + read->bifs_es->imp_exp_time = prev_sc->imp_exp_time + prev_au->timing; /*create first AU*/ read->bifs_au = gf_sm_stream_au_new(read->bifs_es, 0, 0, 1); diff --git a/src/scene_manager/text_to_bifs.c b/src/scene_manager/text_to_bifs.c index 340643b..365ef1d 100644 --- a/src/scene_manager/text_to_bifs.c +++ b/src/scene_manager/text_to_bifs.c @@ -416,7 +416,7 @@ static GF_Err gf_text_import_sub_bifs(GF_SceneManager *ctx, GF_ESD *src, GF_MuxI com = NULL; inf = NULL; - fps = 25.0; + fps = GF_IMPORT_DEFAULT_FPS; if (mux->frame_rate) fps = mux->frame_rate; line = 0; diff --git a/src/scenegraph/base_scenegraph.c b/src/scenegraph/base_scenegraph.c index 82a8e75..a2d1806 100644 --- a/src/scenegraph/base_scenegraph.c +++ b/src/scenegraph/base_scenegraph.c @@ -2006,13 +2006,14 @@ GF_Err gf_node_get_field_by_name(GF_Node *node, char *name, GF_FieldInfo *field) return gf_node_get_field(node, (u32) res, field); } -static char log_node_name[10]; + +static char log_node_name[2+16+1]; const char *gf_node_get_log_name(GF_Node *anim) { const char *name = gf_node_get_name(anim); if (name) return name; else { - sprintf(log_node_name, "0x%p", anim); + sprintf(log_node_name, "%p", anim); return log_node_name; } } diff --git a/src/scenegraph/dom_events.c b/src/scenegraph/dom_events.c index 276c257..6205318 100644 --- a/src/scenegraph/dom_events.c +++ b/src/scenegraph/dom_events.c @@ -219,7 +219,7 @@ void gf_sg_handle_dom_event(GF_Node *hdl, GF_DOM_Event *event, GF_Node *observer { #ifdef GPAC_HAS_SPIDERMONKEY if (hdl->sgprivate->scenegraph->svg_js) - if (hdl->sgprivate->scenegraph->svg_js->handler_execute(hdl, event, observer)) return; + if (hdl->sgprivate->scenegraph->svg_js->handler_execute(hdl, event, observer, NULL)) return; #endif /*no clue what this is*/ GF_LOG(GF_LOG_WARNING, GF_LOG_INTERACT, ("[DOM Events ] Unknown event handler\n")); @@ -252,6 +252,14 @@ static void dom_event_process(GF_Node *listen, GF_DOM_Event *event, GF_Node *obs GF_FieldInfo info; if (gf_node_get_attribute_by_tag(listen, TAG_XMLEV_ATT_handler, 0, 0, &info) == GF_OK) { XMLRI *iri = (XMLRI *)info.far_ptr; + + if ((iri->type==XMLRI_STRING) && iri->string && !strnicmp(iri->string, "javascript:", 11)) { +#ifdef GPAC_HAS_SPIDERMONKEY + if (listen->sgprivate->scenegraph->svg_js) + listen->sgprivate->scenegraph->svg_js->handler_execute(listen, event, observer, iri->string + 11); +#endif + return; + } if (!iri->target && iri->string) { iri->target = gf_sg_find_node_by_name(listen->sgprivate->scenegraph, iri->string+1); } @@ -440,7 +448,7 @@ Bool gf_dom_event_fire_ex(GF_Node *node, GF_DOM_Event *event, GF_List *use_stack GF_DOMEventTarget cur_target; u32 cur_par_idx; if (!node || !event) return 0; - GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[DOM Events ] Graph 0x%x Time %f - Firing event %s.%s\n", gf_node_get_graph(node), gf_node_get_scene_time(node), gf_node_get_log_name(node), gf_dom_event_get_name(event->type))); + GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[DOM Events ] Graph %p Time %f - Firing event %s.%s\n", gf_node_get_graph(node), gf_node_get_scene_time(node), gf_node_get_log_name(node), gf_dom_event_get_name(event->type))); /*flush any pending add_listener see "determine the current target's candidate event listeners" in http://www.w3.org/TR/DOM-Level-3-Events/events.html*/ diff --git a/src/scenegraph/dom_smjs.c b/src/scenegraph/dom_smjs.c index 8778eb5..7204ff2 100644 --- a/src/scenegraph/dom_smjs.c +++ b/src/scenegraph/dom_smjs.c @@ -1077,7 +1077,7 @@ static const char *node_lookup_namespace_by_tag(GF_Node *node, u32 tag) return node_lookup_namespace_by_tag(gf_node_get_parent(node, 0), tag); } -#ifdef UNUSED_FUNC +#ifdef GPAC_UNUSED_FUNC /** * FIXME : function is not used by anybody */ @@ -1101,7 +1101,7 @@ static u32 get_namespace_code_by_prefix(GF_Node *node, char *prefix) /*browse for parent*/ return get_namespace_code_by_prefix(gf_node_get_parent(node, 0), prefix); } -#endif +#endif /*GPAC_UNUSED_FUNC*/ static JSBool dom_node_getProperty(JSContext *c, JSObject *obj, SMJS_PROP_GETTER, jsval *vp) { @@ -1955,8 +1955,22 @@ static JSBool SMJS_FUNCTION(xml_element_set_attribute) } } - if (gf_node_get_attribute_by_name(n, name, ns_code, 1, 1, &info)==GF_OK) { + if (!strcmp(name, "from") || !strcmp(name, "to") || !strcmp(name, "values") ) { + GF_FieldInfo attType; + SMIL_AttributeName *attname; + if (gf_node_get_attribute_by_tag((GF_Node *)n, TAG_SVG_ATT_attributeName, 0, 0, &attType) != GF_OK) + goto exit; + + attname = (SMIL_AttributeName *)attType.far_ptr; + if (!attname->type && attname->name) { + GF_Node *anim_target = gf_smil_anim_get_target(n); + gf_node_get_attribute_by_name((GF_Node *)anim_target, attname->name, attname->type, 0, 0, &attType); + attname->type = attType.fieldType; + } + + anim_value_type = attname->type; + } gf_svg_parse_attribute(n, &info, val, anim_value_type); if (info.fieldType==SVG_ID_datatype) { @@ -2887,7 +2901,9 @@ static JSBool SMJS_FUNCTION(xml_http_send) /*just wait for destruction*/ if (!ctx->async) { while (ctx->sess) { + gf_sg_lock_javascript(ctx->c, 0); gf_sleep(20); + gf_sg_lock_javascript(ctx->c, 1); } } } else { @@ -2903,11 +2919,15 @@ static JSBool SMJS_FUNCTION(xml_http_send) gf_free(ctx->statusText); ctx->statusText = NULL; } + /*opera-style local host*/ + if (!strnicmp(ctx->url, "file://localhost", 16)) xmlf = gf_f64_open(ctx->url+16, "rt"); + /*regular-style local host*/ + else if (!strnicmp(ctx->url, "file://", 7)) xmlf = gf_f64_open(ctx->url+7, "rt"); + else xmlf = gf_f64_open(ctx->url, "rt"); - xmlf = gf_f64_open(ctx->url, "rt"); if (!xmlf) { ctx->html_status = 404; - GF_LOG(GF_LOG_ERROR, GF_LOG_SCRIPT, ("[XmlHttpRequest] cannot parse %s\n", ctx->url)); + GF_LOG(GF_LOG_ERROR, GF_LOG_SCRIPT, ("[XmlHttpRequest] cannot open %s\n", ctx->url)); return JS_TRUE; } ctx->readyState = 2; diff --git a/src/scenegraph/mpeg4_nodes.c b/src/scenegraph/mpeg4_nodes.c index a1005dd..621cafb 100644 --- a/src/scenegraph/mpeg4_nodes.c +++ b/src/scenegraph/mpeg4_nodes.c @@ -24,7 +24,7 @@ /* - DO NOT MOFIFY - File generated on GMT Mon Jan 18 12:27:12 2010 + DO NOT MOFIFY - File generated on GMT Wed Jul 20 05:50:21 2011 BY MPEG4Gen for GPAC Version 0.4.6-DEV */ @@ -32126,14 +32126,14 @@ static Bool AdvancedAudioBuffer_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QTyp *AType = 0; *QType = 13; *QT13_bits = 17; - *b_min = FLT2FIX(-65536.0f); + *b_min = FLT2FIX(-65536); *b_max = FLT2FIX( 0); return 1; case 12: *AType = 0; *QType = 13; *QT13_bits = 17; - *b_min = FLT2FIX(-65536.0f); + *b_min = FLT2FIX(-65536); *b_max = FLT2FIX( 0); return 1; case 13: @@ -35257,6 +35257,7 @@ static void CacheTexture_Del(GF_Node *node) gf_sg_sfstring_del(p->image); gf_sg_sfstring_del(p->cacheURL); gf_sg_mfurl_del(p->cacheOD); + if (p->data) gf_free(p->data); gf_node_free((GF_Node *) p); } diff --git a/src/scenegraph/smil_anim.c b/src/scenegraph/smil_anim.c index 967a22c..4b8568f 100644 --- a/src/scenegraph/smil_anim.c +++ b/src/scenegraph/smil_anim.c @@ -1,1513 +1,1520 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Cyril Concolato - Jean Le Feuvre - * Copyright (c)2004-200X ENST - All rights reserved - * - * This file is part of GPAC / SVG Scene Graph 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 -#include - -#ifndef GPAC_DISABLE_LOG -u32 time_spent_in_anim = 0; -#endif - -#ifndef GPAC_DISABLE_SVG - - -/************************************************************************************** - * Each GF_Node holds the (SVG/SMIL) animation elements which target itself in a list * - * The following are the generic functions to manipulate this list: * - * - add a new animation to the list, * - * - get an animation from the list, * - * - remove an animation from the list, * - * - count the animations in the list, * - * - delete the list * - **************************************************************************************/ -GF_Err gf_node_animation_add(GF_Node *node, void *animation) -{ - if (!node || !animation) return GF_BAD_PARAM; - if (!node->sgprivate->interact) GF_SAFEALLOC(node->sgprivate->interact, struct _node_interactive_ext); - if (!node->sgprivate->interact->animations) node->sgprivate->interact->animations = gf_list_new(); - return gf_list_add(node->sgprivate->interact->animations, animation); -} - -GF_Err gf_node_animation_del(GF_Node *node) -{ - if (!node || !node->sgprivate->interact || !node->sgprivate->interact->animations) return GF_BAD_PARAM; - gf_list_del(node->sgprivate->interact->animations); - node->sgprivate->interact->animations = NULL; - return GF_OK; -} - -u32 gf_node_animation_count(GF_Node *node) -{ - if (!node || !node->sgprivate->interact|| !node->sgprivate->interact->animations) return 0; - return gf_list_count(node->sgprivate->interact->animations); -} - -void *gf_node_animation_get(GF_Node *node, u32 i) -{ - if (!node || !node->sgprivate->interact || !node->sgprivate->interact->animations) return 0; - return gf_list_get(node->sgprivate->interact->animations, i); -} - -GF_Err gf_node_animation_rem(GF_Node *node, u32 i) -{ - if (!node || !node->sgprivate->interact || !node->sgprivate->interact->animations) return GF_OK; - return gf_list_rem(node->sgprivate->interact->animations, i); -} -/************************************************************************************** - * End of Generic GF_Node animations list * - **************************************************************************************/ - - -/************************************************************************************** - * Helping functions for animation * - **************************************************************************************/ -/* Sets the pointer to the attribute value with the pointer - to the value which passed (if unspecified) */ -void gf_svg_attributes_resolve_unspecified(GF_FieldInfo *in, GF_FieldInfo *p, GF_FieldInfo *t) -{ - if (in->fieldType == 0) { - if (p->fieldType == SVG_Transform_datatype) { - /* if the input value is not specified, and the presentation value is of type Transform, - then we should use the default identity transform instead of the presentation value */ - *in = *t; - } else { - *in = *p; - } - } -} - -/* Replaces the pointer to the attribute value with the pointer - to the value which is inherited (if inherited) */ -void gf_svg_attributes_resolve_inherit(GF_FieldInfo *in, GF_FieldInfo *prop) -{ - if (gf_svg_is_inherit(in)) *in = *prop; -} - -/* Replaces the pointer to the attribute value with the pointer - to the value of the color attribute (if the current value is set to currentColor) */ -void gf_svg_attributes_resolve_currentColor(GF_FieldInfo *in, GF_FieldInfo *current_color) -{ - if ((in->fieldType == SVG_Paint_datatype) && gf_svg_is_current_color(in)) { - *in = *current_color; - } -} - -/************************************************************************************** - * The main function doing evaluation of the animation is: gf_smil_anim_evaluate * - * Depending on the timing status of the animation it calls: * - * - gf_smil_anim_animate * - * - gf_smil_anim_animate_with_fraction * - * - gf_smil_anim_freeze * - * - gf_smil_anim_remove * - * * - * The gf_smil_anim_animate consists in * - * - interpolating using gf_smil_anim_compute_interpolation_value * - * - accumulating using gf_smil_anim_apply_accumulate * - * - applying additive behavior * - * * - * Depending on the animation attributes, one of the following functions is called * - * by the function gf_smil_anim_compute_interpolation_value * - * - gf_smil_anim_set * - * - gf_smil_anim_animate_using_values * - * - gf_smil_anim_animate_from_to * - * - gf_smil_anim_animate_from_by * - * - gf_smil_anim_animate_using_path * - * * - * In most animation methods, the important step in the animation is to resolve * - * the inherit and currentColor values to perform further interpolation, i.e. calls: * - * gf_svg_attributes_resolve_currentColor(&info, &rai->owner->current_color_value); * - * gf_svg_attributes_resolve_inherit(&info, &rai->owner->parent_presentation_value); * - * * - **************************************************************************************/ -static void gf_smil_anim_set(SMIL_Anim_RTI *rai) -{ - GF_FieldInfo to_info; - SMILAnimationAttributesPointers *animp = rai->animp; - - if (!animp->to || !animp->to->type) { - GF_LOG(GF_LOG_ERROR, GF_LOG_SMIL, - ("[SMIL Animation] Animation %s - set element without to attribute\n", - gf_node_get_log_name((GF_Node *)rai->anim_elt))); - return; - } - - if (rai->change_detection_mode) { - /* if the set has been applied, unless next animations are additive we don't need - to apply it again */ - if (rai->previous_coef > 0) rai->interpolated_value_changed = 0; - else rai->interpolated_value_changed = 1; - return; - } else { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying set animation\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), - gf_node_get_log_name((GF_Node *)rai->anim_elt))); - - to_info.fieldType = animp->to->type; - to_info.far_ptr = animp->to->value; - /* we do not need to resolve currentColor values or inherit values here, - because no further interpolation is required for the animation and - because inheritance is applied after animations in the compositor. */ - - gf_svg_attributes_copy(&rai->interpolated_value, &to_info, 0); - rai->previous_coef = FIX_ONE; - } -} - -static void gf_smil_anim_use_keypoints_keytimes(SMIL_Anim_RTI *rai, Fixed normalized_simple_time, - Fixed *interpolation_coefficient, u32 *keyValueIndex) -{ - SMILAnimationAttributesPointers *animp = rai->animp; - u32 keyTimeIndex = 0; - Fixed interval_duration; - - *interpolation_coefficient = normalized_simple_time; - - /* Computing new interpolation coefficient */ - if (rai->key_times_count) { - Fixed keyTimeBefore = 0, keyTimeAfter=0; - for (keyTimeIndex = rai->previous_keytime_index; keyTimeIndex< rai->key_times_count; keyTimeIndex++) { - Fixed *tm1, *t = (Fixed *)gf_list_get(*animp->keyTimes, keyTimeIndex); - if (normalized_simple_time < *t) { - rai->previous_keytime_index = keyTimeIndex; - tm1 = (Fixed *) gf_list_get(*animp->keyTimes, keyTimeIndex-1); - if (tm1) keyTimeBefore = *tm1; - else keyTimeBefore = 0; - keyTimeAfter = *t; - break; - } - } - keyTimeIndex--; - interval_duration = keyTimeAfter - keyTimeBefore; - if (keyValueIndex) *keyValueIndex = keyTimeIndex; - if (interval_duration) - *interpolation_coefficient = gf_divfix(normalized_simple_time - keyTimeBefore, interval_duration); - else - *interpolation_coefficient = FIX_ONE; - if (!rai->change_detection_mode) - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - Using Key Times: index %d, interval duration %.2f, coeff: %.2f\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), - gf_node_get_log_name((GF_Node *)rai->anim_elt), - keyTimeIndex, - interval_duration, - interpolation_coefficient)); - } - - if (rai->anim_elt->sgprivate->tag == TAG_SVG_animateMotion && rai->key_points_count) { - Fixed *p1, *p2; - p1 = (Fixed *)gf_list_get(*animp->keyPoints, keyTimeIndex); - if (animp->calcMode && *animp->calcMode == SMIL_CALCMODE_DISCRETE) { - *interpolation_coefficient = *p1; - } else { - p2 = (Fixed *)gf_list_get(*animp->keyPoints, keyTimeIndex+1); - *interpolation_coefficient = gf_mulfix(FIX_ONE - *interpolation_coefficient, *p1) - + gf_mulfix(*interpolation_coefficient, (p2 ? *p2 : *p1)); - } - if (keyValueIndex) *keyValueIndex = 0; - if (!rai->change_detection_mode) - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - Using Key Points: key Point Index %d, coeff: %.2f\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyTimeIndex, *interpolation_coefficient)); - } -} - -static void gf_smil_anim_animate_using_values(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) -{ - SMILAnimationAttributesPointers *animp = rai->animp; - GF_List *values = NULL; - GF_FieldInfo value_info, value_info_next; - u32 keyValueIndex; - Fixed interpolation_coefficient; - u32 real_calcMode; - - values = animp->values->values; - - memset(&value_info, 0, sizeof(GF_FieldInfo)); - value_info.fieldType = animp->values->type; - value_info_next = value_info; - - real_calcMode = (gf_svg_attribute_is_interpolatable(animp->values->type)? - (animp->calcMode ? *animp->calcMode : SMIL_CALCMODE_LINEAR): - SMIL_CALCMODE_DISCRETE - ); - - if (rai->values_count == 1) { - if (rai->change_detection_mode) { - /* Since we have only 1 value, the previous key index should always be 0, - unless the animation has not started or is reset (-1) */ - if (rai->previous_key_index == 0) rai->interpolated_value_changed = 0; - else rai->interpolated_value_changed = 1; - return; - } else { - value_info.far_ptr = gf_list_get(values, 0); - /* no further interpolation needed - therefore no need to resolve inherit and currentColor */ - gf_svg_attributes_copy(&rai->interpolated_value, &value_info, 0); - rai->previous_key_index = 0; - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - Using values[0] as interpolation value\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); - return; - } - } - - /* Computing new key value index and interpolation coefficient */ - if (!rai->key_times_count) { - if (real_calcMode == SMIL_CALCMODE_DISCRETE) { - if (normalized_simple_time == FIX_ONE) { - keyValueIndex = rai->values_count-1; - interpolation_coefficient = FIX_ONE; - } else { - Fixed tmp = normalized_simple_time*rai->values_count; - Fixed tmp_floor = gf_floor(tmp); - if ((tmp - tmp_floor) == 0 && tmp) { - keyValueIndex = FIX2INT(tmp_floor) - 1; - } else { - keyValueIndex = FIX2INT(tmp_floor); - } - interpolation_coefficient = tmp - INT2FIX(keyValueIndex); - } - } else { - Fixed tmp = normalized_simple_time*(rai->values_count-1); - if (normalized_simple_time == FIX_ONE) { - keyValueIndex = rai->values_count-2; - } else { - keyValueIndex = FIX2INT(gf_floor(tmp)); - } - interpolation_coefficient = tmp - INT2FIX(keyValueIndex); - } - //GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("[SMIL Animation] Time %f - Animation %s - No KeyTimes: key index %d, coeff: %.2f\n", gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyValueIndex, FIX2FLT(interpolation_coefficient))); - } else { - gf_smil_anim_use_keypoints_keytimes(rai, normalized_simple_time, &interpolation_coefficient, &keyValueIndex); - } - - if (rai->change_detection_mode) { - if (real_calcMode == SMIL_CALCMODE_DISCRETE && rai->previous_key_index == (s32)keyValueIndex && rai->previous_coef != -FIX_ONE) { - rai->interpolated_value_changed = 0; - } else if (rai->previous_key_index == (s32)keyValueIndex && rai->previous_coef == interpolation_coefficient) - rai->interpolated_value_changed = 0; - else - rai->interpolated_value_changed = 1; - } else { - rai->previous_key_index = keyValueIndex; - rai->previous_coef = interpolation_coefficient; - - switch (real_calcMode) { - case SMIL_CALCMODE_DISCRETE: - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying discrete animation using values (key value index: %d)\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyValueIndex)); - value_info.far_ptr = gf_list_get(values, keyValueIndex); - /* no further interpolation needed - therefore no need to resolve inherit and currentColor */ - gf_svg_attributes_copy(&rai->interpolated_value, &value_info, 0); - break; - case SMIL_CALCMODE_PACED: - /* TODO: at the moment assume it is linear */ - case SMIL_CALCMODE_SPLINE: - /* TODO: at the moment assume it is linear */ - case SMIL_CALCMODE_LINEAR: - if (keyValueIndex == rai->values_count - 1) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying linear animation using values (setting last key value: %d)\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyValueIndex)); - value_info.far_ptr = gf_list_get(values, rai->values_count - 1); - /* no further interpolation needed - therefore no need to resolve inherit and currentColor */ - gf_svg_attributes_copy(&rai->interpolated_value, &value_info, 0); - } else { - - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying linear animation using values (key value indices: %d, %d / coeff: %f)\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyValueIndex, keyValueIndex+1, interpolation_coefficient)); - value_info.far_ptr = gf_list_get(values, keyValueIndex); - if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(animp->values->type)) { - gf_svg_attributes_resolve_currentColor(&value_info, &rai->owner->current_color_value); - gf_svg_attributes_resolve_inherit(&value_info, &rai->owner->parent_presentation_value); - } - - value_info_next.far_ptr = gf_list_get(values, keyValueIndex+1); - if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(animp->values->type)) { - gf_svg_attributes_resolve_currentColor(&value_info_next, &rai->owner->current_color_value); - gf_svg_attributes_resolve_inherit(&value_info_next, &rai->owner->parent_presentation_value); - } - - gf_svg_attributes_interpolate(&value_info, - &value_info_next, - &rai->interpolated_value, - interpolation_coefficient, 1); - } - break; - } - } -} - -static void gf_smil_anim_animate_from_to(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) -{ - GF_FieldInfo from_info, to_info; - SMILAnimationAttributesPointers *animp = rai->animp; - Fixed interpolation_coefficient; - s32 useFrom = (normalized_simple_time<=FIX_ONE/2); - u32 real_calcMode; - - real_calcMode = (animp->to && gf_svg_attribute_is_interpolatable(animp->to->type)? - (animp->calcMode ? *animp->calcMode : SMIL_CALCMODE_LINEAR): - SMIL_CALCMODE_DISCRETE - ); - - if (rai->change_detection_mode) { - if (rai->previous_coef == normalized_simple_time) - rai->interpolated_value_changed = 0; - else { - if (real_calcMode == SMIL_CALCMODE_DISCRETE && - useFrom == rai->previous_key_index) { - rai->interpolated_value_changed = 0; - } else { - rai->interpolated_value_changed = 1; - } - } - } else { - - if (animp->from) { - from_info.fieldType = animp->from->type; - from_info.far_ptr = animp->from->value; - } else { - from_info.fieldType = 0; - from_info.far_ptr = NULL; - } - - if (rai->is_first_anim) - gf_svg_attributes_resolve_unspecified(&from_info, - &rai->owner->specified_value, - &rai->default_transform_value); - else - gf_svg_attributes_resolve_unspecified(&from_info, - &rai->owner->presentation_value, - &rai->default_transform_value); - - if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(from_info.fieldType)) { - gf_svg_attributes_resolve_currentColor(&from_info, &rai->owner->current_color_value); - gf_svg_attributes_resolve_inherit(&from_info, &rai->owner->parent_presentation_value); - } - if (animp->to) { - to_info.fieldType = animp->to->type; - to_info.far_ptr = animp->to->value; - } else { - to_info.fieldType = 0; - to_info.far_ptr = NULL; - } - - if (rai->is_first_anim) - gf_svg_attributes_resolve_unspecified(&to_info, - &rai->owner->specified_value, - &rai->default_transform_value); - else - gf_svg_attributes_resolve_unspecified(&to_info, - &rai->owner->presentation_value, - &rai->default_transform_value); - - if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(to_info.fieldType)) { - gf_svg_attributes_resolve_currentColor(&to_info, &rai->owner->current_color_value); - gf_svg_attributes_resolve_inherit(&to_info, &rai->owner->parent_presentation_value); - } - - gf_smil_anim_use_keypoints_keytimes(rai, normalized_simple_time, &interpolation_coefficient, NULL); - - rai->previous_coef = interpolation_coefficient; - - switch (real_calcMode) { - case SMIL_CALCMODE_DISCRETE: - { - /* before half of the duration stay at 'from' and then switch to 'to' */ - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying from-to animation (using %s value)\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), (useFrom?"from":"to"))); - gf_svg_attributes_copy(&rai->interpolated_value, (useFrom?&from_info:&to_info), 0); - rai->previous_key_index = useFrom; - } - break; - case SMIL_CALCMODE_SPLINE: - case SMIL_CALCMODE_PACED: - case SMIL_CALCMODE_LINEAR: - default: - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying from-to animation (linear interpolation, using coefficient %f)\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), interpolation_coefficient)); - gf_svg_attributes_interpolate(&from_info, &to_info, &rai->interpolated_value, interpolation_coefficient, 1); - break; - } - } -} - -static void gf_smil_anim_animate_from_by(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) -{ - Fixed from_coef; - GF_FieldInfo from_info, by_info; - SMILAnimationAttributesPointers *animp = rai->animp; - s32 useFrom = (normalized_simple_time<=FIX_ONE/2); - - if (rai->change_detection_mode) { - if (rai->previous_coef == normalized_simple_time) - rai->interpolated_value_changed = 0; - else { - if (animp->calcMode && - *animp->calcMode == SMIL_CALCMODE_DISCRETE && - useFrom == rai->previous_key_index) { - rai->interpolated_value_changed = 0; - } else { - rai->interpolated_value_changed = 1; - } - } - } else { - rai->previous_coef = normalized_simple_time; - - if (animp->from) { - from_info.fieldType = animp->from->type; - from_info.far_ptr = animp->from->value; - from_coef = FIX_ONE; - } else { - from_info.fieldType = 0; - from_info.far_ptr = NULL; - /* this is a by animation only, then, it is always additive, - we don't need the from value*/ - from_coef = 0; - } - - if (rai->is_first_anim) - gf_svg_attributes_resolve_unspecified(&from_info, - &rai->owner->specified_value, - &rai->default_transform_value); - else - gf_svg_attributes_resolve_unspecified(&from_info, - &rai->owner->presentation_value, - &rai->default_transform_value); - - if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(from_info.fieldType)) { - gf_svg_attributes_resolve_currentColor(&from_info, &rai->owner->current_color_value); - gf_svg_attributes_resolve_inherit(&from_info, &rai->owner->parent_presentation_value); - } - - if (animp->by) { - by_info.fieldType = animp->by->type; - by_info.far_ptr = animp->by->value; - } else { - by_info.fieldType = 0; - by_info.far_ptr = NULL; - } - - if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(from_info.fieldType)) { - gf_svg_attributes_resolve_currentColor(&by_info, &rai->owner->current_color_value); - gf_svg_attributes_resolve_inherit(&by_info, &rai->owner->parent_presentation_value); - } - - switch ((animp->calcMode ? *animp->calcMode : SMIL_CALCMODE_LINEAR)) { - case SMIL_CALCMODE_DISCRETE: - { - /* before half of the duration stay at 'from' and then switch to 'to' */ - if (useFrom) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying from-by animation (setting from)", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); - gf_svg_attributes_muladd(from_coef, &from_info, 0, &by_info, &rai->interpolated_value, 0); - } else { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying from-by animation (setting from+by)", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); - gf_svg_attributes_muladd(from_coef, &from_info, FIX_ONE, &by_info, &rai->interpolated_value, 0); - } - rai->previous_key_index = useFrom; - } - break; - case SMIL_CALCMODE_SPLINE: - case SMIL_CALCMODE_PACED: - case SMIL_CALCMODE_LINEAR: - default: - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying from-by animation (linear interpolation between from and from+by, coef: %f)\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), normalized_simple_time)); - gf_svg_attributes_muladd(from_coef, &from_info, normalized_simple_time, &by_info, &rai->interpolated_value, 0); - break; - } - } -} - -static void gf_svg_compute_path_anim(SMIL_Anim_RTI *rai, GF_Matrix2D *m, Fixed normalized_simple_time) -{ - Fixed offset; - offset = gf_mulfix(normalized_simple_time, rai->length); - gf_mx2d_init(*m); - - gf_path_iterator_get_transform(rai->path_iterator, offset, 1, m, 1, 0); - //GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("offset: %f, position: (%f, %f)", offset, ((GF_Matrix2D *)rai->interpolated_value.far_ptr)->m[2], ((GF_Matrix2D *)rai->interpolated_value.far_ptr)->m[5])); - switch (rai->rotate) { - case SVG_NUMBER_AUTO: - break; - case SVG_NUMBER_AUTO_REVERSE: - gf_mx2d_add_rotation(m, m->m[2], m->m[5], GF_PI); - break; - default: - m->m[0] = FIX_ONE; - m->m[1] = 0; - m->m[3] = 0; - m->m[4] = FIX_ONE; - } -} - -static void gf_smil_anim_animate_using_path(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) -{ - Fixed interpolation_coefficient; - - gf_smil_anim_use_keypoints_keytimes(rai, normalized_simple_time, &interpolation_coefficient, NULL); - - if (rai->change_detection_mode) { - if (rai->previous_coef == interpolation_coefficient) - rai->interpolated_value_changed = 0; - else { - rai->interpolated_value_changed = 1; - } - } else { - rai->previous_coef = interpolation_coefficient; - - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying path animation (coef: %f)\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), normalized_simple_time)); - - gf_svg_compute_path_anim(rai, (GF_Matrix2D*)rai->interpolated_value.far_ptr, interpolation_coefficient); - } -} - -static void gf_smil_anim_compute_interpolation_value(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) -{ - SMILAnimationAttributesPointers *animp = rai->animp; - - if (rai->path) { - gf_smil_anim_animate_using_path(rai, normalized_simple_time); - } else if (rai->anim_elt->sgprivate->tag == TAG_SVG_set) { - gf_smil_anim_set(rai); - } else if (rai->values_count) { - /* Ignore 'from'/'to'/'by'*/ - gf_smil_anim_animate_using_values(rai, normalized_simple_time); - } else if ((animp->by && animp->by->type) && (!animp->to || animp->to->type == 0)) { - /* 'to' is not specified but 'by' is, so this is a 'by' animation or a 'from'-'by' animation */ - gf_smil_anim_animate_from_by(rai, normalized_simple_time); - } else { - /* Ignore 'by' if specified */ - gf_smil_anim_animate_from_to(rai, normalized_simple_time); - } - -#ifndef GPAC_DISABLE_LOG - if (0 && (gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { - char *str; - gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); - str = gf_svg_dump_attribute(rai->anim_elt, &rai->interpolated_value); - - gf_log("[SMIL Animation] Time %f - Animation %s - Interpolation value changed for attribute %s, new value: %s \n", - gf_node_get_scene_time(rai->anim_elt), gf_node_get_log_name(rai->anim_elt), - gf_svg_get_attribute_name(rai->anim_elt, rai->owner->presentation_value.fieldIndex), str); - - if (str) gf_free(str); - } -#endif -} - -void gf_smil_anim_set_anim_runtime_in_timing(GF_Node *n) -{ - u32 i, j; - SVGTimedAnimBaseElement *timed_elt = NULL; - SMIL_Timing_RTI *rti = NULL; - GF_Node *target = NULL; - - if (!n) return; - timed_elt = (SVGTimedAnimBaseElement *)n; - - if (!gf_svg_is_animation_tag(n->sgprivate->tag)) return; - - target = timed_elt->xlinkp->href->target; - if (!target) return; - - if (timed_elt->timingp) rti = timed_elt->timingp->runtime; - if (!rti) return; - - rti->rai = NULL; - - for (i = 0; i < gf_node_animation_count(target); i++) { - SMIL_Anim_RTI *rai_tmp; - SMIL_AttributeAnimations *aa = (SMIL_AttributeAnimations *)gf_node_animation_get(target, i); - j=0; - while ((rai_tmp = (SMIL_Anim_RTI *)gf_list_enum(aa->anims, &j))) { - if (rai_tmp->timingp->runtime == rti) { - rti->rai = rai_tmp; - return; - } - } - } -} - -static void gf_smil_anim_get_last_specified_value(SMIL_Anim_RTI *rai) -{ - SMILAnimationAttributesPointers *animp = rai->animp; - - if (!animp) return; - - if (rai->path) { - if (!rai->last_specified_value.far_ptr) rai->last_specified_value.far_ptr = gf_malloc(sizeof(GF_Matrix2D)); - gf_svg_compute_path_anim(rai, rai->last_specified_value.far_ptr, FIX_ONE); - return; - } else if (rai->anim_elt->sgprivate->tag == TAG_SVG_set) { - if (animp->to) { - rai->last_specified_value.fieldType = animp->to->type; - rai->last_specified_value.far_ptr = animp->to->value; - } else { - /* TODO ??? */ - GF_LOG(GF_LOG_ERROR, GF_LOG_SMIL, - ("[SMIL Animation] Animation %s - set element without to attribute\n", - gf_node_get_log_name((GF_Node *)rai->anim_elt))); - } - return; - } - - if (rai->values_count) { - /* Ignore from/to/by*/ - rai->last_specified_value.fieldType = animp->values->type; - rai->last_specified_value.far_ptr = gf_list_last(animp->values->values); - } else if ((animp->by && animp->by->type) && (!animp->to || animp->to->type == 0)) { - rai->last_specified_value.fieldType = animp->by->type; - rai->last_specified_value.far_ptr = animp->by->value; - } else if (animp->to) { - rai->last_specified_value.fieldType = animp->to->type; - rai->last_specified_value.far_ptr = animp->to->value; - } - if (gf_svg_is_inherit(&rai->last_specified_value)) { - rai->last_specified_value.fieldType = rai->owner->presentation_value.fieldType; - rai->last_specified_value.far_ptr = rai->owner->presentation_value.far_ptr; - } - if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(rai->last_specified_value.fieldType)) { - gf_svg_attributes_resolve_currentColor(&rai->last_specified_value, &rai->owner->current_color_value); - gf_svg_attributes_resolve_inherit(&rai->last_specified_value, &rai->owner->parent_presentation_value); - } -} - -/* if the animation behavior is accumulative and this is not the first iteration, - then we modify the interpolation value as follows: - interpolation value += last specified value * number of iterations completed */ -static void gf_smil_anim_apply_accumulate(SMIL_Anim_RTI *rai) -{ - u32 nb_iterations; - - SMILAnimationAttributesPointers *animp = rai->animp; - SMILTimingAttributesPointers *timingp = rai->timingp; - - nb_iterations = (timingp->runtime->current_interval ? timingp->runtime->current_interval->nb_iterations : 1); - - if (rai->change_detection_mode) { - if ((animp->accumulate && *animp->accumulate == SMIL_ACCUMULATE_SUM) - && nb_iterations > 0 - && rai->previous_iteration != (s32) nb_iterations) { - /* if we actually do accumulation and the number of iteration is different, - then we force the result as changed regardless of the result of the interpolation - (TODO: check if this need to be improved)*/ - rai->interpolated_value_changed = 1; - } else { - /* if we don't accumulate we leave the value of interpolated_value_changed unchanged */ - } - } else { - if (nb_iterations > 0 && rai->previous_iteration != (s32) nb_iterations) { - rai->previous_iteration = nb_iterations; - } - - if ((animp->accumulate && *animp->accumulate == SMIL_ACCUMULATE_SUM) && nb_iterations > 0) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying accumulation (iteration #%d)\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), nb_iterations)); - - gf_svg_attributes_muladd(FIX_ONE, &rai->interpolated_value, - INT2FIX(nb_iterations), &rai->last_specified_value, - &rai->interpolated_value, 1); - - if ((animp->from) && animp->by && (rai->last_specified_value.far_ptr == animp->by->value)) { - /* this is a from-by animation, the last specified value is not the 'by' value but actually 'from'+'by', - we need to add nb_iterations times from to the interpolated_value - see (animate-elem-210-t.svg (upper two circles in the mid column, after 9s/14s */ - GF_FieldInfo from_info; - from_info.fieldType = rai->animp->from->type; - from_info.far_ptr = rai->animp->from->value; - gf_svg_attributes_muladd(FIX_ONE, &rai->interpolated_value, - INT2FIX(nb_iterations), &from_info, - &rai->interpolated_value, 1); - } - } - } -} - -static void gf_smil_apply_additive(SMIL_Anim_RTI *rai) -{ - SMILAnimationAttributesPointers *animp = rai->animp; - if (rai->change_detection_mode) return; - else { - /* Apply additive behavior if required - PV = (additive == sum ? PV + animp->IV : animp->IV); */ - if (animp->additive && *animp->additive == SMIL_ADDITIVE_SUM) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying additive behavior\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); - - gf_svg_attributes_add((rai->is_first_anim ? &rai->owner->specified_value : &rai->owner->presentation_value), - &rai->interpolated_value, - &rai->owner->presentation_value, - 1); - -#ifndef GPAC_DISABLE_LOG - if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { - char *str; - gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); - str = gf_svg_dump_attribute((GF_Node*)rai->anim_elt, &rai->owner->presentation_value); - gf_log("[SMIL Animation] Time %f - Animation %s - Presentation value changed for attribute %s, new value: %s\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node*)rai->anim_elt), - gf_svg_get_attribute_name((GF_Node*)rai->anim_elt, rai->owner->presentation_value.fieldIndex), str); - - if (str) gf_free(str); - } -#endif - - } else { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying non-additive behavior\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); - - /* FIXME: if we switch pointers to avoid copying values, - we need to modify the address in the DOM node as well, - we also need to take care about change detections. Not easy!! - - void *tmp = rai->owner->presentation_value.far_ptr; - rai->owner->presentation_value.far_ptr = rai->interpolated_value.far_ptr; - rai->interpolated_value.far_ptr = tmp; - */ - - gf_svg_attributes_copy(&rai->owner->presentation_value, &rai->interpolated_value, 1); -#ifndef GPAC_DISABLE_LOG - if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { - char *str; - gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); - str = gf_svg_dump_attribute((GF_Node*)rai->anim_elt, &rai->owner->presentation_value); - - gf_log("[SMIL Animation] Time %f - Animation %s - Presentation value changed for attribute %s, new value: %s\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node*)rai->anim_elt), - gf_svg_get_attribute_name((GF_Node*)rai->anim_elt, rai->owner->presentation_value.fieldIndex), str); - - if (str) gf_free(str); - } -#endif - } - } -} - -static void gf_smil_anim_animate(SMIL_Timing_RTI *rti, Fixed normalized_simple_time) -{ - SMIL_Anim_RTI *rai = rti->rai; - SMILAnimationAttributesPointers *animp = rai->animp; - - if (!rai || !animp) return; - - gf_smil_anim_compute_interpolation_value(rai, normalized_simple_time); - gf_smil_anim_apply_accumulate(rai); - gf_smil_apply_additive(rai); -} - -static void gf_smil_anim_animate_with_fraction(SMIL_Timing_RTI *rti, Fixed normalized_simple_time) -{ - gf_smil_anim_animate(rti, rti->fraction); - rti->evaluate_status = SMIL_TIMING_EVAL_NONE; -} - -void gf_smil_anim_reset_variables(SMIL_Anim_RTI *rai) -{ - if (!rai) return; - /* we reset all the animation parameters to force computation of next interpolation value - when the animation restarts */ - rai->interpolated_value_changed = 0; - rai->previous_key_index = -1; - rai->previous_coef = -FIX_ONE; - rai->previous_iteration = -1; - rai->previous_keytime_index = 0; - rai->anim_done = 0; -} - -/* copy/paste of the animate function - TODO: check if computations of interpolation value can be avoided. -*/ -static void gf_smil_anim_freeze(SMIL_Timing_RTI *rti, Fixed normalized_simple_time) -{ - SMIL_Anim_RTI *rai = rti->rai; - SMILAnimationAttributesPointers *animp = rai->animp; - - if (!rai || !animp) return; - - if (rai->change_detection_mode) { - if (rai->anim_done == 0) - rai->interpolated_value_changed = 1; - else - rai->interpolated_value_changed = 0; - } else { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying freeze behavior\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); - - gf_smil_anim_compute_interpolation_value(rai, normalized_simple_time); - gf_smil_anim_apply_accumulate(rai); - gf_smil_apply_additive(rai); - rai->anim_done = 1; - } -} - -static void gf_smil_anim_remove(SMIL_Timing_RTI *rti, Fixed normalized_simple_time) -{ - SMIL_Anim_RTI *rai = rti->rai; - if (!rai) return; - - if (rai->change_detection_mode) { - if (rai->anim_done == 0) - rai->interpolated_value_changed = 1; - else - rai->interpolated_value_changed = 0; - } else { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying remove behavior\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); - - /* TODO: see if we can avoid this copy by switching pointers */ - gf_svg_attributes_copy(&rai->owner->presentation_value, &rai->owner->specified_value, 0); - /* TODO: check if we need to apply additive behavior even in fill='remove' - maybe (see animate-elem-211-t.svg) */ - - rai->anim_done = 1; - -#ifndef GPAC_DISABLE_LOG - if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { - char *str; - gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); - str = gf_svg_dump_attribute((GF_Node*)rai->anim_elt, &rai->owner->presentation_value); - - gf_log("[SMIL Animation] Time %f - Animation %s - Presentation value changed for attribute %s, new value: %s\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node*)rai->anim_elt), - gf_svg_get_attribute_name((GF_Node*)rai->anim_elt, rai->owner->presentation_value.fieldIndex), str); - if (str) gf_free(str); - } -#endif - - } -} - -static void gf_smil_anim_evaluate(SMIL_Timing_RTI *rti, Fixed normalized_simple_time, u32 state) -{ - SMIL_Anim_RTI *rai = rti->rai; - switch (state) { - case SMIL_TIMING_EVAL_REPEAT: - /* we are starting a new cycle of animation, therefore we need to reset the previous state variables - like previous_keytime_index ... */ - gf_smil_anim_reset_variables(rai); - case SMIL_TIMING_EVAL_UPDATE: - gf_smil_anim_animate(rti, normalized_simple_time); - break; - case SMIL_TIMING_EVAL_FREEZE: - gf_smil_anim_freeze(rti, normalized_simple_time); - break; - case SMIL_TIMING_EVAL_REMOVE: - gf_smil_anim_remove(rti, normalized_simple_time); - break; - case SMIL_TIMING_EVAL_FRACTION: - gf_smil_anim_animate_with_fraction(rti, normalized_simple_time); - break; -/* - discard should be done before in smil_notify_time - case SMIL_TIMING_EVAL_DISCARD: - break; -*/ - } -} -/************************************************************************************** - **************************************************************************************/ - -GF_EXPORT -void gf_svg_apply_animations(GF_Node *node, SVGPropertiesPointers *render_svg_props) -{ - u32 count_all, i; -#ifndef GPAC_DISABLE_LOG - u32 time=0; - u32 active_anim; - - if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_RTI)) { - time = gf_sys_clock(); - } -#endif - - /* Perform all the animations on this node */ - count_all = gf_node_animation_count(node); - for (i = 0; i < count_all; i++) { - GF_FieldInfo info; - s32 j; - u32 count; - SMIL_AttributeAnimations *aa; - - - aa = (SMIL_AttributeAnimations *)gf_node_animation_get(node, i); - count = gf_list_count(aa->anims); - if (!count) continue; - - aa->presentation_value_changed = 0; - - if (aa->is_property) { - /* Storing the pointer to the parent presentation value, - i.e. the presentation value produced at the parent level in the tree */ - aa->parent_presentation_value = aa->presentation_value; - aa->parent_presentation_value.far_ptr = - gf_svg_get_property_pointer((SVG_Element *)node, aa->orig_dom_ptr, render_svg_props); - - /* Storing also the pointer to the presentation value of the color property - (special handling of the keyword 'currentColor' if used in animation values) */ - gf_node_get_attribute_by_tag(node, TAG_SVG_ATT_color, 1, 1, &info); - aa->current_color_value.far_ptr = info.far_ptr; - } - - /* We start with the last animation (TODO in the execution order), then scan in the reverse order - up to the first animation which is not additive, to determine if the presentation value will change - We evaluate each animation, but only in the 'change_detection_mode' */ - for (j = count-1; j >= 0; j--) { - SMIL_Anim_RTI *rai = (SMIL_Anim_RTI *)gf_list_get(aa->anims, j); - SMIL_Timing_RTI *rti = rai->timingp->runtime; - - rai->interpolated_value_changed = 0; - - /* The evaluate_status has been updated when notifying the new scene time to this animation, - i.e. before the scene tree traversal */ - if (rti->evaluate_status) { - rai->change_detection_mode = 1; - rti->evaluate(rti, rti->normalized_simple_time, rti->evaluate_status); - aa->presentation_value_changed += rai->interpolated_value_changed; - if (!rai->animp->additive || *rai->animp->additive == SMIL_ADDITIVE_REPLACE) { - /* we don't need to check previous animations since this one will overwrite it */ - j--; - break; - } - } - } - - active_anim = 0; - if (aa->presentation_value_changed) { - /* If the result of all the combined animations will produce a different result compared to the previous frame, - we start in the forward order from the j were the previous step stopped (i.e. the first anim in replace mode) - and evaluate each animation, in the computation mode (change_detection_mode = 0)*/ - for (j++; j<(s32)count; j++) { - SMIL_Anim_RTI *rai = (SMIL_Anim_RTI *)gf_list_get(aa->anims, j); - SMIL_Timing_RTI *rti = rai->timingp->runtime; - - if (j == 0) rai->is_first_anim = 1; - else rai->is_first_anim = 0; - - if (rti->evaluate_status) { - rai->change_detection_mode = 0; - rti->evaluate(rti, rti->normalized_simple_time, rti->evaluate_status); - active_anim++; - } - } - } - -/* DEBUG: uncomment this line to remove animation effect, and keep animation computation */ -// gf_svg_attributes_copy(&aa->presentation_value, &aa->specified_value, 0); - -#ifndef GPAC_DISABLE_LOG - if (aa->presentation_value_changed) { - if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { - char *str; - gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); - str = gf_svg_dump_attribute(node, &aa->presentation_value); - - gf_log("[SMIL Animation] Time %f - Element %s - Presentation value changed for attribute %s, new value: %s - dirty flags %x\n", - gf_node_get_scene_time(node), gf_node_get_log_name(node), - gf_svg_get_attribute_name(node, aa->presentation_value.fieldIndex), str, aa->dirty_flags); - - if (str) gf_free(str); - } - } -#endif - - /* we only set dirty flags when a real flag is set to avoid unnecessary computation - for example, it is not necessary to set it when the anim is an animateTransform - since there is no associated flag */ - if (aa->dirty_flags) { - if (aa->presentation_value_changed) { - gf_node_dirty_set(node, aa->dirty_flags, aa->dirty_parents); - } else { - /* WARNING - This does not work for use elements because apply_animations may be called several times */ - if (active_anim) gf_node_dirty_clear(node, aa->dirty_flags); - } - } - } - -#ifndef GPAC_DISABLE_LOG - if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_RTI)) { - time_spent_in_anim += gf_sys_clock() - time; - } -#endif -} - - - -void gf_smil_anim_init_runtime_info(GF_Node *e) -{ - u32 i; - GF_FieldInfo target_attribute; - SMIL_AttributeAnimations *aa = NULL; - SMIL_Anim_RTI *rai; - XLinkAttributesPointers *xlinkp = NULL; - SMILAnimationAttributesPointers *animp = NULL; - SMILTimingAttributesPointers *timingp = NULL; - GF_Node *target = NULL; - - if (!e) return; - - /* Filling animation structures to be independent of the SVG Element structure */ - animp = ((SVGTimedAnimBaseElement *)e)->animp; - timingp = ((SVGTimedAnimBaseElement *)e)->timingp; - xlinkp = ((SVGTimedAnimBaseElement *)e)->xlinkp; - - target = xlinkp->href->target; - - memset(&target_attribute, 0, sizeof(GF_FieldInfo)); - if (animp->attributeName && (animp->attributeName->name || animp->attributeName->tag)) { - /* Filling the target_attribute structure with info on the animated attribute (type, pointer to data, ...) - NOTE: in the mode Dynamic Allocation of Attributes, this means that the animated - attribute is created with a default value, if it was not specified on the target element */ - if (animp->attributeName->tag) { - gf_node_get_attribute_by_tag(target, animp->attributeName->tag, 1, 1, &target_attribute); - } else { - gf_node_get_field_by_name(target, animp->attributeName->name, &target_attribute); - } - } else { - /* All animation elements should have a target attribute except for animateMotion - cf http://www.w3.org/mid/u403c21ajf1sjqtk58g0g38eaep9f9g2ss@hive.bjoern.hoehrmann.de - "For animateMotion, the attributeName is implied and cannot be specified; - animateTransform requires specification of the attribute name and any attribute that is - a transform-like attribute can be a target, e.g. gradientTransform."*/ - - switch (e->sgprivate->tag) { - case TAG_SVG_animateMotion: - /* Explicit creation of the pseudo 'motionTransform' attribute since it cannot be specified */ - gf_node_get_attribute_by_tag(target, TAG_SVG_ATT_motionTransform, 1, 0, &target_attribute); - gf_mx2d_init(*(GF_Matrix2D *)target_attribute.far_ptr); - break; - default: - GF_LOG(GF_LOG_WARNING, GF_LOG_SMIL, - ("[SMIL Animation] Missing attributeName attribute on element %s\n", - gf_node_get_log_name((GF_Node*)e) )); - return; - } - } - - if (animp->attributeType && *animp->attributeType == SMIL_ATTRIBUTETYPE_CSS) { - /* see example animate-elem-219-t.svg from the SVG test suite, upper row */ - if (!gf_svg_is_property(target, &target_attribute)) { - GF_LOG(GF_LOG_WARNING, GF_LOG_SMIL, - ("[SMIL Animation] Using CSS attributeType for an animation on an attribute which is not a property %s\n", - gf_node_get_log_name((GF_Node*)e) )); - return; - } - } - - /* Creation and setup of the runtime structure for animation */ - GF_SAFEALLOC(rai, SMIL_Anim_RTI) - - rai->anim_elt = e; - rai->animp = animp; - rai->timingp = timingp; - rai->xlinkp = xlinkp; - - gf_mx2d_init(rai->identity); - rai->default_transform_value.far_ptr = &rai->identity; - rai->default_transform_value.fieldType = SVG_Transform_datatype; - - /* the interpolated value has the same type as the target attribute, - but we need to create a new pointer to hold its value */ - rai->interpolated_value = target_attribute; - rai->interpolated_value.far_ptr = gf_svg_create_attribute_value(target_attribute.fieldType); - - /* there has not been any interpolation yet, so the previous key index and interpolation coefficient - shall not be set*/ - gf_smil_anim_reset_variables(rai); - - rai->values_count = (animp->values ? gf_list_count(animp->values->values) : 0); - rai->key_times_count = (animp->keyTimes ? gf_list_count(*animp->keyTimes) : 0); - rai->key_points_count = (animp->keyPoints ? gf_list_count(*animp->keyPoints) : 0); - rai->key_splines_count = (animp->keySplines ? gf_list_count(*animp->keySplines) : 0); - - - if (!rai->values_count && /* 'values' attribute not specified */ - (!animp->to || animp->to->type == 0) && /* 'to' attribute not specified */ - (!animp->from || animp->from->type == 0) && /* 'from' attribute not specified */ - (animp->by && animp->by->type != 0)) { /* 'by' attribute specified */ - /* if this is a 'by' animation without from the animation is defined to be additive - see http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#AnimationNS-FromToBy - we override the additive attribute */ - if (!animp->additive) { - /* this case can only happen with dynamic allocation of attributes */ - GF_FieldInfo info; - gf_node_get_attribute_by_tag(e, TAG_SVG_ATT_additive, 1, 0, &info); - animp->additive = info.far_ptr; - } - if (*animp->additive == SMIL_ADDITIVE_REPLACE) { - GF_LOG(GF_LOG_WARNING, GF_LOG_SMIL, ("[SMIL Animation] Warning: by-animations cannot use additive=\"replace\"\n")); - } - *animp->additive = SMIL_ADDITIVE_SUM; - } - - /*TODO - http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#animationNS-ToAnimation - To animation defines its own kind of additive semantics, so the additive attribute is ignored. - */ - - /*TODO - http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#animationNS-ToAnimation - Because to animation is defined in terms of absolute values of the target attribute, - cumulative animation is not defined: - */ - - /* TODO - http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#animationNS-setElement - The set element is non-additive. The additive and accumulate attributes are not allowed, - and will be ignored if specified. - */ - - /* For animateMotion, we need to retrieve the value of the rotate attribute, retrieve the path either - from the 'path' attribute or from the 'mpath' element, and then initialize the path iterator*/ - if (e->sgprivate->tag == TAG_SVG_animateMotion) { - GF_Path *the_path = NULL; - GF_ChildNodeItem *child = NULL; - - GF_FieldInfo info; - if (gf_node_get_attribute_by_tag(e, TAG_SVG_ATT_rotate, 0, 0, &info) == GF_OK) { - rai->rotate = ((SVG_Rotate *)info.far_ptr)->type; - } else { - rai->rotate = SVG_NUMBER_VALUE; - } - if (gf_node_get_attribute_by_tag(e, TAG_SVG_ATT_path, 0, 0, &info) == GF_OK) { - the_path = ((SVG_PathData *)info.far_ptr); - } - child = ((SVG_Element *)e)->children; - - if ((!animp->to || animp->to->type == 0) && - (!animp->by || animp->by->type == 0) && - (!animp->values || animp->values->type == 0)) { -#if USE_GF_PATH - if (!gf_path_is_empty(the_path)) { - rai->path = the_path; - rai->path_iterator = gf_path_iterator_new(rai->path); - rai->length = gf_path_iterator_get_length(rai->path_iterator); - } -#else - rai->path = gf_path_new(); - if (gf_list_count(the_path->points)) { - gf_svg_path_build(rai->path, the_path->commands, the_path->points); - rai->path_iterator = gf_path_iterator_new(rai->path); - rai->length = gf_path_iterator_get_length(rai->path_iterator); - } -#endif - else { - while (child) { - GF_Node *used_path = NULL; - u32 child_tag = gf_node_get_tag(child->node); - if (child_tag == TAG_SVG_mpath) { - GF_FieldInfo info; - if (gf_node_get_attribute_by_tag(child->node, TAG_XLINK_ATT_href, 0, 0, &info) == GF_OK) { - XMLRI *iri = (XMLRI *)info.far_ptr; - if (iri->target) used_path = iri->target; - else if (iri->string) used_path = - (GF_Node *)gf_sg_find_node_by_name(gf_node_get_graph(child->node), iri->string); - if (used_path && gf_node_get_tag(used_path) == TAG_SVG_path) { - gf_node_get_attribute_by_tag(used_path, TAG_SVG_ATT_d, 1, 0, &info); -#if USE_GF_PATH - rai->path = (SVG_PathData *)info.far_ptr; -#else - gf_svg_path_build(rai->path, - ((SVG_PathData *)info.far_ptr)->commands, - ((SVG_PathData *)info.far_ptr)->points); -#endif - rai->path_iterator = gf_path_iterator_new(rai->path); - rai->length = gf_path_iterator_get_length(rai->path_iterator); - } - } - break; - } - child = child->next; - } - } - } - } - - /* for all animations, check if there is already one animation on this attribute, - if yes, get the list and append the new animation runtime info - if no, create a list and add the new animation runtime info. */ - for (i = 0; i < gf_node_animation_count(target); i++) { - aa = (SMIL_AttributeAnimations *)gf_node_animation_get(target, i); - if (aa->presentation_value.fieldIndex == target_attribute.fieldIndex) { - gf_list_add(aa->anims, rai); - break; - } - aa = NULL; - } - if (!aa) { - GF_SAFEALLOC(aa, SMIL_AttributeAnimations) - - /* We determine if the animated attribute is a property since this changes quite a lot the animation model */ - aa->is_property = gf_svg_is_property(target, &target_attribute); - aa->current_color_value.fieldType = SVG_Paint_datatype; - - /* We copy (one copy for all animations on the same attribute) the DOM specified - value before any animation starts (because the animation will override it), - we also save the initial memory address of the specified value (orig_dom_ptr) - for inheritance hack */ - aa->specified_value = target_attribute; - aa->orig_dom_ptr = aa->specified_value.far_ptr; - aa->specified_value.far_ptr = gf_svg_create_attribute_value(target_attribute.fieldType); - gf_svg_attributes_copy(&aa->specified_value, &target_attribute, 0); - - /* Now, the initial memory address of the specified value holds the presentation value, - and the presentation value is initialized */ - aa->presentation_value = target_attribute; - - aa->anims = gf_list_new(); - gf_list_add(aa->anims, rai); - gf_node_animation_add(target, aa); - - /* determine what the rendering will need to do when the animation runs */ - aa->dirty_flags = gf_svg_get_modification_flags((SVG_Element *)target, &target_attribute); - - /* If the animation will result in a change of geometry or of the display property, - this animation will require traversing the tree, we need to inform the parents of the target node */ - aa->dirty_parents = 0; - if (aa->dirty_flags & (GF_SG_SVG_GEOMETRY_DIRTY | GF_SG_SVG_DISPLAY_DIRTY)) aa->dirty_parents = 1; - } - - rai->owner = aa; - gf_smil_anim_get_last_specified_value(rai); - - /* for animation (unlike other timed elements like video), the evaluation (i.e. interpolation) cannot be done - during timing evaluation, because due to inheritance, interpolation can only be computed - during scene tree traversal, therefore we need to postpone evaluation of the timed element */ - timingp->runtime->postpone = 1; - - timingp->runtime->evaluate = gf_smil_anim_evaluate; -} - -void gf_smil_anim_delete_runtime_info(SMIL_Anim_RTI *rai) -{ - gf_svg_delete_attribute_value(rai->interpolated_value.fieldType, - rai->interpolated_value.far_ptr, - rai->anim_elt->sgprivate->scenegraph); - if (rai->path) { - gf_svg_delete_attribute_value(rai->last_specified_value.fieldType, - rai->last_specified_value.far_ptr, - rai->anim_elt->sgprivate->scenegraph); - } -#if USE_GF_PATH -#else - if (rai->path) gf_path_del(rai->path); -#endif - if (rai->path_iterator) gf_path_iterator_del(rai->path_iterator); - gf_free(rai); -} - -void gf_smil_anim_remove_from_target(GF_Node *anim, GF_Node *target) -{ - u32 i, j; - if (!target) return; - for (i = 0; i < gf_node_animation_count((GF_Node *)target); i ++) { - SMIL_Anim_RTI *rai; - SMIL_AttributeAnimations *aa = (SMIL_AttributeAnimations *)gf_node_animation_get((GF_Node *)target, i); - j=0; - while ((rai = (SMIL_Anim_RTI *)gf_list_enum(aa->anims, &j))) { - if ((GF_Node *)rai->anim_elt == anim) { - gf_list_rem(aa->anims, j-1); - gf_smil_anim_delete_runtime_info(rai); - break; - } - } - if (gf_list_count(aa->anims) == 0) { - gf_list_del(aa->anims); - gf_svg_delete_attribute_value(aa->specified_value.fieldType, - aa->specified_value.far_ptr, - target->sgprivate->scenegraph); - aa->presentation_value.far_ptr = aa->orig_dom_ptr; - gf_node_animation_rem((GF_Node *)target, i); - gf_free(aa); - } - } -} - -void gf_smil_anim_delete_animations(GF_Node *e) -{ - u32 i, j; - - for (i = 0; i < gf_node_animation_count(e); i ++) { - SMIL_Anim_RTI *rai; - SMIL_AttributeAnimations *aa = (SMIL_AttributeAnimations *)gf_node_animation_get(e, i); - gf_svg_delete_attribute_value(aa->specified_value.fieldType, - aa->specified_value.far_ptr, - e->sgprivate->scenegraph); - j=0; - while ((rai = (SMIL_Anim_RTI *)gf_list_enum(aa->anims, &j))) { - rai->xlinkp->href->target = NULL; - gf_smil_anim_delete_runtime_info(rai); - } - gf_list_del(aa->anims); - gf_free(aa); - } - gf_node_animation_del(e); -} - -void gf_smil_anim_init_discard(GF_Node *node) -{ - SVGAllAttributes all_atts; - XLinkAttributesPointers *xlinkp = NULL; - SVGTimedAnimBaseElement *e = (SVGTimedAnimBaseElement *)node; - gf_smil_timing_init_runtime_info(node); - - gf_svg_flatten_attributes((SVG_Element *)e, &all_atts); - GF_SAFEALLOC(e->xlinkp, XLinkAttributesPointers); - xlinkp = e->xlinkp; - xlinkp->href = all_atts.xlink_href; - xlinkp->type = all_atts.xlink_type; - - e->timingp->runtime->evaluate_status = SMIL_TIMING_EVAL_DISCARD; -} - -void gf_smil_anim_init_node(GF_Node *node) -{ - XLinkAttributesPointers *xlinkp = NULL; - SMILAnimationAttributesPointers *animp = NULL; - SVGAllAttributes all_atts; - SVGTimedAnimBaseElement *e = (SVGTimedAnimBaseElement *)node; - - gf_svg_flatten_attributes((SVG_Element *)e, &all_atts); - e->xlinkp = gf_malloc(sizeof(XLinkAttributesPointers)); - xlinkp = e->xlinkp; - xlinkp->href = all_atts.xlink_href; - xlinkp->type = all_atts.xlink_type; - - /*perform init of default values*/ - if (!xlinkp->href) { - GF_FieldInfo info; - gf_node_get_attribute_by_tag((GF_Node *)node, TAG_XLINK_ATT_href, 1, 0, &info); - xlinkp->href = info.far_ptr; - xlinkp->href->type = XMLRI_ELEMENTID; - xlinkp->href->target = gf_node_get_parent(node, 0); - } - if (xlinkp->href->type == XMLRI_STRING) { - if (!xlinkp->href->string) { - fprintf(stderr, "Error: IRI not initialized\n"); - return; - } else { - GF_Node *n; - - n = (GF_Node*)gf_sg_find_node_by_name(gf_node_get_graph(node), xlinkp->href->string); - if (n) { - xlinkp->href->type = XMLRI_ELEMENTID; - xlinkp->href->target = n; - gf_node_register_iri(node->sgprivate->scenegraph, xlinkp->href); - } else { - return; - } - } - } - if (!xlinkp->href->target) return; - - // We may not have an attribute name, when using an animateMotion element - if (node->sgprivate->tag != TAG_SVG_animateMotion && !all_atts.attributeName) return; - - if ( (all_atts.to && (all_atts.to->type==0)) - || (all_atts.from && (all_atts.from->type==0)) - || (all_atts.from && (all_atts.from->type==0)) - ) { - GF_FieldInfo info; - if (gf_node_get_attribute_by_name((GF_Node *)xlinkp->href->target, all_atts.attributeName->name, 0, 1, 1, &info)==GF_OK) { - u32 anim_value_type = info.fieldType; - u32 i; - for (i=0; i<3; i++) { - u32 tag = 0; - switch (i) { - case 0: tag=TAG_SVG_ATT_to; break; - case 1: tag=TAG_SVG_ATT_from; break; - case 2: tag=TAG_SVG_ATT_by; break; - } - if (gf_node_get_attribute_by_tag((GF_Node *)node, tag, 0, 0, &info)==GF_OK) { - SMIL_AnimateValue *attval = info.far_ptr; - if (attval->type==0) { - SVG_String *string = attval->value; - attval->value = NULL; - if (string) { - gf_svg_parse_attribute((GF_Node *)node, &info, * string, anim_value_type); - if (* string) gf_free(* string); - gf_free(string); - } - } - } - } - } - } - - e->animp = gf_malloc(sizeof(SMILAnimationAttributesPointers)); - animp = e->animp; - animp->accumulate = all_atts.accumulate; - animp->additive = all_atts.additive; - animp->attributeName = all_atts.attributeName; - animp->attributeType = all_atts.attributeType; - animp->by = all_atts.by; - animp->calcMode = all_atts.calcMode; - animp->from = all_atts.from; - animp->keySplines = all_atts.keySplines; - animp->keyTimes = all_atts.keyTimes; - animp->lsr_enabled = all_atts.lsr_enabled; - animp->to = all_atts.to; - animp->type = all_atts.transform_type; - animp->values = all_atts.values; - if (node->sgprivate->tag == TAG_SVG_animateMotion) { - e->animp->keyPoints = all_atts.keyPoints; - e->animp->origin = all_atts.origin; - e->animp->path = all_atts.path; - e->animp->rotate = all_atts.rotate; - } else { - e->animp->keyPoints = NULL; - e->animp->origin = NULL; - e->animp->path = NULL; - e->animp->rotate = NULL; - } - - - gf_smil_timing_init_runtime_info(node); - gf_smil_anim_init_runtime_info(node); - gf_smil_anim_set_anim_runtime_in_timing(node); -} - - - -#endif /*GPAC_DISABLE_SVG*/ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Cyril Concolato - Jean Le Feuvre + * Copyright (c)2004-200X ENST - All rights reserved + * + * This file is part of GPAC / SVG Scene Graph 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 +#include + +#ifndef GPAC_DISABLE_LOG +u32 time_spent_in_anim = 0; +#endif + +#ifndef GPAC_DISABLE_SVG + + +/************************************************************************************** + * Each GF_Node holds the (SVG/SMIL) animation elements which target itself in a list * + * The following are the generic functions to manipulate this list: * + * - add a new animation to the list, * + * - get an animation from the list, * + * - remove an animation from the list, * + * - count the animations in the list, * + * - delete the list * + **************************************************************************************/ +GF_Err gf_node_animation_add(GF_Node *node, void *animation) +{ + if (!node || !animation) return GF_BAD_PARAM; + if (!node->sgprivate->interact) GF_SAFEALLOC(node->sgprivate->interact, struct _node_interactive_ext); + if (!node->sgprivate->interact->animations) node->sgprivate->interact->animations = gf_list_new(); + return gf_list_add(node->sgprivate->interact->animations, animation); +} + +GF_Err gf_node_animation_del(GF_Node *node) +{ + if (!node || !node->sgprivate->interact || !node->sgprivate->interact->animations) return GF_BAD_PARAM; + gf_list_del(node->sgprivate->interact->animations); + node->sgprivate->interact->animations = NULL; + return GF_OK; +} + +u32 gf_node_animation_count(GF_Node *node) +{ + if (!node || !node->sgprivate->interact|| !node->sgprivate->interact->animations) return 0; + return gf_list_count(node->sgprivate->interact->animations); +} + +void *gf_node_animation_get(GF_Node *node, u32 i) +{ + if (!node || !node->sgprivate->interact || !node->sgprivate->interact->animations) return 0; + return gf_list_get(node->sgprivate->interact->animations, i); +} + +GF_Err gf_node_animation_rem(GF_Node *node, u32 i) +{ + if (!node || !node->sgprivate->interact || !node->sgprivate->interact->animations) return GF_OK; + return gf_list_rem(node->sgprivate->interact->animations, i); +} +/************************************************************************************** + * End of Generic GF_Node animations list * + **************************************************************************************/ + + +/************************************************************************************** + * Helping functions for animation * + **************************************************************************************/ +/* Sets the pointer to the attribute value with the pointer + to the value which passed (if unspecified) */ +void gf_svg_attributes_resolve_unspecified(GF_FieldInfo *in, GF_FieldInfo *p, GF_FieldInfo *t) +{ + if (in->fieldType == 0) { + if (p->fieldType == SVG_Transform_datatype) { + /* if the input value is not specified, and the presentation value is of type Transform, + then we should use the default identity transform instead of the presentation value */ + *in = *t; + } else { + *in = *p; + } + } +} + +/* Replaces the pointer to the attribute value with the pointer + to the value which is inherited (if inherited) */ +void gf_svg_attributes_resolve_inherit(GF_FieldInfo *in, GF_FieldInfo *prop) +{ + if (gf_svg_is_inherit(in)) *in = *prop; +} + +/* Replaces the pointer to the attribute value with the pointer + to the value of the color attribute (if the current value is set to currentColor) */ +void gf_svg_attributes_resolve_currentColor(GF_FieldInfo *in, GF_FieldInfo *current_color) +{ + if ((in->fieldType == SVG_Paint_datatype) && gf_svg_is_current_color(in)) { + *in = *current_color; + } +} + +/************************************************************************************** + * The main function doing evaluation of the animation is: gf_smil_anim_evaluate * + * Depending on the timing status of the animation it calls: * + * - gf_smil_anim_animate * + * - gf_smil_anim_animate_with_fraction * + * - gf_smil_anim_freeze * + * - gf_smil_anim_remove * + * * + * The gf_smil_anim_animate consists in * + * - interpolating using gf_smil_anim_compute_interpolation_value * + * - accumulating using gf_smil_anim_apply_accumulate * + * - applying additive behavior * + * * + * Depending on the animation attributes, one of the following functions is called * + * by the function gf_smil_anim_compute_interpolation_value * + * - gf_smil_anim_set * + * - gf_smil_anim_animate_using_values * + * - gf_smil_anim_animate_from_to * + * - gf_smil_anim_animate_from_by * + * - gf_smil_anim_animate_using_path * + * * + * In most animation methods, the important step in the animation is to resolve * + * the inherit and currentColor values to perform further interpolation, i.e. calls: * + * gf_svg_attributes_resolve_currentColor(&info, &rai->owner->current_color_value); * + * gf_svg_attributes_resolve_inherit(&info, &rai->owner->parent_presentation_value); * + * * + **************************************************************************************/ +static void gf_smil_anim_set(SMIL_Anim_RTI *rai) +{ + GF_FieldInfo to_info; + SMILAnimationAttributesPointers *animp = rai->animp; + + if (!animp->to || !animp->to->type) { + GF_LOG(GF_LOG_ERROR, GF_LOG_SMIL, + ("[SMIL Animation] Animation %s - set element without to attribute\n", + gf_node_get_log_name((GF_Node *)rai->anim_elt))); + return; + } + + if (rai->change_detection_mode) { + /* if the set has been applied, unless next animations are additive we don't need + to apply it again */ + if (rai->previous_coef > 0) rai->interpolated_value_changed = 0; + else rai->interpolated_value_changed = 1; + return; + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying set animation\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), + gf_node_get_log_name((GF_Node *)rai->anim_elt))); + + to_info.fieldType = animp->to->type; + to_info.far_ptr = animp->to->value; + /* we do not need to resolve currentColor values or inherit values here, + because no further interpolation is required for the animation and + because inheritance is applied after animations in the compositor. */ + + gf_svg_attributes_copy(&rai->interpolated_value, &to_info, 0); + rai->previous_coef = FIX_ONE; + } +} + +static void gf_smil_anim_use_keypoints_keytimes(SMIL_Anim_RTI *rai, Fixed normalized_simple_time, + Fixed *interpolation_coefficient, u32 *keyValueIndex) +{ + SMILAnimationAttributesPointers *animp = rai->animp; + u32 keyTimeIndex = 0; + Fixed interval_duration; + + *interpolation_coefficient = normalized_simple_time; + + /* Computing new interpolation coefficient */ + if (rai->key_times_count) { + Fixed keyTimeBefore = 0, keyTimeAfter=0; + for (keyTimeIndex = rai->previous_keytime_index; keyTimeIndex< rai->key_times_count; keyTimeIndex++) { + Fixed *tm1, *t = (Fixed *)gf_list_get(*animp->keyTimes, keyTimeIndex); + if (normalized_simple_time < *t) { + rai->previous_keytime_index = keyTimeIndex; + tm1 = (Fixed *) gf_list_get(*animp->keyTimes, keyTimeIndex-1); + if (tm1) keyTimeBefore = *tm1; + else keyTimeBefore = 0; + keyTimeAfter = *t; + break; + } + } + keyTimeIndex--; + interval_duration = keyTimeAfter - keyTimeBefore; + if (keyValueIndex) *keyValueIndex = keyTimeIndex; + if (interval_duration) + *interpolation_coefficient = gf_divfix(normalized_simple_time - keyTimeBefore, interval_duration); + else + *interpolation_coefficient = FIX_ONE; + if (!rai->change_detection_mode) + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - Using Key Times: index %d, interval duration %.2f, coeff: %.2f\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), + gf_node_get_log_name((GF_Node *)rai->anim_elt), + keyTimeIndex, + interval_duration, + interpolation_coefficient)); + } + + if (rai->anim_elt->sgprivate->tag == TAG_SVG_animateMotion && rai->key_points_count) { + Fixed *p1, *p2; + p1 = (Fixed *)gf_list_get(*animp->keyPoints, keyTimeIndex); + if (animp->calcMode && *animp->calcMode == SMIL_CALCMODE_DISCRETE) { + *interpolation_coefficient = *p1; + } else { + p2 = (Fixed *)gf_list_get(*animp->keyPoints, keyTimeIndex+1); + *interpolation_coefficient = gf_mulfix(FIX_ONE - *interpolation_coefficient, *p1) + + gf_mulfix(*interpolation_coefficient, (p2 ? *p2 : *p1)); + } + if (keyValueIndex) *keyValueIndex = 0; + if (!rai->change_detection_mode) + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - Using Key Points: key Point Index %d, coeff: %.2f\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyTimeIndex, *interpolation_coefficient)); + } +} + +static void gf_smil_anim_animate_using_values(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) +{ + SMILAnimationAttributesPointers *animp = rai->animp; + GF_List *values = NULL; + GF_FieldInfo value_info, value_info_next; + u32 keyValueIndex; + Fixed interpolation_coefficient; + u32 real_calcMode; + + values = animp->values->values; + + memset(&value_info, 0, sizeof(GF_FieldInfo)); + value_info.fieldType = animp->values->type; + value_info_next = value_info; + + real_calcMode = (gf_svg_attribute_is_interpolatable(animp->values->type)? + (animp->calcMode ? *animp->calcMode : SMIL_CALCMODE_LINEAR): + SMIL_CALCMODE_DISCRETE + ); + + if (rai->values_count == 1) { + if (rai->change_detection_mode) { + /* Since we have only 1 value, the previous key index should always be 0, + unless the animation has not started or is reset (-1) */ + if (rai->previous_key_index == 0) rai->interpolated_value_changed = 0; + else rai->interpolated_value_changed = 1; + return; + } else { + value_info.far_ptr = gf_list_get(values, 0); + /* no further interpolation needed + therefore no need to resolve inherit and currentColor */ + gf_svg_attributes_copy(&rai->interpolated_value, &value_info, 0); + rai->previous_key_index = 0; + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - Using values[0] as interpolation value\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); + return; + } + } + + /* Computing new key value index and interpolation coefficient */ + if (!rai->key_times_count) { + if (real_calcMode == SMIL_CALCMODE_DISCRETE) { + if (normalized_simple_time == FIX_ONE) { + keyValueIndex = rai->values_count-1; + interpolation_coefficient = FIX_ONE; + } else { + Fixed tmp = normalized_simple_time*rai->values_count; + Fixed tmp_floor = gf_floor(tmp); + if ((tmp - tmp_floor) == 0 && tmp) { + keyValueIndex = FIX2INT(tmp_floor) - 1; + } else { + keyValueIndex = FIX2INT(tmp_floor); + } + interpolation_coefficient = tmp - INT2FIX(keyValueIndex); + } + } else { + Fixed tmp = normalized_simple_time*(rai->values_count-1); + if (normalized_simple_time == FIX_ONE) { + keyValueIndex = rai->values_count-2; + } else { + keyValueIndex = FIX2INT(gf_floor(tmp)); + } + interpolation_coefficient = tmp - INT2FIX(keyValueIndex); + } + //GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("[SMIL Animation] Time %f - Animation %s - No KeyTimes: key index %d, coeff: %.2f\n", gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyValueIndex, FIX2FLT(interpolation_coefficient))); + } else { + gf_smil_anim_use_keypoints_keytimes(rai, normalized_simple_time, &interpolation_coefficient, &keyValueIndex); + } + + if (rai->change_detection_mode) { + if (real_calcMode == SMIL_CALCMODE_DISCRETE && rai->previous_key_index == (s32)keyValueIndex && rai->previous_coef != -FIX_ONE) { + rai->interpolated_value_changed = 0; + } else if (rai->previous_key_index == (s32)keyValueIndex && rai->previous_coef == interpolation_coefficient) + rai->interpolated_value_changed = 0; + else + rai->interpolated_value_changed = 1; + } else { + rai->previous_key_index = keyValueIndex; + rai->previous_coef = interpolation_coefficient; + + switch (real_calcMode) { + case SMIL_CALCMODE_DISCRETE: + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying discrete animation using values (key value index: %d)\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyValueIndex)); + value_info.far_ptr = gf_list_get(values, keyValueIndex); + /* no further interpolation needed + therefore no need to resolve inherit and currentColor */ + gf_svg_attributes_copy(&rai->interpolated_value, &value_info, 0); + break; + case SMIL_CALCMODE_PACED: + /* TODO: at the moment assume it is linear */ + case SMIL_CALCMODE_SPLINE: + /* TODO: at the moment assume it is linear */ + case SMIL_CALCMODE_LINEAR: + if (keyValueIndex == rai->values_count - 1) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying linear animation using values (setting last key value: %d)\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyValueIndex)); + value_info.far_ptr = gf_list_get(values, rai->values_count - 1); + /* no further interpolation needed + therefore no need to resolve inherit and currentColor */ + gf_svg_attributes_copy(&rai->interpolated_value, &value_info, 0); + } else { + + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying linear animation using values (key value indices: %d, %d / coeff: %f)\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyValueIndex, keyValueIndex+1, interpolation_coefficient)); + value_info.far_ptr = gf_list_get(values, keyValueIndex); + if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(animp->values->type)) { + gf_svg_attributes_resolve_currentColor(&value_info, &rai->owner->current_color_value); + gf_svg_attributes_resolve_inherit(&value_info, &rai->owner->parent_presentation_value); + } + + value_info_next.far_ptr = gf_list_get(values, keyValueIndex+1); + if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(animp->values->type)) { + gf_svg_attributes_resolve_currentColor(&value_info_next, &rai->owner->current_color_value); + gf_svg_attributes_resolve_inherit(&value_info_next, &rai->owner->parent_presentation_value); + } + + gf_svg_attributes_interpolate(&value_info, + &value_info_next, + &rai->interpolated_value, + interpolation_coefficient, 1); + } + break; + } + } +} + +static void gf_smil_anim_animate_from_to(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) +{ + GF_FieldInfo from_info, to_info; + SMILAnimationAttributesPointers *animp = rai->animp; + Fixed interpolation_coefficient; + s32 useFrom = (normalized_simple_time<=FIX_ONE/2); + u32 real_calcMode; + + real_calcMode = (animp->to && gf_svg_attribute_is_interpolatable(animp->to->type)? + (animp->calcMode ? *animp->calcMode : SMIL_CALCMODE_LINEAR): + SMIL_CALCMODE_DISCRETE + ); + + if (rai->change_detection_mode) { + if (rai->previous_coef == normalized_simple_time) + rai->interpolated_value_changed = 0; + else { + if (real_calcMode == SMIL_CALCMODE_DISCRETE && + useFrom == rai->previous_key_index) { + rai->interpolated_value_changed = 0; + } else { + rai->interpolated_value_changed = 1; + } + } + } else { + + if (animp->from) { + from_info.fieldType = animp->from->type; + from_info.far_ptr = animp->from->value; + } else { + from_info.fieldType = 0; + from_info.far_ptr = NULL; + } + + if (rai->is_first_anim) + gf_svg_attributes_resolve_unspecified(&from_info, + &rai->owner->specified_value, + &rai->default_transform_value); + else + gf_svg_attributes_resolve_unspecified(&from_info, + &rai->owner->presentation_value, + &rai->default_transform_value); + + if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(from_info.fieldType)) { + gf_svg_attributes_resolve_currentColor(&from_info, &rai->owner->current_color_value); + gf_svg_attributes_resolve_inherit(&from_info, &rai->owner->parent_presentation_value); + } + if (animp->to) { + to_info.fieldType = animp->to->type; + to_info.far_ptr = animp->to->value; + } else { + to_info.fieldType = 0; + to_info.far_ptr = NULL; + } + + if (rai->is_first_anim) + gf_svg_attributes_resolve_unspecified(&to_info, + &rai->owner->specified_value, + &rai->default_transform_value); + else + gf_svg_attributes_resolve_unspecified(&to_info, + &rai->owner->presentation_value, + &rai->default_transform_value); + + if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(to_info.fieldType)) { + gf_svg_attributes_resolve_currentColor(&to_info, &rai->owner->current_color_value); + gf_svg_attributes_resolve_inherit(&to_info, &rai->owner->parent_presentation_value); + } + + gf_smil_anim_use_keypoints_keytimes(rai, normalized_simple_time, &interpolation_coefficient, NULL); + + rai->previous_coef = interpolation_coefficient; + + switch (real_calcMode) { + case SMIL_CALCMODE_DISCRETE: + { + /* before half of the duration stay at 'from' and then switch to 'to' */ + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying from-to animation (using %s value)\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), (useFrom?"from":"to"))); + gf_svg_attributes_copy(&rai->interpolated_value, (useFrom?&from_info:&to_info), 0); + rai->previous_key_index = useFrom; + } + break; + case SMIL_CALCMODE_SPLINE: + case SMIL_CALCMODE_PACED: + case SMIL_CALCMODE_LINEAR: + default: + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying from-to animation (linear interpolation, using coefficient %f)\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), interpolation_coefficient)); + gf_svg_attributes_interpolate(&from_info, &to_info, &rai->interpolated_value, interpolation_coefficient, 1); + break; + } + } +} + +static void gf_smil_anim_animate_from_by(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) +{ + Fixed from_coef; + GF_FieldInfo from_info, by_info; + SMILAnimationAttributesPointers *animp = rai->animp; + s32 useFrom = (normalized_simple_time<=FIX_ONE/2); + + if (rai->change_detection_mode) { + if (rai->previous_coef == normalized_simple_time) + rai->interpolated_value_changed = 0; + else { + if (animp->calcMode && + *animp->calcMode == SMIL_CALCMODE_DISCRETE && + useFrom == rai->previous_key_index) { + rai->interpolated_value_changed = 0; + } else { + rai->interpolated_value_changed = 1; + } + } + } else { + rai->previous_coef = normalized_simple_time; + + if (animp->from) { + from_info.fieldType = animp->from->type; + from_info.far_ptr = animp->from->value; + from_coef = FIX_ONE; + } else { + from_info.fieldType = 0; + from_info.far_ptr = NULL; + /* this is a by animation only, then, it is always additive, + we don't need the from value*/ + from_coef = 0; + } + + if (rai->is_first_anim) + gf_svg_attributes_resolve_unspecified(&from_info, + &rai->owner->specified_value, + &rai->default_transform_value); + else + gf_svg_attributes_resolve_unspecified(&from_info, + &rai->owner->presentation_value, + &rai->default_transform_value); + + if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(from_info.fieldType)) { + gf_svg_attributes_resolve_currentColor(&from_info, &rai->owner->current_color_value); + gf_svg_attributes_resolve_inherit(&from_info, &rai->owner->parent_presentation_value); + } + + if (animp->by) { + by_info.fieldType = animp->by->type; + by_info.far_ptr = animp->by->value; + } else { + by_info.fieldType = 0; + by_info.far_ptr = NULL; + } + + if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(from_info.fieldType)) { + gf_svg_attributes_resolve_currentColor(&by_info, &rai->owner->current_color_value); + gf_svg_attributes_resolve_inherit(&by_info, &rai->owner->parent_presentation_value); + } + + switch ((animp->calcMode ? *animp->calcMode : SMIL_CALCMODE_LINEAR)) { + case SMIL_CALCMODE_DISCRETE: + { + /* before half of the duration stay at 'from' and then switch to 'to' */ + if (useFrom) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying from-by animation (setting from)", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); + gf_svg_attributes_muladd(from_coef, &from_info, 0, &by_info, &rai->interpolated_value, 0); + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying from-by animation (setting from+by)", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); + gf_svg_attributes_muladd(from_coef, &from_info, FIX_ONE, &by_info, &rai->interpolated_value, 0); + } + rai->previous_key_index = useFrom; + } + break; + case SMIL_CALCMODE_SPLINE: + case SMIL_CALCMODE_PACED: + case SMIL_CALCMODE_LINEAR: + default: + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying from-by animation (linear interpolation between from and from+by, coef: %f)\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), normalized_simple_time)); + gf_svg_attributes_muladd(from_coef, &from_info, normalized_simple_time, &by_info, &rai->interpolated_value, 0); + break; + } + } +} + +static void gf_svg_compute_path_anim(SMIL_Anim_RTI *rai, GF_Matrix2D *m, Fixed normalized_simple_time) +{ + Fixed offset; + offset = gf_mulfix(normalized_simple_time, rai->length); + gf_mx2d_init(*m); + + gf_path_iterator_get_transform(rai->path_iterator, offset, 1, m, 1, 0); + //GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("offset: %f, position: (%f, %f)", offset, ((GF_Matrix2D *)rai->interpolated_value.far_ptr)->m[2], ((GF_Matrix2D *)rai->interpolated_value.far_ptr)->m[5])); + switch (rai->rotate) { + case SVG_NUMBER_AUTO: + break; + case SVG_NUMBER_AUTO_REVERSE: + gf_mx2d_add_rotation(m, m->m[2], m->m[5], GF_PI); + break; + default: + m->m[0] = FIX_ONE; + m->m[1] = 0; + m->m[3] = 0; + m->m[4] = FIX_ONE; + } +} + +static void gf_smil_anim_animate_using_path(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) +{ + Fixed interpolation_coefficient; + + gf_smil_anim_use_keypoints_keytimes(rai, normalized_simple_time, &interpolation_coefficient, NULL); + + if (rai->change_detection_mode) { + if (rai->previous_coef == interpolation_coefficient) + rai->interpolated_value_changed = 0; + else { + rai->interpolated_value_changed = 1; + } + } else { + rai->previous_coef = interpolation_coefficient; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying path animation (coef: %f)\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), normalized_simple_time)); + + gf_svg_compute_path_anim(rai, (GF_Matrix2D*)rai->interpolated_value.far_ptr, interpolation_coefficient); + } +} + +static void gf_smil_anim_compute_interpolation_value(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) +{ + SMILAnimationAttributesPointers *animp = rai->animp; + + if (rai->path) { + gf_smil_anim_animate_using_path(rai, normalized_simple_time); + } else if (rai->anim_elt->sgprivate->tag == TAG_SVG_set) { + gf_smil_anim_set(rai); + } else if (rai->values_count) { + /* Ignore 'from'/'to'/'by'*/ + gf_smil_anim_animate_using_values(rai, normalized_simple_time); + } else if ((animp->by && animp->by->type) && (!animp->to || animp->to->type == 0)) { + /* 'to' is not specified but 'by' is, so this is a 'by' animation or a 'from'-'by' animation */ + gf_smil_anim_animate_from_by(rai, normalized_simple_time); + } else { + /* Ignore 'by' if specified */ + gf_smil_anim_animate_from_to(rai, normalized_simple_time); + } + +#ifndef GPAC_DISABLE_LOG + if (0 && (gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { + char *str; + gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); + str = gf_svg_dump_attribute(rai->anim_elt, &rai->interpolated_value); + + gf_log("[SMIL Animation] Time %f - Animation %s - Interpolation value changed for attribute %s, new value: %s \n", + gf_node_get_scene_time(rai->anim_elt), gf_node_get_log_name(rai->anim_elt), + gf_svg_get_attribute_name(rai->anim_elt, rai->owner->presentation_value.fieldIndex), str); + + if (str) gf_free(str); + } +#endif +} + +void gf_smil_anim_set_anim_runtime_in_timing(GF_Node *n) +{ + u32 i, j; + SVGTimedAnimBaseElement *timed_elt = NULL; + SMIL_Timing_RTI *rti = NULL; + GF_Node *target = NULL; + + if (!n) return; + timed_elt = (SVGTimedAnimBaseElement *)n; + + if (!gf_svg_is_animation_tag(n->sgprivate->tag)) return; + + target = timed_elt->xlinkp->href->target; + if (!target) return; + + if (timed_elt->timingp) rti = timed_elt->timingp->runtime; + if (!rti) return; + + rti->rai = NULL; + + for (i = 0; i < gf_node_animation_count(target); i++) { + SMIL_Anim_RTI *rai_tmp; + SMIL_AttributeAnimations *aa = (SMIL_AttributeAnimations *)gf_node_animation_get(target, i); + j=0; + while ((rai_tmp = (SMIL_Anim_RTI *)gf_list_enum(aa->anims, &j))) { + if (rai_tmp->timingp->runtime == rti) { + rti->rai = rai_tmp; + return; + } + } + } +} + +static void gf_smil_anim_get_last_specified_value(SMIL_Anim_RTI *rai) +{ + SMILAnimationAttributesPointers *animp = rai->animp; + + if (!animp) return; + + if (rai->path) { + if (!rai->last_specified_value.far_ptr) rai->last_specified_value.far_ptr = gf_malloc(sizeof(GF_Matrix2D)); + gf_svg_compute_path_anim(rai, rai->last_specified_value.far_ptr, FIX_ONE); + return; + } else if (rai->anim_elt->sgprivate->tag == TAG_SVG_set) { + if (animp->to) { + rai->last_specified_value.fieldType = animp->to->type; + rai->last_specified_value.far_ptr = animp->to->value; + } else { + /* TODO ??? */ + GF_LOG(GF_LOG_ERROR, GF_LOG_SMIL, + ("[SMIL Animation] Animation %s - set element without to attribute\n", + gf_node_get_log_name((GF_Node *)rai->anim_elt))); + } + return; + } + + if (rai->values_count) { + /* Ignore from/to/by*/ + rai->last_specified_value.fieldType = animp->values->type; + rai->last_specified_value.far_ptr = gf_list_last(animp->values->values); + } else if ((animp->by && animp->by->type) && (!animp->to || animp->to->type == 0)) { + rai->last_specified_value.fieldType = animp->by->type; + rai->last_specified_value.far_ptr = animp->by->value; + } else if (animp->to) { + rai->last_specified_value.fieldType = animp->to->type; + rai->last_specified_value.far_ptr = animp->to->value; + } + if (gf_svg_is_inherit(&rai->last_specified_value)) { + rai->last_specified_value.fieldType = rai->owner->presentation_value.fieldType; + rai->last_specified_value.far_ptr = rai->owner->presentation_value.far_ptr; + } + if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(rai->last_specified_value.fieldType)) { + gf_svg_attributes_resolve_currentColor(&rai->last_specified_value, &rai->owner->current_color_value); + gf_svg_attributes_resolve_inherit(&rai->last_specified_value, &rai->owner->parent_presentation_value); + } +} + +/* if the animation behavior is accumulative and this is not the first iteration, + then we modify the interpolation value as follows: + interpolation value += last specified value * number of iterations completed */ +static void gf_smil_anim_apply_accumulate(SMIL_Anim_RTI *rai) +{ + u32 nb_iterations; + + SMILAnimationAttributesPointers *animp = rai->animp; + SMILTimingAttributesPointers *timingp = rai->timingp; + + nb_iterations = (timingp->runtime->current_interval ? timingp->runtime->current_interval->nb_iterations : 1); + + if (rai->change_detection_mode) { + if ((animp->accumulate && *animp->accumulate == SMIL_ACCUMULATE_SUM) + && nb_iterations > 0 + && rai->previous_iteration != (s32) nb_iterations) { + /* if we actually do accumulation and the number of iteration is different, + then we force the result as changed regardless of the result of the interpolation + (TODO: check if this need to be improved)*/ + rai->interpolated_value_changed = 1; + } else { + /* if we don't accumulate we leave the value of interpolated_value_changed unchanged */ + } + } else { + if (nb_iterations > 0 && rai->previous_iteration != (s32) nb_iterations) { + rai->previous_iteration = nb_iterations; + } + + if ((animp->accumulate && *animp->accumulate == SMIL_ACCUMULATE_SUM) && nb_iterations > 0) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying accumulation (iteration #%d)\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), nb_iterations)); + + gf_svg_attributes_muladd(FIX_ONE, &rai->interpolated_value, + INT2FIX(nb_iterations), &rai->last_specified_value, + &rai->interpolated_value, 1); + + if ((animp->from) && animp->by && (rai->last_specified_value.far_ptr == animp->by->value)) { + /* this is a from-by animation, the last specified value is not the 'by' value but actually 'from'+'by', + we need to add nb_iterations times from to the interpolated_value + see (animate-elem-210-t.svg (upper two circles in the mid column, after 9s/14s */ + GF_FieldInfo from_info; + from_info.fieldType = rai->animp->from->type; + from_info.far_ptr = rai->animp->from->value; + gf_svg_attributes_muladd(FIX_ONE, &rai->interpolated_value, + INT2FIX(nb_iterations), &from_info, + &rai->interpolated_value, 1); + } + } + } +} + +static void gf_smil_apply_additive(SMIL_Anim_RTI *rai) +{ + SMILAnimationAttributesPointers *animp = rai->animp; + if (rai->change_detection_mode) return; + else { + /* Apply additive behavior if required + PV = (additive == sum ? PV + animp->IV : animp->IV); */ + if (animp->additive && *animp->additive == SMIL_ADDITIVE_SUM) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying additive behavior\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); + + gf_svg_attributes_add((rai->is_first_anim ? &rai->owner->specified_value : &rai->owner->presentation_value), + &rai->interpolated_value, + &rai->owner->presentation_value, + 1); + +#ifndef GPAC_DISABLE_LOG + if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { + char *str; + gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); + str = gf_svg_dump_attribute((GF_Node*)rai->anim_elt, &rai->owner->presentation_value); + gf_log("[SMIL Animation] Time %f - Animation %s - Presentation value changed for attribute %s, new value: %s\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node*)rai->anim_elt), + gf_svg_get_attribute_name((GF_Node*)rai->anim_elt, rai->owner->presentation_value.fieldIndex), str); + + if (str) gf_free(str); + } +#endif + + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying non-additive behavior\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); + + /* FIXME: if we switch pointers to avoid copying values, + we need to modify the address in the DOM node as well, + we also need to take care about change detections. Not easy!! + + void *tmp = rai->owner->presentation_value.far_ptr; + rai->owner->presentation_value.far_ptr = rai->interpolated_value.far_ptr; + rai->interpolated_value.far_ptr = tmp; + */ + + gf_svg_attributes_copy(&rai->owner->presentation_value, &rai->interpolated_value, 1); +#ifndef GPAC_DISABLE_LOG + if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { + char *str; + gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); + str = gf_svg_dump_attribute((GF_Node*)rai->anim_elt, &rai->owner->presentation_value); + + gf_log("[SMIL Animation] Time %f - Animation %s - Presentation value changed for attribute %s, new value: %s\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node*)rai->anim_elt), + gf_svg_get_attribute_name((GF_Node*)rai->anim_elt, rai->owner->presentation_value.fieldIndex), str); + + if (str) gf_free(str); + } +#endif + } + } +} + +static void gf_smil_anim_animate(SMIL_Timing_RTI *rti, Fixed normalized_simple_time) +{ + SMIL_Anim_RTI *rai = rti->rai; + SMILAnimationAttributesPointers *animp = rai->animp; + + if (!rai || !animp) return; + + gf_smil_anim_compute_interpolation_value(rai, normalized_simple_time); + gf_smil_anim_apply_accumulate(rai); + gf_smil_apply_additive(rai); +} + +static void gf_smil_anim_animate_with_fraction(SMIL_Timing_RTI *rti, Fixed normalized_simple_time) +{ + gf_smil_anim_animate(rti, rti->fraction); + rti->evaluate_status = SMIL_TIMING_EVAL_NONE; +} + +void gf_smil_anim_reset_variables(SMIL_Anim_RTI *rai) +{ + if (!rai) return; + /* we reset all the animation parameters to force computation of next interpolation value + when the animation restarts */ + rai->interpolated_value_changed = 0; + rai->previous_key_index = -1; + rai->previous_coef = -FIX_ONE; + rai->previous_iteration = -1; + rai->previous_keytime_index = 0; + rai->anim_done = 0; +} + +/* copy/paste of the animate function + TODO: check if computations of interpolation value can be avoided. +*/ +static void gf_smil_anim_freeze(SMIL_Timing_RTI *rti, Fixed normalized_simple_time) +{ + SMIL_Anim_RTI *rai = rti->rai; + SMILAnimationAttributesPointers *animp = rai->animp; + + if (!rai || !animp) return; + + if (rai->change_detection_mode) { + if (rai->anim_done == 0) + rai->interpolated_value_changed = 1; + else + rai->interpolated_value_changed = 0; + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying freeze behavior\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); + + gf_smil_anim_compute_interpolation_value(rai, normalized_simple_time); + gf_smil_anim_apply_accumulate(rai); + gf_smil_apply_additive(rai); + rai->anim_done = 1; + } +} + +static void gf_smil_anim_remove(SMIL_Timing_RTI *rti, Fixed normalized_simple_time) +{ + SMIL_Anim_RTI *rai = rti->rai; + if (!rai) return; + + if (rai->change_detection_mode) { + if (rai->anim_done == 0) + rai->interpolated_value_changed = 1; + else + rai->interpolated_value_changed = 0; + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying remove behavior\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); + + /* TODO: see if we can avoid this copy by switching pointers */ + gf_svg_attributes_copy(&rai->owner->presentation_value, &rai->owner->specified_value, 0); + /* TODO: check if we need to apply additive behavior even in fill='remove' + maybe (see animate-elem-211-t.svg) */ + + rai->anim_done = 1; + +#ifndef GPAC_DISABLE_LOG + if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { + char *str; + gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); + str = gf_svg_dump_attribute((GF_Node*)rai->anim_elt, &rai->owner->presentation_value); + + gf_log("[SMIL Animation] Time %f - Animation %s - Presentation value changed for attribute %s, new value: %s\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node*)rai->anim_elt), + gf_svg_get_attribute_name((GF_Node*)rai->anim_elt, rai->owner->presentation_value.fieldIndex), str); + if (str) gf_free(str); + } +#endif + + } +} + +static void gf_smil_anim_evaluate(SMIL_Timing_RTI *rti, Fixed normalized_simple_time, u32 state) +{ + SMIL_Anim_RTI *rai = rti->rai; + switch (state) { + case SMIL_TIMING_EVAL_REPEAT: + /* we are starting a new cycle of animation, therefore we need to reset the previous state variables + like previous_keytime_index ... */ + gf_smil_anim_reset_variables(rai); + case SMIL_TIMING_EVAL_UPDATE: + gf_smil_anim_animate(rti, normalized_simple_time); + break; + case SMIL_TIMING_EVAL_FREEZE: + gf_smil_anim_freeze(rti, normalized_simple_time); + break; + case SMIL_TIMING_EVAL_REMOVE: + gf_smil_anim_remove(rti, normalized_simple_time); + break; + case SMIL_TIMING_EVAL_FRACTION: + gf_smil_anim_animate_with_fraction(rti, normalized_simple_time); + break; +/* + discard should be done before in smil_notify_time + case SMIL_TIMING_EVAL_DISCARD: + break; +*/ + } +} +/************************************************************************************** + **************************************************************************************/ + +GF_EXPORT +void gf_svg_apply_animations(GF_Node *node, SVGPropertiesPointers *render_svg_props) +{ + u32 count_all, i; + u32 active_anim; +#ifndef GPAC_DISABLE_LOG + u32 time=0; + + if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_RTI)) { + time = gf_sys_clock(); + } +#endif + + /* Perform all the animations on this node */ + count_all = gf_node_animation_count(node); + for (i = 0; i < count_all; i++) { + GF_FieldInfo info; + s32 j; + u32 count; + SMIL_AttributeAnimations *aa; + + + aa = (SMIL_AttributeAnimations *)gf_node_animation_get(node, i); + count = gf_list_count(aa->anims); + if (!count) continue; + + aa->presentation_value_changed = 0; + + if (aa->is_property) { + /* Storing the pointer to the parent presentation value, + i.e. the presentation value produced at the parent level in the tree */ + aa->parent_presentation_value = aa->presentation_value; + aa->parent_presentation_value.far_ptr = + gf_svg_get_property_pointer((SVG_Element *)node, aa->orig_dom_ptr, render_svg_props); + + /* Storing also the pointer to the presentation value of the color property + (special handling of the keyword 'currentColor' if used in animation values) */ + gf_node_get_attribute_by_tag(node, TAG_SVG_ATT_color, 1, 1, &info); + aa->current_color_value.far_ptr = info.far_ptr; + } + + /* We start with the last animation (TODO in the execution order), then scan in the reverse order + up to the first animation which is not additive, to determine if the presentation value will change + We evaluate each animation, but only in the 'change_detection_mode' */ + for (j = count-1; j >= 0; j--) { + SMIL_Anim_RTI *rai = (SMIL_Anim_RTI *)gf_list_get(aa->anims, j); + SMIL_Timing_RTI *rti = rai->timingp->runtime; + + rai->interpolated_value_changed = 0; + + /* The evaluate_status has been updated when notifying the new scene time to this animation, + i.e. before the scene tree traversal */ + if (rti->evaluate_status) { + rai->change_detection_mode = 1; + rti->evaluate(rti, rti->normalized_simple_time, rti->evaluate_status); + aa->presentation_value_changed += rai->interpolated_value_changed; + if (!rai->animp->additive || *rai->animp->additive == SMIL_ADDITIVE_REPLACE) { + /* we don't need to check previous animations since this one will overwrite it */ + j--; + break; + } + } + } + + active_anim = 0; + if (aa->presentation_value_changed) { + /* If the result of all the combined animations will produce a different result compared to the previous frame, + we start in the forward order from the j were the previous step stopped (i.e. the first anim in replace mode) + and evaluate each animation, in the computation mode (change_detection_mode = 0)*/ + for (j++; j<(s32)count; j++) { + SMIL_Anim_RTI *rai = (SMIL_Anim_RTI *)gf_list_get(aa->anims, j); + SMIL_Timing_RTI *rti = rai->timingp->runtime; + + if (j == 0) rai->is_first_anim = 1; + else rai->is_first_anim = 0; + + if (rti->evaluate_status) { + rai->change_detection_mode = 0; + rti->evaluate(rti, rti->normalized_simple_time, rti->evaluate_status); + active_anim++; + } + } + } + +/* DEBUG: uncomment this line to remove animation effect, and keep animation computation */ +// gf_svg_attributes_copy(&aa->presentation_value, &aa->specified_value, 0); + +#ifndef GPAC_DISABLE_LOG + if (aa->presentation_value_changed) { + if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { + char *str; + gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); + str = gf_svg_dump_attribute(node, &aa->presentation_value); + + gf_log("[SMIL Animation] Time %f - Element %s - Presentation value changed for attribute %s, new value: %s - dirty flags %x\n", + gf_node_get_scene_time(node), gf_node_get_log_name(node), + gf_svg_get_attribute_name(node, aa->presentation_value.fieldIndex), str, aa->dirty_flags); + + if (str) gf_free(str); + } + } +#endif + + /* we only set dirty flags when a real flag is set to avoid unnecessary computation + for example, it is not necessary to set it when the anim is an animateTransform + since there is no associated flag */ + if (aa->dirty_flags) { + if (aa->presentation_value_changed) { + gf_node_dirty_set(node, aa->dirty_flags, aa->dirty_parents); + } else { + /* WARNING - This does not work for use elements because apply_animations may be called several times */ + if (active_anim) gf_node_dirty_clear(node, aa->dirty_flags); + } + } + } + +#ifndef GPAC_DISABLE_LOG + if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_RTI)) { + time_spent_in_anim += gf_sys_clock() - time; + } +#endif +} + + +GF_Node *gf_smil_anim_get_target(GF_Node *e) +{ + XLinkAttributesPointers *xlinkp = NULL; + if (!gf_svg_is_animation_tag(e->sgprivate->tag)) return NULL; + xlinkp = ((SVGTimedAnimBaseElement *)e)->xlinkp; + return xlinkp->href->target; +} + +void gf_smil_anim_init_runtime_info(GF_Node *e) +{ + u32 i; + GF_FieldInfo target_attribute; + SMIL_AttributeAnimations *aa = NULL; + SMIL_Anim_RTI *rai; + XLinkAttributesPointers *xlinkp = NULL; + SMILAnimationAttributesPointers *animp = NULL; + SMILTimingAttributesPointers *timingp = NULL; + GF_Node *target = NULL; + + if (!e) return; + + /* Filling animation structures to be independent of the SVG Element structure */ + animp = ((SVGTimedAnimBaseElement *)e)->animp; + timingp = ((SVGTimedAnimBaseElement *)e)->timingp; + xlinkp = ((SVGTimedAnimBaseElement *)e)->xlinkp; + + target = xlinkp->href->target; + + memset(&target_attribute, 0, sizeof(GF_FieldInfo)); + if (animp->attributeName && (animp->attributeName->name || animp->attributeName->tag)) { + /* Filling the target_attribute structure with info on the animated attribute (type, pointer to data, ...) + NOTE: in the mode Dynamic Allocation of Attributes, this means that the animated + attribute is created with a default value, if it was not specified on the target element */ + if (animp->attributeName->tag) { + gf_node_get_attribute_by_tag(target, animp->attributeName->tag, 1, 1, &target_attribute); + } else { + gf_node_get_field_by_name(target, animp->attributeName->name, &target_attribute); + } + } else { + /* All animation elements should have a target attribute except for animateMotion + cf http://www.w3.org/mid/u403c21ajf1sjqtk58g0g38eaep9f9g2ss@hive.bjoern.hoehrmann.de + "For animateMotion, the attributeName is implied and cannot be specified; + animateTransform requires specification of the attribute name and any attribute that is + a transform-like attribute can be a target, e.g. gradientTransform."*/ + + switch (e->sgprivate->tag) { + case TAG_SVG_animateMotion: + /* Explicit creation of the pseudo 'motionTransform' attribute since it cannot be specified */ + gf_node_get_attribute_by_tag(target, TAG_SVG_ATT_motionTransform, 1, 0, &target_attribute); + gf_mx2d_init(*(GF_Matrix2D *)target_attribute.far_ptr); + break; + default: + GF_LOG(GF_LOG_WARNING, GF_LOG_SMIL, + ("[SMIL Animation] Missing attributeName attribute on element %s\n", + gf_node_get_log_name((GF_Node*)e) )); + return; + } + } + + if (animp->attributeType && *animp->attributeType == SMIL_ATTRIBUTETYPE_CSS) { + /* see example animate-elem-219-t.svg from the SVG test suite, upper row */ + if (!gf_svg_is_property(target, &target_attribute)) { + GF_LOG(GF_LOG_WARNING, GF_LOG_SMIL, + ("[SMIL Animation] Using CSS attributeType for an animation on an attribute which is not a property %s\n", + gf_node_get_log_name((GF_Node*)e) )); + return; + } + } + + /* Creation and setup of the runtime structure for animation */ + GF_SAFEALLOC(rai, SMIL_Anim_RTI) + + rai->anim_elt = e; + rai->animp = animp; + rai->timingp = timingp; + rai->xlinkp = xlinkp; + + gf_mx2d_init(rai->identity); + rai->default_transform_value.far_ptr = &rai->identity; + rai->default_transform_value.fieldType = SVG_Transform_datatype; + + /* the interpolated value has the same type as the target attribute, + but we need to create a new pointer to hold its value */ + rai->interpolated_value = target_attribute; + rai->interpolated_value.far_ptr = gf_svg_create_attribute_value(target_attribute.fieldType); + + /* there has not been any interpolation yet, so the previous key index and interpolation coefficient + shall not be set*/ + gf_smil_anim_reset_variables(rai); + + rai->values_count = (animp->values ? gf_list_count(animp->values->values) : 0); + rai->key_times_count = (animp->keyTimes ? gf_list_count(*animp->keyTimes) : 0); + rai->key_points_count = (animp->keyPoints ? gf_list_count(*animp->keyPoints) : 0); + rai->key_splines_count = (animp->keySplines ? gf_list_count(*animp->keySplines) : 0); + + + if (!rai->values_count && /* 'values' attribute not specified */ + (!animp->to || animp->to->type == 0) && /* 'to' attribute not specified */ + (!animp->from || animp->from->type == 0) && /* 'from' attribute not specified */ + (animp->by && animp->by->type != 0)) { /* 'by' attribute specified */ + /* if this is a 'by' animation without from the animation is defined to be additive + see http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#AnimationNS-FromToBy + we override the additive attribute */ + if (!animp->additive) { + /* this case can only happen with dynamic allocation of attributes */ + GF_FieldInfo info; + gf_node_get_attribute_by_tag(e, TAG_SVG_ATT_additive, 1, 0, &info); + animp->additive = info.far_ptr; + } + if (*animp->additive == SMIL_ADDITIVE_REPLACE) { + GF_LOG(GF_LOG_WARNING, GF_LOG_SMIL, ("[SMIL Animation] Warning: by-animations cannot use additive=\"replace\"\n")); + } + *animp->additive = SMIL_ADDITIVE_SUM; + } + + /*TODO + http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#animationNS-ToAnimation + To animation defines its own kind of additive semantics, so the additive attribute is ignored. + */ + + /*TODO + http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#animationNS-ToAnimation + Because to animation is defined in terms of absolute values of the target attribute, + cumulative animation is not defined: + */ + + /* TODO + http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#animationNS-setElement + The set element is non-additive. The additive and accumulate attributes are not allowed, + and will be ignored if specified. + */ + + /* For animateMotion, we need to retrieve the value of the rotate attribute, retrieve the path either + from the 'path' attribute or from the 'mpath' element, and then initialize the path iterator*/ + if (e->sgprivate->tag == TAG_SVG_animateMotion) { + GF_Path *the_path = NULL; + GF_ChildNodeItem *child = NULL; + + GF_FieldInfo info; + if (gf_node_get_attribute_by_tag(e, TAG_SVG_ATT_rotate, 0, 0, &info) == GF_OK) { + rai->rotate = ((SVG_Rotate *)info.far_ptr)->type; + } else { + rai->rotate = SVG_NUMBER_VALUE; + } + if (gf_node_get_attribute_by_tag(e, TAG_SVG_ATT_path, 0, 0, &info) == GF_OK) { + the_path = ((SVG_PathData *)info.far_ptr); + } + child = ((SVG_Element *)e)->children; + + if ((!animp->to || animp->to->type == 0) && + (!animp->by || animp->by->type == 0) && + (!animp->values || animp->values->type == 0)) { +#if USE_GF_PATH + if (!gf_path_is_empty(the_path)) { + rai->path = the_path; + rai->path_iterator = gf_path_iterator_new(rai->path); + rai->length = gf_path_iterator_get_length(rai->path_iterator); + } +#else + rai->path = gf_path_new(); + if (gf_list_count(the_path->points)) { + gf_svg_path_build(rai->path, the_path->commands, the_path->points); + rai->path_iterator = gf_path_iterator_new(rai->path); + rai->length = gf_path_iterator_get_length(rai->path_iterator); + } +#endif + else { + while (child) { + GF_Node *used_path = NULL; + u32 child_tag = gf_node_get_tag(child->node); + if (child_tag == TAG_SVG_mpath) { + GF_FieldInfo info; + if (gf_node_get_attribute_by_tag(child->node, TAG_XLINK_ATT_href, 0, 0, &info) == GF_OK) { + XMLRI *iri = (XMLRI *)info.far_ptr; + if (iri->target) used_path = iri->target; + else if (iri->string) used_path = + (GF_Node *)gf_sg_find_node_by_name(gf_node_get_graph(child->node), iri->string); + if (used_path && gf_node_get_tag(used_path) == TAG_SVG_path) { + gf_node_get_attribute_by_tag(used_path, TAG_SVG_ATT_d, 1, 0, &info); +#if USE_GF_PATH + rai->path = (SVG_PathData *)info.far_ptr; +#else + gf_svg_path_build(rai->path, + ((SVG_PathData *)info.far_ptr)->commands, + ((SVG_PathData *)info.far_ptr)->points); +#endif + rai->path_iterator = gf_path_iterator_new(rai->path); + rai->length = gf_path_iterator_get_length(rai->path_iterator); + } + } + break; + } + child = child->next; + } + } + } + } + + /* for all animations, check if there is already one animation on this attribute, + if yes, get the list and append the new animation runtime info + if no, create a list and add the new animation runtime info. */ + for (i = 0; i < gf_node_animation_count(target); i++) { + aa = (SMIL_AttributeAnimations *)gf_node_animation_get(target, i); + if (aa->presentation_value.fieldIndex == target_attribute.fieldIndex) { + gf_list_add(aa->anims, rai); + break; + } + aa = NULL; + } + if (!aa) { + GF_SAFEALLOC(aa, SMIL_AttributeAnimations) + + /* We determine if the animated attribute is a property since this changes quite a lot the animation model */ + aa->is_property = gf_svg_is_property(target, &target_attribute); + aa->current_color_value.fieldType = SVG_Paint_datatype; + + /* We copy (one copy for all animations on the same attribute) the DOM specified + value before any animation starts (because the animation will override it), + we also save the initial memory address of the specified value (orig_dom_ptr) + for inheritance hack */ + aa->specified_value = target_attribute; + aa->orig_dom_ptr = aa->specified_value.far_ptr; + aa->specified_value.far_ptr = gf_svg_create_attribute_value(target_attribute.fieldType); + gf_svg_attributes_copy(&aa->specified_value, &target_attribute, 0); + + /* Now, the initial memory address of the specified value holds the presentation value, + and the presentation value is initialized */ + aa->presentation_value = target_attribute; + + aa->anims = gf_list_new(); + gf_list_add(aa->anims, rai); + gf_node_animation_add(target, aa); + + /* determine what the rendering will need to do when the animation runs */ + aa->dirty_flags = gf_svg_get_modification_flags((SVG_Element *)target, &target_attribute); + + /* If the animation will result in a change of geometry or of the display property, + this animation will require traversing the tree, we need to inform the parents of the target node */ + aa->dirty_parents = 0; + if (aa->dirty_flags & (GF_SG_SVG_GEOMETRY_DIRTY | GF_SG_SVG_DISPLAY_DIRTY)) aa->dirty_parents = 1; + } + + rai->owner = aa; + gf_smil_anim_get_last_specified_value(rai); + + /* for animation (unlike other timed elements like video), the evaluation (i.e. interpolation) cannot be done + during timing evaluation, because due to inheritance, interpolation can only be computed + during scene tree traversal, therefore we need to postpone evaluation of the timed element */ + timingp->runtime->postpone = 1; + + timingp->runtime->evaluate = gf_smil_anim_evaluate; +} + +void gf_smil_anim_delete_runtime_info(SMIL_Anim_RTI *rai) +{ + gf_svg_delete_attribute_value(rai->interpolated_value.fieldType, + rai->interpolated_value.far_ptr, + rai->anim_elt->sgprivate->scenegraph); + if (rai->path) { + gf_svg_delete_attribute_value(rai->last_specified_value.fieldType, + rai->last_specified_value.far_ptr, + rai->anim_elt->sgprivate->scenegraph); + } +#if USE_GF_PATH +#else + if (rai->path) gf_path_del(rai->path); +#endif + if (rai->path_iterator) gf_path_iterator_del(rai->path_iterator); + gf_free(rai); +} + +void gf_smil_anim_remove_from_target(GF_Node *anim, GF_Node *target) +{ + u32 i, j; + if (!target) return; + for (i = 0; i < gf_node_animation_count((GF_Node *)target); i ++) { + SMIL_Anim_RTI *rai; + SMIL_AttributeAnimations *aa = (SMIL_AttributeAnimations *)gf_node_animation_get((GF_Node *)target, i); + j=0; + while ((rai = (SMIL_Anim_RTI *)gf_list_enum(aa->anims, &j))) { + if ((GF_Node *)rai->anim_elt == anim) { + gf_list_rem(aa->anims, j-1); + gf_smil_anim_delete_runtime_info(rai); + break; + } + } + if (gf_list_count(aa->anims) == 0) { + gf_list_del(aa->anims); + gf_svg_delete_attribute_value(aa->specified_value.fieldType, + aa->specified_value.far_ptr, + target->sgprivate->scenegraph); + aa->presentation_value.far_ptr = aa->orig_dom_ptr; + gf_node_animation_rem((GF_Node *)target, i); + gf_free(aa); + } + } +} + +void gf_smil_anim_delete_animations(GF_Node *e) +{ + u32 i, j; + + for (i = 0; i < gf_node_animation_count(e); i ++) { + SMIL_Anim_RTI *rai; + SMIL_AttributeAnimations *aa = (SMIL_AttributeAnimations *)gf_node_animation_get(e, i); + gf_svg_delete_attribute_value(aa->specified_value.fieldType, + aa->specified_value.far_ptr, + e->sgprivate->scenegraph); + j=0; + while ((rai = (SMIL_Anim_RTI *)gf_list_enum(aa->anims, &j))) { + rai->xlinkp->href->target = NULL; + gf_smil_anim_delete_runtime_info(rai); + } + gf_list_del(aa->anims); + gf_free(aa); + } + gf_node_animation_del(e); +} + +void gf_smil_anim_init_discard(GF_Node *node) +{ + SVGAllAttributes all_atts; + XLinkAttributesPointers *xlinkp = NULL; + SVGTimedAnimBaseElement *e = (SVGTimedAnimBaseElement *)node; + gf_smil_timing_init_runtime_info(node); + + gf_svg_flatten_attributes((SVG_Element *)e, &all_atts); + GF_SAFEALLOC(e->xlinkp, XLinkAttributesPointers); + xlinkp = e->xlinkp; + xlinkp->href = all_atts.xlink_href; + xlinkp->type = all_atts.xlink_type; + + e->timingp->runtime->evaluate_status = SMIL_TIMING_EVAL_DISCARD; +} + +void gf_smil_anim_init_node(GF_Node *node) +{ + XLinkAttributesPointers *xlinkp = NULL; + SMILAnimationAttributesPointers *animp = NULL; + SVGAllAttributes all_atts; + SVGTimedAnimBaseElement *e = (SVGTimedAnimBaseElement *)node; + + gf_svg_flatten_attributes((SVG_Element *)e, &all_atts); + e->xlinkp = gf_malloc(sizeof(XLinkAttributesPointers)); + xlinkp = e->xlinkp; + xlinkp->href = all_atts.xlink_href; + xlinkp->type = all_atts.xlink_type; + + /*perform init of default values*/ + if (!xlinkp->href) { + GF_FieldInfo info; + gf_node_get_attribute_by_tag((GF_Node *)node, TAG_XLINK_ATT_href, 1, 0, &info); + xlinkp->href = info.far_ptr; + xlinkp->href->type = XMLRI_ELEMENTID; + xlinkp->href->target = gf_node_get_parent(node, 0); + } + if (xlinkp->href->type == XMLRI_STRING) { + if (!xlinkp->href->string) { + fprintf(stderr, "Error: IRI not initialized\n"); + return; + } else { + GF_Node *n; + + n = (GF_Node*)gf_sg_find_node_by_name(gf_node_get_graph(node), xlinkp->href->string); + if (n) { + xlinkp->href->type = XMLRI_ELEMENTID; + xlinkp->href->target = n; + gf_node_register_iri(node->sgprivate->scenegraph, xlinkp->href); + } else { + return; + } + } + } + if (!xlinkp->href->target) return; + + // We may not have an attribute name, when using an animateMotion element + if (node->sgprivate->tag != TAG_SVG_animateMotion && !all_atts.attributeName) return; + + if ( (all_atts.to && (all_atts.to->type==0)) + || (all_atts.from && (all_atts.from->type==0)) + || (all_atts.from && (all_atts.from->type==0)) + ) { + GF_FieldInfo info; + if (gf_node_get_attribute_by_name((GF_Node *)xlinkp->href->target, all_atts.attributeName->name, 0, 1, 1, &info)==GF_OK) { + u32 anim_value_type = info.fieldType; + u32 i; + for (i=0; i<3; i++) { + u32 tag = 0; + switch (i) { + case 0: tag=TAG_SVG_ATT_to; break; + case 1: tag=TAG_SVG_ATT_from; break; + case 2: tag=TAG_SVG_ATT_by; break; + } + if (gf_node_get_attribute_by_tag((GF_Node *)node, tag, 0, 0, &info)==GF_OK) { + SMIL_AnimateValue *attval = info.far_ptr; + if (attval->type==0) { + SVG_String *string = attval->value; + attval->value = NULL; + if (string) { + gf_svg_parse_attribute((GF_Node *)node, &info, * string, anim_value_type); + if (* string) gf_free(* string); + gf_free(string); + } + } + } + } + } + } + + e->animp = gf_malloc(sizeof(SMILAnimationAttributesPointers)); + animp = e->animp; + animp->accumulate = all_atts.accumulate; + animp->additive = all_atts.additive; + animp->attributeName = all_atts.attributeName; + animp->attributeType = all_atts.attributeType; + animp->by = all_atts.by; + animp->calcMode = all_atts.calcMode; + animp->from = all_atts.from; + animp->keySplines = all_atts.keySplines; + animp->keyTimes = all_atts.keyTimes; + animp->lsr_enabled = all_atts.lsr_enabled; + animp->to = all_atts.to; + animp->type = all_atts.transform_type; + animp->values = all_atts.values; + if (node->sgprivate->tag == TAG_SVG_animateMotion) { + e->animp->keyPoints = all_atts.keyPoints; + e->animp->origin = all_atts.origin; + e->animp->path = all_atts.path; + e->animp->rotate = all_atts.rotate; + } else { + e->animp->keyPoints = NULL; + e->animp->origin = NULL; + e->animp->path = NULL; + e->animp->rotate = NULL; + } + + + gf_smil_timing_init_runtime_info(node); + gf_smil_anim_init_runtime_info(node); + gf_smil_anim_set_anim_runtime_in_timing(node); +} + + + +#endif /*GPAC_DISABLE_SVG*/ diff --git a/src/scenegraph/svg_attributes.c b/src/scenegraph/svg_attributes.c index 5cce30e..2f7eaa1 100644 --- a/src/scenegraph/svg_attributes.c +++ b/src/scenegraph/svg_attributes.c @@ -891,7 +891,7 @@ static GF_Err svg_parse_clock_value(char *d, Double *clock_value) u32 hours; u32 minutes; Float seconds; - if (sscanf(d, "%ud:%ud:%f", &hours, &minutes, &seconds) < 3) return GF_BAD_PARAM; + if (sscanf(d, "%u:%u:%f", &hours, &minutes, &seconds) < 3) return GF_BAD_PARAM; *clock_value = hours*3600 + minutes*60 + seconds; } else { /* Partial Clock value : mm:ss(.frac) */ @@ -960,29 +960,27 @@ static GF_Err smil_parse_time(GF_Node *elt, SMIL_Time *v, char *d) v->type = GF_SMIL_TIME_WALLCLOCK; tmp += 10; if ((tmp1 = strchr(tmp, 'T')) ) { - /* From tmp to wallStartTime, we parse a date - do not use %ud here, broken on Win32 (sscanf returns 1) - */ - sscanf(tmp, "%d-%d-%dT", &year, &month, &day); + /* From tmp to wallStartTime, we parse a date */ + sscanf(tmp, "%u-%u-%dT", &year, &month, &day); tmp1++; tmp = tmp1; } if ((tmp1 = strchr(tmp, ':')) ) { if ((tmp2 = strchr(tmp1, ':')) ) { /* HHMMSS */ - sscanf(tmp, "%ud:%ud:%f", &hours, &minutes, &seconds); + sscanf(tmp, "%u:%u:%f", &hours, &minutes, &seconds); } else { /* HHMM */ - sscanf(tmp, "%ud:%ud", &hours, &minutes); + sscanf(tmp, "%u:%u", &hours, &minutes); } } if (strchr(tmp, 'Z')) { return GF_OK; } else { if ( (tmp1 = strchr(tmp, '+')) ) { - sscanf(tmp1, "%ud:%ud", &nhours, &nminutes); + sscanf(tmp1, "%u:%u", &nhours, &nminutes); } else if ( (tmp1 = strchr(tmp, '-')) ) { - sscanf(tmp1, "%ud:%ud", &nhours, &nminutes); + sscanf(tmp1, "%u:%u", &nhours, &nminutes); } } return GF_OK; diff --git a/src/scenegraph/svg_smjs.c b/src/scenegraph/svg_smjs.c index c66adef..c0b6b56 100644 --- a/src/scenegraph/svg_smjs.c +++ b/src/scenegraph/svg_smjs.c @@ -42,7 +42,7 @@ #define JSVAL_CHECK_STRING(_v) (JSVAL_IS_STRING(_v) || JSVAL_IS_NULL(_v)) -static Bool svg_script_execute_handler(GF_Node *node, GF_DOM_Event *event, GF_Node *observer); +static Bool svg_script_execute_handler(GF_Node *node, GF_DOM_Event *event, GF_Node *observer, char *utf8_script); jsval dom_element_construct(JSContext *c, GF_Node *n); @@ -1360,6 +1360,33 @@ JSBool SMJS_FUNCTION(svg_udom_create_color) return JS_TRUE; } + +JSBool SMJS_FUNCTION(svg_path_get_total_length) +{ + Double length = 0; + GF_FieldInfo info; + SMJS_OBJ + + GF_Node *n = (GF_Node *)dom_get_element(c, obj); + if (!n) return JS_TRUE; + if (n->sgprivate->tag != TAG_SVG_path) return JS_TRUE; + + gf_node_get_field_by_name(n, "d", &info); + if (info.fieldType == SVG_PathData_datatype) { +#if USE_GF_PATH + GF_Path *p = (GF_Path *)info.far_ptr; + GF_PathIterator *path_it = gf_path_iterator_new(p); + if (path_it) { + Fixed len = gf_path_iterator_get_length(path_it); + length = FIX2FLT(len); + gf_path_iterator_del(path_it); + } +#endif + } + SMJS_SET_RVAL( JS_MAKE_DOUBLE(c, length ) ); + return JS_TRUE; +} + JSBool SMJS_FUNCTION(svg_udom_move_focus) { GF_JSAPIParam par; @@ -1424,7 +1451,7 @@ static JSBool SMJS_FUNCTION(svg_connection_create) return JS_TRUE; } -#ifdef UNUSED_FUNC +#ifdef GPAC_UNUSED_FUNC /** * FIXME : those 5 funcs and two variables are not used anywhere... */ @@ -1462,7 +1489,7 @@ static JSFunctionSpec connectionFuncs[] = { {"close", svg_connection_close, 0, 0, 0}, {0, 0, 0, 0, 0} }; -#endif /* UNUSED_FUNC */ +#endif /*GPAC_UNUSED_FUNC*/ static void baseCI_finalize(JSContext *c, JSObject *obj) { @@ -1617,7 +1644,7 @@ static JSObject *svg_new_path_object(JSContext *c, SVG_PathData *d) #endif } -#ifdef UNUSED_FUNC +#ifdef GPAC_UNUSED_FUNC static JSBool pathCI_constructor(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { pathCI *p; @@ -1626,7 +1653,7 @@ static JSBool pathCI_constructor(JSContext *c, JSObject *obj, uintN argc, jsval *rval = OBJECT_TO_JSVAL(obj); return JS_TRUE; } -#endif /* UNUSED_FUNC */ +#endif /*GPAC_UNUSED_FUNC*/ static void pathCI_finalize(JSContext *c, JSObject *obj) { @@ -2160,6 +2187,9 @@ static void svg_init_js_api(GF_SceneGraph *scene) SMJS_FUNCTION_SPEC("endElement", svg_udom_smil_end, 0), SMJS_FUNCTION_SPEC("pauseElement", svg_udom_smil_pause, 0), SMJS_FUNCTION_SPEC("resumeElement", svg_udom_smil_resume, 0), + + SMJS_FUNCTION_SPEC("getTotalLength", svg_path_get_total_length, 0), + SMJS_FUNCTION_SPEC(0, 0, 0) }; @@ -2545,7 +2575,7 @@ void dump_root(const char *name, void *rp, void *data) } #endif -static Bool svg_script_execute_handler(GF_Node *node, GF_DOM_Event *event, GF_Node *observer) +static Bool svg_script_execute_handler(GF_Node *node, GF_DOM_Event *event, GF_Node *observer, char *utf8_script) { GF_DOMText *txt = NULL; GF_SVGJS *svg_js; @@ -2555,19 +2585,27 @@ static Bool svg_script_execute_handler(GF_Node *node, GF_DOM_Event *event, GF_No GF_DOMHandler *hdl = (GF_DOMHandler *)node; jsval fval, rval; - if (!hdl->js_fun && !hdl->js_fun_val && !hdl->evt_listen_obj) { - txt = svg_get_text_child(node); - if (!txt) return 0; + /*LASeR hack for encoding scripts without handler - node is a listener in this case, not a handler*/ + if (utf8_script) { + if (!node) return 0; + hdl = NULL; + } else { + if (!hdl->js_fun && !hdl->js_fun_val && !hdl->evt_listen_obj) { + txt = svg_get_text_child(node); + if (!txt) return 0; + } + /*not sure about this (cf test struct-use-205-t.svg)*/ + if (!node->sgprivate->parents) return 0; } - /*not sure about this (cf test struct-use-205-t.svg)*/ - if (!node->sgprivate->parents) return 0; svg_js = node->sgprivate->scenegraph->svg_js; #ifndef GPAC_DISABLE_LOG if ((gf_log_get_level() >= (GF_LOG_DEBUG)) && (gf_log_get_tools() & (GF_LOG_SCRIPT))) { char *content, *_content = NULL; - if (hdl->js_fun_val) { + if (utf8_script) { + content = utf8_script; + } else if (hdl->js_fun_val) { JSString *s = JS_DecompileFunction(svg_js->js_ctx, JS_ValueToFunction(svg_js->js_ctx, (jsval) hdl->js_fun_val), 0); content = _content = SMJS_CHARS_FROM_STRING(svg_js->js_ctx, s); } else if (hdl->js_fun) { @@ -2596,15 +2634,18 @@ static Bool svg_script_execute_handler(GF_Node *node, GF_DOM_Event *event, GF_No svg_js->in_script = 1; /*if an observer is being specified, use it*/ - if (hdl->evt_listen_obj) __this = hdl->evt_listen_obj; + if (hdl && hdl->evt_listen_obj) __this = hdl->evt_listen_obj; /*compile the jsfun if any - 'this' is the associated observer*/ else __this = observer ? JSVAL_TO_OBJECT( dom_element_construct(svg_js->js_ctx, observer) ) : svg_js->global; - if (txt && !hdl->js_fun) { + if (txt && hdl && !hdl->js_fun) { const char *argn = "evt"; hdl->js_fun = JS_CompileFunction(svg_js->js_ctx, __this, NULL, 1, &argn, txt->textContent, strlen(txt->textContent), NULL, 0); } - if (hdl->js_fun || hdl->js_fun_val || hdl->evt_listen_obj) { + if (utf8_script) { + ret = JS_EvaluateScript(svg_js->js_ctx, __this, utf8_script, strlen(utf8_script), 0, 0, &rval); + } + else if (hdl->js_fun || hdl->js_fun_val || hdl->evt_listen_obj) { JSObject *evt; jsval argv[1]; evt = gf_dom_new_event(svg_js->js_ctx); @@ -2628,8 +2669,15 @@ static Bool svg_script_execute_handler(GF_Node *node, GF_DOM_Event *event, GF_No else { ret = JS_EvaluateScript(svg_js->js_ctx, __this, txt->textContent, strlen(txt->textContent), 0, 0, &rval); } + + /*check any pending exception if outer-most event*/ + if (!prev_event && JS_IsExceptionPending(svg_js->js_ctx)) { + JS_ReportPendingException(svg_js->js_ctx); + JS_ClearPendingException(svg_js->js_ctx); + } + JS_SetPrivate(svg_js->js_ctx, svg_js->event, prev_event); - if (txt ) hdl->js_fun=0; + if (txt && hdl) hdl->js_fun=0; while (svg_js->force_gc) { svg_js->force_gc = 0; @@ -2643,7 +2691,7 @@ static Bool svg_script_execute_handler(GF_Node *node, GF_DOM_Event *event, GF_No if ((event->type==GF_EVENT_CLICK) || (event->type==GF_EVENT_MOUSEOVER)) { NodeIDedItem *reg_node; fprintf(stdout, "Node registry\n"); - reg_node = hdl->sgprivate->scenegraph->id_node; + reg_node = node->sgprivate->scenegraph->id_node; while (reg_node) { fprintf(stdout, "\t%s\n", reg_node->NodeName); reg_node = reg_node->next; diff --git a/src/scenegraph/vrml_proto.c b/src/scenegraph/vrml_proto.c index 6253822..d9f0ed7 100644 --- a/src/scenegraph/vrml_proto.c +++ b/src/scenegraph/vrml_proto.c @@ -848,30 +848,24 @@ void gf_sg_proto_del_instance(GF_ProtoInstance *inst) gf_node_unregister(node, (GF_Node*) inst); gf_list_rem(inst->node_code, 0); } - gf_list_del(inst->node_code); + sg = inst->sgprivate->scenegraph; + + /*reset the scene graph before destroying the node code list, as unregistering nodes + not destroyed in the previous phase (eg, cyclic references such as script and co) will + refer to the node-code list*/ + gf_sg_reset(sg); + sg->pOwningProto = NULL; + + gf_free((char *) inst->proto_name); + gf_list_del(inst->node_code); assert(!gf_list_count(inst->scripts_to_load)); gf_list_del(inst->scripts_to_load); if (inst->proto_interface) gf_list_del_item(inst->proto_interface->instances, inst); - sg = inst->sgprivate->scenegraph; - - gf_free((char *) inst->proto_name); - - /*and finally destroy the node. If the proto is a hardcoded one (UserCallback set), destroy the node first - since the hardcoded proto may need the scene graph when being destroyed*/ - if (inst->sgprivate->UserCallback) { - gf_sg_reset(sg); - sg->pOwningProto = NULL; - gf_node_free((GF_Node *)inst); - gf_sg_del(sg); - } else { - gf_sg_reset(sg); - sg->pOwningProto = NULL; - gf_node_free((GF_Node *)inst); - gf_sg_del(sg); - } + gf_node_free((GF_Node *)inst); + gf_sg_del(sg); } /*Note on ISed fields: we cannot support fan-in on proto, eg we assume only one eventIn field can receive events diff --git a/src/scenegraph/vrml_smjs.c b/src/scenegraph/vrml_smjs.c index b99aeac..0c6d4a0 100644 --- a/src/scenegraph/vrml_smjs.c +++ b/src/scenegraph/vrml_smjs.c @@ -306,7 +306,7 @@ JSContext *gf_sg_ecmascript_new(GF_SceneGraph *sg) GF_SAFEALLOC(js_rt, GF_JSRuntime); js_rt->js_runtime = js_runtime; js_rt->mx = gf_mx_new("JavaScript"); - GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[ECMAScript] ECMAScript runtime allocated 0x%08x\n", js_runtime)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[ECMAScript] ECMAScript runtime allocated %p\n", js_runtime)); gf_sg_load_script_modules(sg); } js_rt->nb_inst++; @@ -732,6 +732,12 @@ static void on_route_to_object(GF_Node *node, GF_Route *_r) if (JSVAL_IS_GCTHING(argv[0])) gf_js_remove_root(priv->js_ctx, &argv[0], GF_JSGC_VAL); if (JSVAL_IS_GCTHING(argv[1])) gf_js_remove_root(priv->js_ctx, &argv[1], GF_JSGC_VAL); + /*check any pending exception if outer-most event*/ + if ( (JS_IsRunning(priv->js_ctx)==JS_FALSE) && JS_IsExceptionPending(priv->js_ctx)) { + JS_ReportPendingException(priv->js_ctx); + JS_ClearPendingException(priv->js_ctx); + } + gf_sg_lock_javascript(priv->js_ctx, 0); #ifdef FORCE_GC @@ -1405,7 +1411,7 @@ static void node_finalize_ex(JSContext *c, JSObject *obj, Bool is_js_call) JS_ObjectDestroyed(c, obj, ptr, is_js_call); if (ptr) { - GF_Node *parent = (GF_Node *)JS_GetScript(ptr->js_ctx ? ptr->js_ctx : c); + JS_GetScript(ptr->js_ctx ? ptr->js_ctx : c); if (ptr->node /*num_instances may be 0 if the node is the script being destroyed*/ && ptr->node->sgprivate->num_instances @@ -3600,7 +3606,6 @@ static void gf_sg_script_update_cached_object(GF_ScriptPriv *priv, JSObject *obj { u32 i; jsval newVal; - GF_JSField *slot = NULL; JSString *s; /*we need to rebuild MF types where SF is a native type.*/ @@ -3809,7 +3814,7 @@ jsval gf_sg_script_to_smjs_field(GF_ScriptPriv *priv, GF_FieldInfo *field, GF_No && (jsf->field.far_ptr==field->far_ptr) #endif ) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[VRML JS] found cached jsobj 0x%08x (field %s) in script %s bank (%d entries)\n", obj, field->name, gf_node_get_log_name((GF_Node*)JS_GetScript(priv->js_ctx)), gf_list_count(priv->js_cache) ) ); + GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[VRML JS] found cached jsobj %p (field %s) in script %s bank (%d entries)\n", obj, field->name, gf_node_get_log_name((GF_Node*)JS_GetScript(priv->js_ctx)), gf_list_count(priv->js_cache) ) ); if (!force_evaluate && !jsf->field.NDTtype) return OBJECT_TO_JSVAL(obj); gf_sg_script_update_cached_object(priv, obj, jsf, field, parent); @@ -4089,8 +4094,6 @@ jsval gf_sg_script_to_smjs_field(GF_ScriptPriv *priv, GF_FieldInfo *field, GF_No static void JS_ReleaseRootObjects(GF_ScriptPriv *priv) { - u32 i=0; - while (gf_list_count(priv->js_cache)) { GF_JSField *jsf; /*we don't walk through the list since unprotecting an element could trigger GC which in turn could modify this list content*/ @@ -4275,6 +4278,12 @@ static void JS_EventIn(GF_Node *node, GF_FieldInfo *in_field) if (JSVAL_IS_GCTHING(argv[0])) gf_js_remove_root(priv->js_ctx, &argv[0], GF_JSGC_VAL); if (JSVAL_IS_GCTHING(argv[1])) gf_js_remove_root(priv->js_ctx, &argv[1], GF_JSGC_VAL); + /*check any pending exception if outer-most event*/ + if ( (JS_IsRunning(priv->js_ctx)==JS_FALSE) && JS_IsExceptionPending(priv->js_ctx)) { + JS_ReportPendingException(priv->js_ctx); + JS_ClearPendingException(priv->js_ctx); + } + gf_sg_lock_javascript(priv->js_ctx, 0); gf_js_vrml_flush_event_out(node, priv); @@ -4528,7 +4537,7 @@ static void JSScript_NodeModified(GF_SceneGraph *sg, GF_Node *node, GF_FieldInfo if (gf_list_del_item(sg->objects, node->sgprivate->interact->js_binding->node)>=0) { #ifndef GPAC_DISABLE_SVG - JSBool ret = gf_js_remove_root(sg->svg_js->js_ctx, &(node->sgprivate->interact->js_binding->node), GF_JSGC_OBJECT); + gf_js_remove_root(sg->svg_js->js_ctx, &(node->sgprivate->interact->js_binding->node), GF_JSGC_OBJECT); if (sg->svg_js->in_script) sg->svg_js->force_gc = 1; else @@ -4664,6 +4673,12 @@ void gf_sg_handle_dom_event_for_vrml(GF_Node *node, GF_DOM_Event *event, GF_Node ret = JS_CallFunctionName(priv->js_ctx, hdl->evt_listen_obj, "handleEvent", 1, argv, &rval); } + /*check any pending exception if outer-most event*/ + if (!prev_event && JS_IsExceptionPending(priv->js_ctx)) { + JS_ReportPendingException(priv->js_ctx); + JS_ClearPendingException(priv->js_ctx); + } + event->is_vrml = prev_type; JS_SetPrivate(priv->js_ctx, priv->event, prev_event); diff --git a/src/terminal/channel.c b/src/terminal/channel.c index 7247770..39c7d6a 100644 --- a/src/terminal/channel.c +++ b/src/terminal/channel.c @@ -633,6 +633,8 @@ void Channel_ReceiveSkipSL(GF_ClientService *serv, GF_Channel *ch, const char *S gf_es_lock(ch, 0); } + + static void gf_es_check_timing(GF_Channel *ch) { /*the first data received inits the clock - this is needed to handle clock dependencies on non-initialized @@ -670,6 +672,42 @@ static void gf_es_check_timing(GF_Channel *ch) } } + +void gf_es_dispatch_raw_media_au(GF_Channel *ch, char *payload, u32 payload_size, u32 cts) +{ + GF_CompositionMemory *cb; + GF_CMUnit *cu; + if (!payload || !ch->odm->codec->CB) return; + if (!ch->odm->codec->CB->no_allocation) return; + + cb = ch->odm->codec->CB; + cu = gf_cm_lock_input(cb, cts, 1); + if (cu) { + u32 size = 0; + assert(cu->RenderedLength==0); + if (cb->UnitSize >= payload_size) { + cu->data = payload; + size = payload_size; + cu->TS = cts; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[ODM%d] Raw Frame dispatched to CB - TS %d ms\n", ch->odm->OD->objectDescriptorID, cu->TS)); + } + gf_cm_unlock_input(cb, cu, size, 1); + + if (ch->BufferOn) { + ch->BufferOn = 0; + gf_clock_buffer_off(ch->clock); + gf_cm_abort_buffering(cb); + } + /*since the CB is a simple pointer to the input frame, wait until it is released before getting + back to the caller module*/ + if (size) { + gf_sema_wait(ch->odm->raw_frame_sema); + assert(cb->output->dataLength == 0); + } + } +} + + /*handles reception of an SL-PDU, logical or physical*/ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *payload, u32 payload_size, GF_SLHeader *header, GF_Err reception_status) { @@ -693,6 +731,20 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *paylo if (ch->es_state != GF_ESM_ES_RUNNING) return; + if (ch->skip_sl) { + Channel_ReceiveSkipSL(serv, ch, payload, payload_size); + return; + } + if (ch->is_raw_channel) { + ch->CTS = ch->DTS = (u32) (ch->ts_offset + (header->compositionTimeStamp - ch->seed_ts) * 1000 / ch->ts_res); + if (!ch->IsClockInit) { + gf_es_check_timing(ch); + } + if (payload) + gf_es_dispatch_raw_media_au(ch, payload, payload_size, ch->CTS); + return; + } + /*physical SL-PDU - depacketize*/ if (!header) { u32 SLHdrLen; @@ -704,11 +756,6 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *paylo hdr = *header; } - if (ch->skip_sl) { - Channel_ReceiveSkipSL(serv, ch, payload, payload_size); - return; - } - /*we ignore OCRs for the moment*/ if (hdr.OCRflag) { if (!ch->IsClockInit) { @@ -723,8 +770,12 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *paylo } ch->clock->clock_init = 0; gf_clock_set_time(ch->clock, OCR_TS); + /*many TS streams deployed with HLS have broken PCRs - we will check their consistency + when receiving the first AU with DTS/CTS on this channel*/ + ch->clock->probe_ocr = 1; GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] ES%d: initializing clock at STB %d from OCR TS %d (origial TS "LLD") - %d buffering - OTB %d\n", ch->esd->ESID, gf_term_get_time(ch->odm->term), OCR_TS, hdr.objectClockReference, ch->clock->Buffering, gf_clock_time(ch->clock) )); if (ch->clock->clock_init) ch->IsClockInit = 1; + } } #if 0 @@ -749,6 +800,18 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *paylo GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] ES%d: At OTB %d adjusting OCR to %d (origial TS "LLD") - diff %d\n", ch->esd->ESID, gf_clock_real_time(ch->clock), OCR_TS, hdr.objectClockReference, (s32) OCR_TS - (s32) ck)); // gf_clock_set_time(ch->clock, (u32) OCR_TS); } +#else + { + u32 ck; + u32 OCR_TS; + if (hdr.m2ts_pcr) { + OCR_TS = (u32) ( hdr.objectClockReference / 27000); + } else { + OCR_TS = (u32) ( (s64) (hdr.objectClockReference) * ch->ocr_scale); + } + ck = gf_clock_time(ch->clock); + GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] ES%d: At OTB %d got OCR %d (origial TS "LLD") - diff %d%s\n", ch->esd->ESID, gf_clock_real_time(ch->clock), OCR_TS, hdr.objectClockReference, (s32) OCR_TS - (s32) ck, (hdr.m2ts_pcr==2) ? " - PCR Discontinuity flag" : "" )); + } #endif if (!payload_size) return; } @@ -842,6 +905,7 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *paylo if (!ch->IsClockInit && (ch->net_dts < ch->seed_ts)) ch->seed_ts = ch->net_dts; #endif + if (ch->net_ctsseed_ts) { u64 diff = ch->seed_ts - ch->net_cts; @@ -860,6 +924,17 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *paylo ch->DTS = (u32) (ch->ts_offset + (s64) (ch->net_dts) * 1000 / ch->ts_res); } + if (ch->clock->probe_ocr && gf_es_owns_clock(ch)) { + s32 diff_ts = ch->DTS; + diff_ts -= ch->clock->init_time; + if (ABS(diff_ts) > 10000) { + GF_LOG(GF_LOG_ERROR, GF_LOG_SYNC, ("[SyncLayer] ES%d: invalid clock reference detected - DTS %d OCR %d - using DTS as OCR\n", ch->DTS, ch->clock->init_time)); + ch->clock->clock_init = 0; + gf_clock_set_time(ch->clock, ch->DTS-1000); + } + ch->clock->probe_ocr = 0; + } + ch->no_timestamps = 0; } else { ch->no_timestamps = 1; @@ -1140,6 +1215,7 @@ GF_DBUnit *gf_es_get_au(GF_Channel *ch) /*update timing if new stream data but send no data*/ if (is_new_data) { gf_es_receive_sl_packet(ch->service, ch, NULL, 0, &slh, GF_OK); + if (ch->ipmp_tool) { GF_IPMPEvent evt; memset(&evt, 0, sizeof(evt)); @@ -1450,7 +1526,7 @@ void gf_es_config_drm(GF_Channel *ch, GF_NetComDRMConfig *drm_cfg) gf_modules_close_interface((GF_BaseInterface *) ch->ipmp_tool); ch->ipmp_tool = NULL; } - gf_term_message(ch->odm->term, ch->service->url, "No IPMP tool suitable to handle channel protection", GF_NOT_SUPPORTED); + GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("[IPMP] No IPMP tool suitable to handle channel protection scheme %s (KMS URI %s)\n", drm_cfg->scheme_uri, drm_cfg->kms_uri)); ch_buffer_off(ch); } diff --git a/src/terminal/decoder.c b/src/terminal/decoder.c index 047fcfc..38b3081 100644 --- a/src/terminal/decoder.c +++ b/src/terminal/decoder.c @@ -33,6 +33,7 @@ #include "input_sensor.h" GF_Err Codec_Load(GF_Codec *codec, GF_ESD *esd, u32 PL); +GF_Err gf_codec_process_raw_media_pull(GF_Codec *codec, u32 TimeAvailable); GF_Codec *gf_codec_new(GF_ObjectManager *odm, GF_ESD *base_layer, s32 PL, GF_Err *e) { @@ -59,7 +60,7 @@ GF_Codec *gf_codec_new(GF_ObjectManager *odm, GF_ESD *base_layer, s32 PL, GF_Err if (tmp->type==GF_STREAM_PRIVATE_MEDIA) tmp->type = GF_STREAM_VISUAL; - GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[Codec] Found decoder %s for stream type %s\n", tmp->decio->module_name, gf_esd_get_textual_description(base_layer) )); + GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[Codec] Found decoder %s for stream type %s\n", tmp->decio ? tmp->decio->module_name : "RAW", gf_esd_get_textual_description(base_layer) )); return tmp; } @@ -160,9 +161,15 @@ GF_Err gf_codec_add_channel(GF_Codec *codec, GF_Channel *ch) /*setup CB*/ if (!codec->CB && max) { + if (codec->flags & GF_ESM_CODEC_IS_RAW_MEDIA) { + max = 1; + /*create a semaphore in non-notified stage*/ + codec->odm->raw_frame_sema = gf_sema_new(1, 0); + } + GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[ODM] Creating composition buffer for codec %s - %d units %d bytes each\n", codec->decio->module_name, max, CUsize)); - codec->CB = gf_cm_new(CUsize, max); + codec->CB = gf_cm_new(CUsize, max, (codec->flags & GF_ESM_CODEC_IS_RAW_MEDIA) ? 1 : 0); codec->CB->Min = min; codec->CB->odm = codec->odm; } @@ -175,6 +182,10 @@ GF_Err gf_codec_add_channel(GF_Codec *codec, GF_Channel *ch) codec->is_reordering = cap.cap.valueInt; } + if (codec->flags & GF_ESM_CODEC_IS_RAW_MEDIA) { + ch->is_raw_channel = 1; + } + /*setup net channel config*/ if (ch->service) { memset(&com, 0, sizeof(GF_NetworkCommand)); @@ -208,8 +219,27 @@ GF_Err gf_codec_add_channel(GF_Codec *codec, GF_Channel *ch) } } + } else if (codec->flags & GF_ESM_CODEC_IS_RAW_MEDIA) { + cap.CapCode = GF_CODEC_OUTPUT_SIZE; + gf_codec_get_capability(codec, &cap); + if (codec->CB && (cap.cap.valueInt != codec->CB->UnitSize)) { + gf_cm_del(codec->CB); + codec->CB = NULL; + } + CUsize = cap.cap.valueInt; + /*create a semaphore in non-notified stage*/ + codec->odm->raw_frame_sema = gf_sema_new(1, 0); + + codec->CB = gf_cm_new(CUsize, 1, 1); + codec->CB->Min = 0; + codec->CB->odm = codec->odm; + ch->is_raw_channel = 1; + if (ch->is_pulling) { + codec->process = gf_codec_process_raw_media_pull; + } } + /*assign the first base layer as the codec clock by default, or current channel clock if no clock set Also assign codec priority here*/ if (!ch->esd->dependsOnESID || !codec->ck) { @@ -453,7 +483,7 @@ check_unit: gf_scene_regenerate(scene); scene->graph_attached = 2; scene->is_dynamic_scene = prev_dyn; - GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[Decoder] Got OD resources before scene - generating temporary scene\n")); + GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[Decoder] Got OD resources before scene - generating temporary scene\n")); } } @@ -673,8 +703,6 @@ static GF_Err MediaCodec_Process(GF_Codec *codec, u32 TimeAvailable) gf_es_drop_au(ch); return GF_OK; } - codec->nb_repeted_frames = 0; - memcpy(codec->last_unit_signature, new_unit_signature, sizeof(new_unit_signature)); /*usually only one image is tolerated in the stream, but just in case force reset of CB*/ if (codec->CB->UnitCount && (obj_time>=AU->CTS)) { @@ -683,6 +711,14 @@ static GF_Err MediaCodec_Process(GF_Codec *codec, u32 TimeAvailable) codec->CB->UnitCount = 0; gf_mx_v(codec->odm->mx); } + + /*CB is already full*/ + if (codec->CB->UnitCount) + return GF_OK; + + codec->nb_repeted_frames = 0; + memcpy(codec->last_unit_signature, new_unit_signature, sizeof(new_unit_signature)); + } /*try to refill the full buffer*/ @@ -712,11 +748,11 @@ static GF_Err MediaCodec_Process(GF_Codec *codec, u32 TimeAvailable) NOTE: the 100 ms safety gard is to avoid discarding audio*/ if (!ch->skip_sl && (AU->CTS + 100 < obj_time) ) { mmlevel = GF_CODEC_LEVEL_DROP; - GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[%s] ODM%d: frame too late (%d vs %d) - using drop level\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, AU->CTS, obj_time)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[%s] ODM%d: frame too late (%d vs %d) - using drop level\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, AU->CTS, obj_time)); if (ch->resync_drift && (AU->CTS + ch->resync_drift < obj_time)) { ch->clock->StartTime += (obj_time - AU->CTS); - GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[%s] ODM%d: decoder too slow on OCR stream - rewinding clock of %d ms\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, obj_time - AU->CTS)); + GF_LOG(GF_LOG_WARNING, GF_LOG_CODEC, ("[%s] ODM%d: decoder too slow on OCR stream - rewinding clock of %d ms\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, obj_time - AU->CTS)); obj_time = gf_clock_time(codec->ck); } } @@ -805,15 +841,12 @@ scalable_retry: processing a scalable stream*/ case GF_OK: if (unit_size) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_RTI|GF_LOG_CODEC, ("[%s] ODM%d at %d decoded frame TS %d in %d ms (DTS %d)\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, gf_clock_real_time(ch->clock), AU->CTS, now, AU->DTS)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_RTI|GF_LOG_CODEC, ("[%s] ODM%d at %d decoded frame TS %d in %d ms (DTS %d) - %d in CB\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, gf_clock_real_time(ch->clock), AU->CTS, now, AU->DTS, codec->CB->UnitCount + 1)); } /*if no size the decoder is not using the composition memory - if the object is in intitial buffering resume it!!*/ else if (codec->CB->Status == CB_BUFFER) { gf_cm_abort_buffering(codec->CB); } - /*in seek don't dispatch any output*/ - if (mmlevel == GF_CODEC_LEVEL_SEEK) - unit_size = 0; codec_update_stats(codec, AU->dataLength, now); if (ch->skip_sl) { @@ -829,7 +862,7 @@ scalable_retry: } #ifndef GPAC_DISABLE_LOGS if (codec->odm->flags & GF_ODM_PREFETCH) { - GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[%s] ODM%d At %d decoding frame TS %d in prefetch mode\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, gf_clock_real_time(ch->clock) )); + GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[%s] ODM%d At %d decoding frame TS %d in prefetch mode\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, gf_clock_real_time(ch->clock), AU->CTS)); } #endif break; @@ -837,7 +870,7 @@ scalable_retry: unit_size = 0; /*error - if the object is in intitial buffering resume it!!*/ gf_cm_abort_buffering(codec->CB); - GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[%s] ODM%d At %d (frame TS %d - %d ms ): decoded error %s\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, gf_clock_real_time(ch->clock), AU->CTS, now, gf_error_to_string(e) )); + GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[%s] ODM%d At %d (frame TS %d - %d ms ): decoded error %s\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, gf_clock_real_time(ch->clock), AU->CTS, now, gf_error_to_string(e) )); e = GF_OK; break; } @@ -862,8 +895,14 @@ drop: Decoder_GetNextAU(codec, &ch, &AU); /*same CTS: same output, likely scalable stream so don't release the CB*/ - if (AU && (AU->CTS == cts) && (ch !=prev_ch) ) + if (AU && (AU->CTS == cts) && (ch !=prev_ch) ) { + unit_size = codec->CB->UnitSize; goto scalable_retry; + } + + /*in seek don't dispatch any output*/ + if (mmlevel == GF_CODEC_LEVEL_SEEK) + unit_size = 0; UnlockCompositionUnit(codec, CU, unit_size); if (!ch || !AU) return GF_OK; @@ -882,6 +921,54 @@ drop: } +GF_Err gf_codec_process_private_media(GF_Codec *codec, u32 TimeAvailable) +{ + + if (codec->ck && codec->ck->Paused) { + u32 i; + for (i=0; iodm->channels); i++) { + GF_Channel *ch = gf_list_get(codec->odm->channels, i); + if (ch->BufferOn) { + ch->BufferOn = 0; + gf_clock_buffer_off(ch->clock); + } + } + if (codec->CB) + gf_cm_abort_buffering(codec->CB); + } + return GF_OK; +} + + +GF_Err gf_codec_process_raw_media_pull(GF_Codec *codec, u32 TimeAvailable) +{ + GF_Channel *ch; + GF_DBUnit *db; + if (codec->ck && codec->ck->Paused) { + u32 i; + for (i=0; iodm->channels); i++) { + ch = gf_list_get(codec->odm->channels, i); + if (ch->BufferOn) { + ch->BufferOn = 0; + gf_clock_buffer_off(ch->clock); + } + } + if (codec->CB) + gf_cm_abort_buffering(codec->CB); + } + + /*this will pull the next AU from the service */ + Decoder_GetNextAU(codec, &ch, &db); + if (!db) return GF_OK; + + /*dispatch raw media - this call is blocking untill the cu has been consumed */ + gf_es_dispatch_raw_media_au(ch, db->data, db->dataLength, db->CTS); + + /*release AU from service*/ + gf_term_channel_release_sl_packet(ch->service, ch); + return GF_OK; +} + GF_Err gf_codec_process_ocr(GF_Codec *codec, u32 TimeAvailable) { /*OCR: needed for OCR in pull mode (dummy streams used to sync various sources)*/ @@ -920,8 +1007,62 @@ GF_Err gf_codec_process(GF_Codec *codec, u32 TimeAvailable) GF_Err gf_codec_get_capability(GF_Codec *codec, GF_CodecCapability *cap) { cap->cap.valueInt = 0; - if (!codec->decio) return GF_OK; - return codec->decio->GetCapabilities(codec->decio, cap); + if (codec->decio) + return codec->decio->GetCapabilities(codec->decio, cap); + + if (codec->flags & GF_ESM_CODEC_IS_RAW_MEDIA) { + GF_BitStream *bs; + u32 pf, w, h, stride, out_size, sr, nb_ch, bpp, ch_cfg; + GF_Channel *ch = gf_list_get(codec->odm->channels, 0); + if (!ch || !ch->esd->decoderConfig->decoderSpecificInfo || !ch->esd->decoderConfig->decoderSpecificInfo->data) return 0; + bs = gf_bs_new(ch->esd->decoderConfig->decoderSpecificInfo->data, ch->esd->decoderConfig->decoderSpecificInfo->dataLength, GF_BITSTREAM_READ); + + pf = w = h = sr = nb_ch = bpp = ch_cfg = 0; + if (codec->type==GF_STREAM_VISUAL) { + pf = gf_bs_read_u32(bs); + w = gf_bs_read_u16(bs); + h = gf_bs_read_u16(bs); + out_size = gf_bs_read_u32(bs); + stride = gf_bs_read_u32(bs); + } else { + sr = gf_bs_read_u32(bs); + nb_ch = gf_bs_read_u16(bs); + bpp = gf_bs_read_u16(bs); + out_size = gf_bs_read_u32(bs); + ch_cfg = gf_bs_read_u32(bs); + } + gf_bs_del(bs); + switch (cap->CapCode) { + case GF_CODEC_WIDTH: + cap->cap.valueInt = w; + return GF_OK; + case GF_CODEC_HEIGHT: + cap->cap.valueInt = h; + return GF_OK; + case GF_CODEC_STRIDE: + cap->cap.valueInt = stride; + return GF_OK; + case GF_CODEC_PIXEL_FORMAT: + cap->cap.valueInt = pf; + return GF_OK; + case GF_CODEC_OUTPUT_SIZE: + cap->cap.valueInt = out_size; + return GF_OK; + case GF_CODEC_SAMPLERATE: + cap->cap.valueInt = sr; + return GF_OK; + case GF_CODEC_NB_CHAN: + cap->cap.valueInt = nb_ch; + return GF_OK; + case GF_CODEC_BITS_PER_SAMPLE: + cap->cap.valueInt = bpp; + return GF_OK; + case GF_CODEC_CHANNEL_CONFIG: + cap->cap.valueInt = ch_cfg; + return GF_OK; + } + } + return GF_BAD_PARAM; } GF_Err gf_codec_set_capability(GF_Codec *codec, GF_CodecCapability cap) @@ -976,11 +1117,11 @@ static GF_Err Codec_LoadModule(GF_Codec *codec, GF_ESD *esd, u32 PL) { char szPrefDec[500]; const char *sOpt; - GF_BaseDecoder *ifce; + GF_BaseDecoder *ifce, *dec_ifce; u32 i, plugCount; u32 ifce_type; char *cfg; - u32 cfg_size; + u32 cfg_size, dec_confidence; GF_Terminal *term = codec->odm->term; if (esd->decoderConfig->decoderSpecificInfo) { @@ -1000,7 +1141,7 @@ static GF_Err Codec_LoadModule(GF_Codec *codec, GF_ESD *esd, u32 PL) break; case GF_STREAM_PRIVATE_MEDIA: ifce_type = GF_PRIVATE_MEDIA_DECODER_INTERFACE; - codec->process = MediaCodec_Process; + codec->process = gf_codec_process_private_media; break; case GF_STREAM_PRIVATE_SCENE: ifce_type = GF_SCENE_DECODER_INTERFACE; @@ -1036,28 +1177,51 @@ static GF_Err Codec_LoadModule(GF_Codec *codec, GF_ESD *esd, u32 PL) } } + dec_confidence = 0; + ifce = NULL; + if (sOpt) { ifce = (GF_BaseDecoder *) gf_modules_load_interface_by_name(term->user->modules, sOpt, ifce_type); if (ifce) { - if (ifce->CanHandleStream && ifce->CanHandleStream(ifce, esd->decoderConfig->streamType, esd, PL) ) { - codec->decio = ifce; - return GF_OK; + if (ifce->CanHandleStream) { + dec_confidence = ifce->CanHandleStream(ifce, esd->decoderConfig->streamType, esd, PL); + if (dec_confidence==GF_CODEC_SUPPORTED) { + codec->decio = ifce; + return GF_OK; + } + if (dec_confidence==GF_CODEC_NOT_SUPPORTED) { + gf_modules_close_interface((GF_BaseInterface *) ifce); + ifce = NULL; + } + } else { + gf_modules_close_interface((GF_BaseInterface *) ifce); } - gf_modules_close_interface((GF_BaseInterface *) ifce); } } + dec_ifce = ifce; /*prefered codec module per streamType/objectType from config*/ sprintf(szPrefDec, "codec_%02X_%02X", esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication); sOpt = gf_cfg_get_key(term->user->config, "Systems", szPrefDec); if (sOpt) { ifce = (GF_BaseDecoder *) gf_modules_load_interface_by_name(term->user->modules, sOpt, ifce_type); if (ifce) { - if (ifce->CanHandleStream && ifce->CanHandleStream(ifce, esd->decoderConfig->streamType, esd, PL) ) { - codec->decio = ifce; - return GF_OK; + if (ifce->CanHandleStream) { + u32 conf = ifce->CanHandleStream(ifce, esd->decoderConfig->streamType, esd, PL); + if ((conf!=GF_CODEC_NOT_SUPPORTED) && (conf>=dec_confidence)) { + /*switch*/ + if (dec_ifce) gf_modules_close_interface((GF_BaseInterface *) dec_ifce); + dec_confidence = conf; + dec_ifce = ifce; + ifce = NULL; + if (dec_confidence==GF_CODEC_SUPPORTED) { + codec->decio = dec_ifce; + return GF_OK; + } + } } - gf_modules_close_interface((GF_BaseInterface *) ifce); + if (ifce) + gf_modules_close_interface((GF_BaseInterface *) ifce); } } /*not found, check all modules*/ @@ -1065,14 +1229,28 @@ static GF_Err Codec_LoadModule(GF_Codec *codec, GF_ESD *esd, u32 PL) for (i = 0; i < plugCount ; i++) { ifce = (GF_BaseDecoder *) gf_modules_load_interface(term->user->modules, i, ifce_type); if (!ifce) continue; - if (ifce->CanHandleStream && ifce->CanHandleStream(ifce, esd->decoderConfig->streamType, esd, PL) ) { - codec->decio = ifce; - sprintf(szPrefDec, "codec_%02X_%02X", esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication); - gf_cfg_set_key(term->user->config, "Systems", szPrefDec, ifce->module_name); - return GF_OK; + if (ifce->CanHandleStream) { + u32 conf = ifce->CanHandleStream(ifce, esd->decoderConfig->streamType, esd, PL); + + if ((conf!=GF_CODEC_NOT_SUPPORTED) && (conf>dec_confidence)) { + /*switch*/ + if (dec_ifce) gf_modules_close_interface((GF_BaseInterface *) dec_ifce); + dec_confidence = conf; + dec_ifce = ifce; + ifce = NULL; + } } - gf_modules_close_interface((GF_BaseInterface *) ifce); + if (ifce) + gf_modules_close_interface((GF_BaseInterface *) ifce); + } + + if (dec_ifce) { + codec->decio = dec_ifce; + sprintf(szPrefDec, "codec_%02X_%02X", esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication); + gf_cfg_set_key(term->user->config, "Systems", szPrefDec, dec_ifce->module_name); + return GF_OK; } + return GF_CODEC_NOT_FOUND; } @@ -1098,6 +1276,12 @@ GF_Err Codec_Load(GF_Codec *codec, GF_ESD *esd, u32 PL) case GF_STREAM_AUDIO: if (!esd->decoderConfig->objectTypeIndication) return GF_NON_COMPLIANT_BITSTREAM; + + if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_RAW_MEDIA_STREAM) { + codec->flags |= GF_ESM_CODEC_IS_RAW_MEDIA; + codec->process = gf_codec_process_private_media; + return GF_OK; + } default: return Codec_LoadModule(codec, esd, PL); } @@ -1122,7 +1306,8 @@ void gf_codec_del(GF_Codec *codec) break; #endif default: - gf_modules_close_interface((GF_BaseInterface *) codec->decio); + if (codec->decio) + gf_modules_close_interface((GF_BaseInterface *) codec->decio); break; } } diff --git a/src/terminal/media_manager.c b/src/terminal/media_manager.c index bc30fdd..9f0e297 100644 --- a/src/terminal/media_manager.c +++ b/src/terminal/media_manager.c @@ -126,7 +126,7 @@ void gf_term_add_codec(GF_Terminal *term, GF_Codec *codec) GF_CodecCapability cap; assert(codec); - GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Registering codec %s\n", codec->decio ? codec->decio->module_name : "Unknown")); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Registering codec %s\n", codec->decio ? codec->decio->module_name : "RAW")); /*caution: the mutex can be grabbed by a decoder waiting for a mutex owned by the calling thread this happens when several scene codecs are running concurently and triggering play/pause on media*/ @@ -217,7 +217,7 @@ void gf_term_remove_codec(GF_Terminal *term, GF_Codec *codec) Bool locked; CodecEntry *ce; - GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Unregistering codec %s\n", codec->decio ? codec->decio->module_name : "Unknown")); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Unregistering codec %s\n", codec->decio ? codec->decio->module_name : "RAW")); /*cf note above*/ locked = gf_mx_try_lock(term->mm_mx); @@ -302,14 +302,16 @@ static u32 MM_SimulationStep_Decoder(GF_Terminal *term) time_taken = gf_sys_clock(); e = gf_codec_process(ce->dec, time_slice); + time_taken = gf_sys_clock() - time_taken; /*avoid signaling errors too often...*/ #ifndef GPAC_DISABLE_LOG - if (e) GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[ODM%d] Decoding Error %s\n", ce->dec->odm->OD->objectDescriptorID, gf_error_to_string(e) )); + if (e) { + GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[ODM%d] Decoding Error %s\n", ce->dec->odm->OD->objectDescriptorID, gf_error_to_string(e) )); + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[%s] Decode time slice %d ms out of %d ms\n", ce->dec->decio ? ce->dec->decio->module_name : "RAW", time_taken, time_left )); + } #endif - - time_taken = gf_sys_clock() - time_taken; - if (ce->flags & GF_MM_CE_DISCRADED) { gf_free(ce); gf_list_rem(term->codecs, term->last_codec); @@ -318,11 +320,11 @@ static u32 MM_SimulationStep_Decoder(GF_Terminal *term) if (ce->dec->CB && (ce->dec->CB->UnitCount >= ce->dec->CB->Min)) ce->dec->PriorityBoost = 0; } + term->last_codec = (term->last_codec + 1) % count; + remain -= 1; if (!remain) break; - term->last_codec = (term->last_codec + 1) % count; - if (time_left > time_taken) { time_left -= time_taken; } else { diff --git a/src/terminal/media_memory.c b/src/terminal/media_memory.c index f3159ce..892c131 100644 --- a/src/terminal/media_memory.c +++ b/src/terminal/media_memory.c @@ -84,20 +84,22 @@ static GFINLINE void my_large_gf_free(void *ptr) { #endif -static void gf_cm_unit_del(GF_CMUnit *cb) +static void gf_cm_unit_del(GF_CMUnit *cb, Bool no_data_allocation) { if (!cb) return; - if (cb->next) gf_cm_unit_del(cb->next); + if (cb->next) gf_cm_unit_del(cb->next, no_data_allocation); cb->next = NULL; if (cb->data) { - my_large_gf_free(cb->data); + if (!no_data_allocation) { + my_large_gf_free(cb->data); + } cb->data = NULL; } gf_free(cb); } -GF_CompositionMemory *gf_cm_new(u32 UnitSize, u32 capacity) +GF_CompositionMemory *gf_cm_new(u32 UnitSize, u32 capacity, Bool no_allocation) { GF_CompositionMemory *tmp; GF_CMUnit *cu, *prev; @@ -108,6 +110,7 @@ GF_CompositionMemory *gf_cm_new(u32 UnitSize, u32 capacity) tmp->Capacity = capacity; tmp->UnitSize = UnitSize; + tmp->no_allocation = no_allocation; prev = NULL; i = 1; @@ -120,8 +123,12 @@ GF_CompositionMemory *gf_cm_new(u32 UnitSize, u32 capacity) cu->prev = prev; } cu->dataLength = 0; - cu->data = UnitSize ? (char*)my_large_alloc(sizeof(char)*UnitSize) : NULL; - if (cu->data) memset(cu->data, 0, sizeof(char)*UnitSize); + if (no_allocation) { + cu->data = NULL; + } else { + cu->data = UnitSize ? (char*)my_large_alloc(sizeof(char)*UnitSize) : NULL; + if (cu->data) memset(cu->data, 0, sizeof(char)*UnitSize); + } prev = cu; capacity --; i++; @@ -148,7 +155,7 @@ void gf_cm_del(GF_CompositionMemory *cb) if (cb->input){ /*break the loop and destroy*/ cb->input->prev->next = NULL; - gf_cm_unit_del(cb->input); + gf_cm_unit_del(cb->input, cb->no_allocation); cb->input = NULL; } gf_odm_lock(cb->odm, 0); @@ -372,6 +379,11 @@ void gf_cm_reset(GF_CompositionMemory *cb) cu = cb->input; cu->RenderedLength = 0; + if (cu->dataLength && cb->odm->raw_frame_sema) { + cu->dataLength = 0; + gf_sema_notify(cb->odm->raw_frame_sema, 1); + } + cu->dataLength = 0; cu->TS = 0; cu = cu->next; @@ -400,12 +412,24 @@ void gf_cm_resize(GF_CompositionMemory *cb, u32 newCapacity) cu = cb->input; cb->UnitSize = newCapacity; - my_large_gf_free(cu->data); - cu->data = (char*) my_large_alloc(newCapacity); - cu = cu->next; - while (cu != cb->input) { + if (!cb->no_allocation) { my_large_gf_free(cu->data); cu->data = (char*) my_large_alloc(newCapacity); + } else { + cu->data = NULL; + if (cu->dataLength && cb->odm->raw_frame_sema) { + cu->dataLength = 0; + gf_sema_notify(cb->odm->raw_frame_sema, 1); + } + } + cu = cu->next; + while (cu != cb->input) { + if (!cb->no_allocation) { + my_large_gf_free(cu->data); + cu->data = (char*) my_large_alloc(newCapacity); + } else { + cu->data = NULL; + } cu = cu->next; } @@ -425,7 +449,7 @@ void gf_cm_reinit(GF_CompositionMemory *cb, u32 UnitSize, u32 Capacity) if (cb->input){ /*break the loop and destroy*/ cb->input->prev->next = NULL; - gf_cm_unit_del(cb->input); + gf_cm_unit_del(cb->input, cb->no_allocation); cb->input = NULL; } @@ -444,7 +468,11 @@ void gf_cm_reinit(GF_CompositionMemory *cb, u32 UnitSize, u32 Capacity) cu->prev = prev; } cu->dataLength = 0; - cu->data = (char*)my_large_alloc(UnitSize); + if (cb->no_allocation) { + cu->data = NULL; + } else { + cu->data = (char*)my_large_alloc(UnitSize); + } prev = cu; Capacity --; i++; @@ -523,9 +551,13 @@ void gf_cm_drop_output(GF_CompositionMemory *cb) /*this allows reuse of the CU*/ cb->output->RenderedLength = 0; cb->LastRenderedTS = cb->output->TS; + if (cb->odm->raw_frame_sema) { + cb->output->dataLength = 0; + gf_sema_notify(cb->odm->raw_frame_sema, 1); + } - /*on visual streams, always keep the last AU*/ - if (cb->output->dataLength && (cb->odm->codec->type == GF_STREAM_VISUAL) ) { + /*on visual streams (except raw oness), always keep the last AU*/ + if (!cb->no_allocation && cb->output->dataLength && (cb->odm->codec->type == GF_STREAM_VISUAL) ) { if ( !cb->output->next->dataLength || (cb->Capacity == 1) ) { return; } diff --git a/src/terminal/media_memory.h b/src/terminal/media_memory.h index 76b836c..5a2d5e3 100644 --- a/src/terminal/media_memory.h +++ b/src/terminal/media_memory.h @@ -110,6 +110,7 @@ struct _composition_memory u32 Min; /*Unit size is the size of each buffer*/ u32 UnitSize; + Bool no_allocation; /*Status of the buffer*/ u32 Status; @@ -127,7 +128,7 @@ struct _composition_memory }; /*a composition buffer only has fixed-size unit*/ -GF_CompositionMemory *gf_cm_new(u32 UnitSize, u32 capacity); +GF_CompositionMemory *gf_cm_new(u32 UnitSize, u32 capacity, Bool no_allocation); void gf_cm_del(GF_CompositionMemory *cb); /*re-inits complete cb*/ void gf_cm_reinit(GF_CompositionMemory *cb, u32 UnitSize, u32 Capacity); diff --git a/src/terminal/media_object.c b/src/terminal/media_object.c index 79e1efd..36367e7 100644 --- a/src/terminal/media_object.c +++ b/src/terminal/media_object.c @@ -453,6 +453,8 @@ void gf_mo_release_data(GF_MediaObject *mo, u32 nb_bytes, s32 forceDrop) gf_odm_lock(mo->odm, 0); return; } + if (mo->odm->codec->CB->no_allocation) + forceDrop = 1; /*perform a sanity check on TS since the CB may have changed status - this may happen in temporal scalability only*/ @@ -567,6 +569,9 @@ void gf_mo_play(GF_MediaObject *mo, Double clipBegin, Double clipEnd, Bool can_l mo->odm->media_stop_time = 0; } } + /*done prefetching*/ + mo->odm->flags &= ~GF_ODM_PREFETCH; + if (is_restart) { mediacontrol_restart(mo->odm); } else { @@ -759,7 +764,7 @@ Bool gf_mo_is_same_url(GF_MediaObject *obj, MFURL *an_url, Bool *keep_fragment, /*check on full URL without removing fragment IDs*/ if (include_sub_url) { for (i=0; icount; i++) { - if (!stricmp(szURL1, an_url->vals[i].url)) return 1; + if (an_url->vals[i].url && !stricmp(szURL1, an_url->vals[i].url)) return 1; } return 0; } @@ -952,12 +957,11 @@ Bool gf_mo_is_done(GF_MediaObject *mo) u64 dur; if (!gf_odm_lock_mo(mo)) return 0; - /*for natural media use composition buffer*/ - if (mo->odm->codec && mo->odm->codec->CB) + if (mo->odm->codec && mo->odm->codec->CB) { + /*for natural media use composition buffer*/ res = (mo->odm->codec->CB->Status==CB_STOP) ? 1 : 0; - - /*otherwise check EOS and time*/ - else { + } else { + /*otherwise check EOS and time*/ codec = mo->odm->codec; dur = mo->odm->duration; if (!mo->odm->codec) { @@ -1017,13 +1021,16 @@ Bool gf_mo_is_private_media(GF_MediaObject *mo) } GF_EXPORT -void gf_mo_set_position(GF_MediaObject *mo, GF_Window *src, GF_Window *dst) +Bool gf_mo_set_position(GF_MediaObject *mo, GF_Window *src, GF_Window *dst) { + GF_Err e; GF_PrivateMediaDecoder *dec; - if (!mo->odm || !mo->odm->codec || !mo->odm->codec->decio || (mo->odm->codec->decio->InterfaceType!=GF_PRIVATE_MEDIA_DECODER_INTERFACE)) return; + if (!mo->odm || !mo->odm->codec || !mo->odm->codec->decio || (mo->odm->codec->decio->InterfaceType!=GF_PRIVATE_MEDIA_DECODER_INTERFACE)) return 0; dec = (GF_PrivateMediaDecoder*)mo->odm->codec->decio; - dec->Control(dec, 0, src, dst); + e = dec->Control(dec, 0, src, dst); + if (e==GF_BUFFER_TOO_SMALL) return 1; + return 0; } GF_EXPORT diff --git a/src/terminal/media_sensor.c b/src/terminal/media_sensor.c index 75f4e5b..9c5afd0 100644 --- a/src/terminal/media_sensor.c +++ b/src/terminal/media_sensor.c @@ -107,7 +107,7 @@ void MS_Modified(GF_Node *node) gf_mo_unregister(node, st->stream); if (st->sensor->isActive) { st->sensor->isActive = 0; - gf_node_event_out_str((GF_Node *) st->sensor, "isActive"); + gf_node_event_out((GF_Node *) st->sensor, 4/*"isActive"*/); } } st->stream = gf_mo_register(node, &st->sensor->url, 0, 0); @@ -138,7 +138,7 @@ void mediasensor_update_timing(GF_ObjectManager *odm, Bool is_eos) if (ck->has_seen_eos && (1000*time>=(Double) (s64)odm->subscene->duration)) { if (media_sens->sensor->isActive) { media_sens->sensor->isActive = 0; - gf_node_event_out_str((GF_Node *) media_sens->sensor, "isActive"); + gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/); GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[ODM%d] Deactivating media sensor\n", odm->OD->objectDescriptorID)); } @@ -148,7 +148,7 @@ void mediasensor_update_timing(GF_ObjectManager *odm, Bool is_eos) if (!is_eos && !media_sens->sensor->isActive) { media_sens->sensor->isActive = 1; - gf_node_event_out_str((GF_Node *) media_sens->sensor, "isActive"); + gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/); if (odm->subscene) { media_sens->sensor->mediaDuration = (Double) (s64)odm->subscene->duration; } else { @@ -159,15 +159,15 @@ void mediasensor_update_timing(GF_ObjectManager *odm, Bool is_eos) else media_sens->sensor->mediaDuration = -FIX_ONE; - gf_node_event_out_str((GF_Node *) media_sens->sensor, "mediaDuration"); + gf_node_event_out((GF_Node *) media_sens->sensor, 3/*"mediaDuration"*/); } if (media_sens->sensor->isActive && (media_sens->sensor->mediaCurrentTime != time)) { media_sens->sensor->mediaCurrentTime = time; - gf_node_event_out_str((GF_Node *) media_sens->sensor, "mediaCurrentTime"); + gf_node_event_out((GF_Node *) media_sens->sensor, 1/*"mediaCurrentTime"*/); } if (is_eos && media_sens->sensor->isActive) { media_sens->sensor->isActive = 0; - gf_node_event_out_str((GF_Node *) media_sens->sensor, "isActive"); + gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/); } continue; } @@ -179,7 +179,7 @@ void mediasensor_update_timing(GF_ObjectManager *odm, Bool is_eos) if (desc->startTime > time) { if (media_sens->sensor->isActive) { media_sens->sensor->isActive = 0; - gf_node_event_out_str((GF_Node *) media_sens->sensor, "isActive"); + gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/); GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[ODM%d] Deactivating media sensor at time %g - segment %s\n", odm->OD->objectDescriptorID, time, desc->SegmentName)); } @@ -197,18 +197,18 @@ void mediasensor_update_timing(GF_ObjectManager *odm, Bool is_eos) if (!media_sens->sensor->isActive) { media_sens->sensor->isActive = 1; - gf_node_event_out_str((GF_Node *) media_sens->sensor, "isActive"); + gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/); /*set info*/ gf_sg_vrml_mf_reset(& media_sens->sensor->info, GF_SG_VRML_MFSTRING); gf_sg_vrml_mf_alloc(& media_sens->sensor->info, GF_SG_VRML_MFSTRING, 1); media_sens->sensor->info.vals[0] = desc->SegmentName ? gf_strdup(desc->SegmentName) : NULL; - gf_node_event_out_str((GF_Node *) media_sens->sensor, "info"); + gf_node_event_out((GF_Node *) media_sens->sensor, 5/*"info"*/); /*set duration*/ media_sens->sensor->mediaDuration = desc->Duration; - gf_node_event_out_str((GF_Node *) media_sens->sensor, "mediaDuration"); + gf_node_event_out((GF_Node *) media_sens->sensor, 3/*"mediaDuration"*/); /*set seg start time*/ media_sens->sensor->streamObjectStartTime = desc->startTime; - gf_node_event_out_str((GF_Node *) media_sens->sensor, "streamObjectStartTime"); + gf_node_event_out((GF_Node *) media_sens->sensor, 2/*"streamObjectStartTime"*/); GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[ODM%d] Activating media sensor time %g - segment %s\n", odm->OD->objectDescriptorID, time, desc->SegmentName)); } @@ -216,7 +216,7 @@ void mediasensor_update_timing(GF_ObjectManager *odm, Bool is_eos) time -= desc->startTime; if (media_sens->sensor->mediaCurrentTime != time) { media_sens->sensor->mediaCurrentTime = time; - gf_node_event_out_str((GF_Node *) media_sens->sensor, "mediaCurrentTime"); + gf_node_event_out((GF_Node *) media_sens->sensor, 1/*"mediaCurrentTime"*/); } break; } @@ -224,7 +224,7 @@ void mediasensor_update_timing(GF_ObjectManager *odm, Bool is_eos) /*we're after last segment, deactivate*/ if (media_sens->sensor->isActive) { media_sens->sensor->isActive = 0; - gf_node_event_out_str((GF_Node *) media_sens->sensor, "isActive"); + gf_node_event_out((GF_Node *) media_sens->sensor, 4/*"isActive"*/); media_sens->active_seg = count; GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[ODM%d] Deactivating media sensor at time %g: no more segments\n", odm->OD->objectDescriptorID, time)); } @@ -236,7 +236,7 @@ void MS_Stop(MediaSensorStack *st) { if (st->sensor->isActive) { st->sensor->isActive = 0; - gf_node_event_out_str((GF_Node *) st->sensor, "isActive"); + gf_node_event_out((GF_Node *) st->sensor, 4/*"isActive"*/); GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[ODM%d] Deactivating media sensor\n", st->stream->odm->OD->objectDescriptorID)); } diff --git a/src/terminal/network_service.c b/src/terminal/network_service.c index faafa21..1e82aa0 100644 --- a/src/terminal/network_service.c +++ b/src/terminal/network_service.c @@ -157,11 +157,15 @@ static void term_on_connect(void *user_priv, GF_ClientService *service, LPNETCHA /*not a fatal error*/ if (err) gf_term_message(term, "GPAC Cache", "Cannot load cache", err); } + return; } /*this is channel connection*/ ch = gf_term_get_channel(service, netch); - if (!ch) return; + if (!ch) { + GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("[Terminal] Channel connection ACK error: channel not found\n")); + return; + } /*confirm channel connection even if error - this allow playback of objects even if not all streams are setup*/ gf_term_lock_net(term, 1); @@ -169,13 +173,16 @@ static void term_on_connect(void *user_priv, GF_ClientService *service, LPNETCHA gf_term_lock_net(term, 0); if (err && ((err!=GF_STREAM_NOT_FOUND) || (ch->esd->decoderConfig->streamType!=GF_STREAM_INTERACT))) { - char szMsg[1024]; - sprintf(szMsg, "Channel %d connection failure", ch->esd->ESID); - gf_term_message(term, service->url, szMsg, err); + GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("[Terminal] Channel %d connection error: %s\n", ch->esd->ESID, gf_error_to_string(err) )); ch->es_state = GF_ESM_ES_UNAVAILABLE; /* return;*/ } + if (ch->odm->mo) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Channel %d connected - %d objects opened\n", ch->esd->ESID, ch->odm->mo->num_open )); + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Channel %d connected - not attached to the scene\n", ch->esd->ESID)); + } /*Plays request are skiped until all channels are connected. We send a PLAY on the objecy in case 1-OD user has requested a play 2-this is a channel of the root OD @@ -249,13 +256,15 @@ static Bool is_same_od(GF_ObjectDescriptor *od1, GF_ObjectDescriptor *od2) if (!esd1) return 0; esd2 = gf_list_get(od2->ESDescriptors, 0); if (!esd2) return 0; - if (esd1->ESID==esd2->ESID) return 1; - return 0; + if (esd1->ESID!=esd2->ESID) return 0; + if (esd1->decoderConfig->streamType != esd2->decoderConfig->streamType) return 0; + if (esd1->decoderConfig->objectTypeIndication != esd2->decoderConfig->objectTypeIndication ) return 0; + return 1; } static void term_on_media_add(void *user_priv, GF_ClientService *service, GF_Descriptor *media_desc, Bool no_scene_check) { - u32 i; + u32 i, min_od_id; GF_MediaObject *the_mo; GF_Scene *scene; GF_ObjectManager *odm, *root; @@ -264,12 +273,12 @@ static void term_on_media_add(void *user_priv, GF_ClientService *service, GF_Des root = service->owner; if (!root){ - GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[Service %s] has not root, aborting !\n", service->url)); + GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("[Service %s] has not root, aborting !\n", service->url)); return; } scene = root->subscene ? root->subscene : root->parentscene; - GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[Service %s] %s\n", service->url, media_desc ? "Adding new media object" : "Regenerating scene graph")); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Service %s] %s\n", service->url, media_desc ? "Adding new media object" : "Regenerating scene graph")); if (!media_desc) { if (!no_scene_check) gf_scene_regenerate(scene); return; @@ -294,11 +303,17 @@ static void term_on_media_add(void *user_priv, GF_ClientService *service, GF_Des /*check if we have a mediaObject in the scene not attached and matching this object*/ the_mo = NULL; odm = NULL; + min_od_id = 0; for (i=0; iscene_objects); i++) { char *frag, *ext; GF_ESD *esd; + char *url; GF_MediaObject *mo = gf_list_get(scene->scene_objects, i); if (!mo->odm) continue; + + if ((mo->OD_ID != GF_MEDIA_EXTERNAL_ID) && (min_od_idOD_ID)) + min_od_id = mo->OD_ID; + /*already assigned object - this may happen since the compositor has no control on when objects are declared by the service, therefore opening file#video and file#audio may result in the objects being declared twice if the service doesn't keep track of declared objects*/ @@ -328,7 +343,12 @@ static void term_on_media_add(void *user_priv, GF_ClientService *service, GF_Des frag = strchr(ext, '='); ext[0] = 0; } - if (!strstr(service->url, mo->URLs.vals[0].url)) { + url = mo->URLs.vals[0].url; + if (!strnicmp(url, "file://localhost", 16)) url += 16; + else if (!strnicmp(url, "file://", 7)) url += 7; + else if (!strnicmp(url, "gpac://", 7)) url += 7; + + if (!strstr(service->url, url)) { if (ext) ext[0] = '#'; continue; } @@ -364,7 +384,6 @@ static void term_on_media_add(void *user_priv, GF_ClientService *service, GF_Des odm = mo->odm; break; } - if (!odm) { odm = gf_odm_new(); odm->term = term; @@ -373,12 +392,22 @@ static void term_on_media_add(void *user_priv, GF_ClientService *service, GF_Des } odm->OD = od; odm->mo = the_mo; - if (the_mo) the_mo->OD_ID = od->objectDescriptorID; odm->flags |= GF_ODM_NOT_IN_OD_STREAM; - gf_term_lock_net(term, 0); + if (!od->objectDescriptorID) { + od->objectDescriptorID = min_od_id + 1; + } + if (the_mo) the_mo->OD_ID = od->objectDescriptorID; + if (!scene->selected_service_id) + scene->selected_service_id = od->ServiceID; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[ODM%d] setup object - MO %08x\n", odm->OD->objectDescriptorID, odm->mo)); gf_odm_setup_object(odm, service); + /*unlock net once the object has been added to the scene, otherwise we may have another modules declaring an object with ID 0 from + another thread, which will assert (only one object with a givne OD ID)*/ + gf_term_lock_net(term, 0); + /*OD inserted by service: resetup scene*/ if (!no_scene_check && scene->is_dynamic_scene) gf_scene_regenerate(scene); } @@ -422,12 +451,14 @@ static void term_on_command(void *user_priv, GF_ClientService *service, GF_Netwo GF_Channel *ch = (GF_Channel *)gf_list_get(odm->channels, j); if (ch->service != service) continue; if (ch->es_state != GF_ESM_ES_RUNNING) continue; - if (!ch->MaxBuffer || ch->dispatch_after_db || ch->bypass_sl_and_db || ch->IsEndOfStream) continue; + if (/*!ch->MaxBuffer || */ch->dispatch_after_db || ch->bypass_sl_and_db || ch->IsEndOfStream) continue; if (ch->MaxBuffer>com->buffer.max) com->buffer.max = ch->MaxBuffer; if (ch->MinBufferbuffer.min) com->buffer.min = ch->MinBuffer; if (ch->IsClockInit && (u32) ch->BufferTime < com->buffer.occupancy) { - if (odm->codec->CB->UnitCount <= odm->codec->CB->Min) { - com->buffer.occupancy = 0; + /*if we don't have more units (compressed or not) than requested max for the composition memory, request more data*/ + if (odm->codec->CB->UnitCount + ch->AU_Count <= odm->codec->CB->Capacity) { +// com->buffer.occupancy = 0; + com->buffer.occupancy = ch->BufferTime; } else { com->buffer.occupancy = ch->BufferTime; } @@ -435,6 +466,7 @@ static void term_on_command(void *user_priv, GF_ClientService *service, GF_Netwo } } gf_mx_v(term->mm_mx); +// fprintf(stdout, "Buffer occupancy %d\n", com->buffer.occupancy); if (com->buffer.occupancy==(u32) -1) com->buffer.occupancy = 0; return; } @@ -507,34 +539,37 @@ Bool net_check_interface(GF_InputService *ifce) return 1; } -static void fetch_mime_io(void *dnld, GF_NETIO_Parameter *parameter) -{ - /* - * souchay : - * NOTE for shoutcast servers and dumb servers - * if HEAD method is not undertood, it will be handled into HTTP 501 : method not implemented - */ - if (parameter->msg_type==GF_NETIO_GET_METHOD) parameter->name = "HEAD"; -} - -static char *get_mime_type(GF_Terminal *term, const char *url, GF_Err *ret_code) +static char *get_mime_type(GF_Terminal *term, const char *url, GF_Err *ret_code, GF_DownloadSession **the_session) { char * ret = NULL; GF_DownloadSession * sess; (*ret_code) = GF_OK; if (strnicmp(url, "http", 4)) return NULL; - sess = gf_dm_sess_new(term->downloader, (char *) url, GF_NETIO_SESSION_NOT_THREADED | GF_NETIO_SESSION_FORCE_NO_CACHE, fetch_mime_io, NULL, ret_code); + + /*don't use any NetIO and don't issue a HEAD command, always go for GET and store the session */ + sess = gf_dm_sess_new(term->downloader, (char *) url, GF_NETIO_SESSION_NOT_THREADED | GF_NETIO_SESSION_NOT_CACHED, NULL, NULL, ret_code); if (!sess) { if (strstr(url, "rtsp://") || strstr(url, "rtp://") || strstr(url, "udp://") || strstr(url, "tcp://") ) (*ret_code) = GF_OK; return NULL; } else { - const char * mime = gf_dm_sess_mime_type(sess); - if (mime){ - ret = gf_strdup(mime); - } + /*start processing the resource, and stop if error or as soon as we get data*/ + while (1) { + *ret_code = gf_dm_sess_process_headers(sess); + if (*ret_code) break; + if (gf_dm_sess_get_status(sess)>=GF_NETIO_DATA_EXCHANGE) { + const char * mime = gf_dm_sess_mime_type(sess); + if (mime) ret = gf_strdup(mime); + break; + } + } + } + + if (the_session && (*ret_code == GF_OK)) { + *the_session = sess; + } else { + gf_dm_sess_del(sess); } - gf_dm_sess_del(sess); return ret; } @@ -561,13 +596,15 @@ static Bool check_extension(const char *szExtList, char *szExt) } -static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char *url, const char *parent_url, Bool no_mime_check, char **out_url, GF_Err *ret_code) +static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char *url, const char *parent_url, Bool no_mime_check, char **out_url, GF_Err *ret_code, GF_DownloadSession **the_session) { u32 i; GF_Err e; char *sURL, *qm, *frag, *ext, *mime_type, *url_res; char szExt[50]; + const char *force_module = NULL; GF_InputService *ifce; + Bool skip_mime = 0; memset(szExt, 0, sizeof(szExt)); (*ret_code) = GF_OK; @@ -581,8 +618,15 @@ static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char goto exit; } + if (!strnicmp(url, "libplayer://", 12)) { + force_module = "LibPlayer"; + } + /*used by GUIs scripts to skip URL concatenation*/ if (!strncmp(url, "gpac://", 7)) sURL = gf_strdup(url+7); + /*opera-style localhost URLs*/ + else if (!strncmp(url, "file://localhost", 16)) sURL = gf_strdup(url+16); + else if (parent_url) sURL = gf_url_concatenate(parent_url, url); /*path absolute*/ @@ -591,6 +635,7 @@ static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char if (gf_url_is_local(sURL)) gf_url_to_fs_path(sURL); + if (the_session) *the_session = NULL; if (no_mime_check) { mime_type = NULL; } else { @@ -598,7 +643,7 @@ static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char TRYTOFIXME: it would be nice to reuse the downloader created while fetching the mime type, however we don't know if the plugin will want it threaded or not.... */ - mime_type = get_mime_type(term, sURL, &e); + mime_type = get_mime_type(term, sURL, &e, the_session); if (e) { (*ret_code) = e; goto exit; @@ -611,14 +656,13 @@ static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char || !stricmp(mime_type, "application/octet-stream") ) ) { - gf_free(mime_type); - mime_type = NULL; + skip_mime = 1; } ifce = NULL; /*load from mime type*/ - if (mime_type) { + if (mime_type && !skip_mime) { const char *sPlug = gf_cfg_get_key(term->user->config, "MimeTypes", mime_type); GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Mime type found: %s\n", mime_type)); if (!sPlug) { @@ -630,6 +674,10 @@ static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char sPlug += 2; GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("%s:%d FOUND matching module %s\n", __FILE__, __LINE__, sPlug)); ifce = (GF_InputService *) gf_modules_load_interface_by_name(term->user->modules, sPlug, GF_NET_CLIENT_INTERFACE); + if (force_module && ifce && !strstr(ifce->module_name, force_module)) { + gf_modules_close_interface((GF_BaseInterface *) ifce); + ifce = NULL; + } if (ifce && !net_check_interface(ifce) ) { gf_modules_close_interface((GF_BaseInterface *) ifce); ifce = NULL; @@ -697,7 +745,12 @@ static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] module[%i]=%s, mime=%s, cannot be loaded for GF_NET_CLIENT_INTERFACE.\n", i, sPlug, sMime)); continue; } - if (!net_check_interface(ifce)) { + if (force_module && ifce && !strstr(ifce->module_name, force_module)) { + gf_modules_close_interface((GF_BaseInterface *) ifce); + ifce = NULL; + continue; + } + if (ifce && !net_check_interface(ifce)) { gf_modules_close_interface((GF_BaseInterface *) ifce); ifce = NULL; continue; @@ -713,17 +766,25 @@ static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char ifce = (GF_InputService *) gf_modules_load_interface(term->user->modules, i, GF_NET_CLIENT_INTERFACE); if (!ifce) continue; GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Checking if module %s supports URL %s\n", ifce->module_name, sURL)); - if (net_check_interface(ifce) && ifce->CanHandleURL(ifce, sURL)) break; + if (force_module && ifce && !strstr(ifce->module_name, force_module)) { + } + else if (net_check_interface(ifce) && ifce->CanHandleURL(ifce, sURL)) { + break; + } gf_modules_close_interface((GF_BaseInterface *) ifce); ifce = NULL; } } exit: if (!ifce){ - GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[Terminal] Did not find any input plugin for URL %s (%s)\n", sURL ? sURL : url, mime_type ? mime_type : "no mime type")); + GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("[Terminal] Did not find any input plugin for URL %s (%s)\n", sURL ? sURL : url, mime_type ? mime_type : "no mime type")); if (sURL) gf_free(sURL); if ( (*ret_code) == GF_OK) (*ret_code) = GF_NOT_SUPPORTED; *out_url = NULL; + + if (the_session && *the_session) { + gf_dm_sess_del(*the_session); + } } else { *out_url = sURL; GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[Terminal] Found input plugin %s for URL %s (%s)\n", ifce->module_name, sURL, mime_type ? mime_type : "no mime type")); @@ -736,9 +797,10 @@ exit: GF_ClientService *gf_term_service_new(GF_Terminal *term, struct _od_manager *owner, const char *url, const char *parent_url, GF_Err *ret_code) { + GF_DownloadSession *download_session; char *sURL; GF_ClientService *serv; - GF_InputService *ifce = gf_term_can_handle_service(term, url, parent_url, 0, &sURL, ret_code); + GF_InputService *ifce = gf_term_can_handle_service(term, url, parent_url, 0, &sURL, ret_code, &download_session); if (!ifce) return NULL; GF_SAFEALLOC(serv, GF_ClientService); @@ -748,6 +810,7 @@ GF_ClientService *gf_term_service_new(GF_Terminal *term, struct _od_manager *own serv->url = sURL; serv->Clocks = gf_list_new(); serv->dnloads = gf_list_new(); + serv->pending_service_session = download_session; gf_list_add(term->net_services, serv); return serv; @@ -761,7 +824,7 @@ Bool gf_term_is_supported_url(GF_Terminal *term, const char *fileName, Bool use_ char *parent_url = NULL; if (use_parent_url && term->root_scene) parent_url = term->root_scene->root_od->net_service->url; - ifce = gf_term_can_handle_service(term, fileName, parent_url, no_mime_check, &sURL, &e); + ifce = gf_term_can_handle_service(term, fileName, parent_url, no_mime_check, &sURL, &e, NULL); if (!ifce) return 0; gf_modules_close_interface((GF_BaseInterface *) ifce); gf_free(sURL); @@ -778,7 +841,8 @@ Bool gf_term_service_can_handle_url(GF_ClientService *ns, char *url) GF_Err gf_term_service_command(GF_ClientService *ns, GF_NetworkCommand *com) { - return ns->ifce->ServiceCommand(ns->ifce, com); + if (ns) return ns->ifce->ServiceCommand(ns->ifce, com); + return GF_OK; } GF_Err gf_term_channel_get_sl_packet(GF_ClientService *ns, LPNETCHANNEL channel, char **out_data_ptr, u32 *out_data_size, GF_SLHeader *out_sl_hdr, Bool *sl_compressed, GF_Err *out_reception_status, Bool *is_new_data) { @@ -815,6 +879,15 @@ void gf_term_on_command(GF_ClientService *service, GF_NetworkCommand *com, GF_Er assert(service); term_on_command(service->term, service, com, response); } + +GF_EXPORT +Bool gf_term_on_service_event(GF_ClientService *service, GF_Event *service_event) +{ + assert(service); + if (service->term->user->EventProc) return service->term->user->EventProc(service->term->user->opaque, service_event); + return 0; +} + GF_EXPORT void gf_term_on_sl_packet(GF_ClientService *service, LPNETCHANNEL ns, char *data, u32 data_size, GF_SLHeader *hdr, GF_Err reception_status) { @@ -836,11 +909,13 @@ const char *gf_term_get_service_url(GF_ClientService *service) return service->url; } -void NM_DeleteService(GF_ClientService *ns) +void gf_term_delete_net_service(GF_ClientService *ns) { const char *sOpt = gf_cfg_get_key(ns->term->user->config, "StreamingCache", "AutoSave"); if (ns->cache) gf_term_service_cache_close(ns, (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); + if (ns->pending_service_session) gf_dm_sess_del(ns->pending_service_session); + assert(!ns->nb_odm_users); assert(!ns->nb_ch_users); assert(!ns->owner); @@ -873,7 +948,7 @@ GF_DownloadSession *gf_term_download_new(GF_ClientService *service, const char * { GF_Err e; GF_DownloadSession * sess; - char *sURL; + char *sURL, *orig_url; if (!service){ GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[HTTP] service is null, cannot create new download session for %s.\n", url)); return NULL; @@ -883,7 +958,21 @@ GF_DownloadSession *gf_term_download_new(GF_ClientService *service, const char * /*path was absolute*/ if (!sURL) sURL = gf_strdup(url); assert( service->term ); - sess = gf_dm_sess_new(service->term->downloader, sURL, flags, user_io, cbk, &e); + + orig_url = service->pending_service_session ? (char *) gf_dm_sess_get_original_resource_name(service->pending_service_session) : NULL; + /*this will take care of URL formatting (%20 etc ..) */ + if (orig_url) orig_url = gf_url_concatenate(service->url, orig_url); + + if (orig_url && !strcmp(orig_url, sURL)) { + sess = service->pending_service_session; + service->pending_service_session = NULL; + /*resetup*/ + gf_dm_sess_reassign(sess, flags, user_io, cbk); + } else { + sess = gf_dm_sess_new(service->term->downloader, sURL, flags, user_io, cbk, &e); + } + if (orig_url) gf_free(orig_url); + if (!sess){ GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[HTTP] session could not be created for %s : %s. service url=%s, url=%s.\n", sURL, gf_error_to_string(e), service->url, url)); gf_free(sURL); @@ -958,7 +1047,7 @@ void gf_term_service_del(GF_ClientService *ns) if (! * (u32 *) ns) { gf_dm_sess_del((GF_DownloadSession * ) ns); } else { - NM_DeleteService(ns); + gf_term_delete_net_service(ns); } } diff --git a/src/terminal/object_browser.c b/src/terminal/object_browser.c index 346ac01..227a82b 100644 --- a/src/terminal/object_browser.c +++ b/src/terminal/object_browser.c @@ -106,6 +106,20 @@ void gf_term_select_object(GF_Terminal *term, GF_ObjectManager *odm) gf_scene_select_object(term->root_scene, odm); } +u32 gf_term_get_current_service_id(GF_Terminal *term) +{ + SFURL *the_url; + GF_MediaObject *mo; + if (!term || !term->root_scene) return 0; + if (! term->root_scene->is_dynamic_scene) return term->root_scene->root_od->OD->ServiceID; + + if (term->root_scene->visual_url.OD_ID || term->root_scene->visual_url.url) the_url = &term->root_scene->visual_url; + else the_url = &term->root_scene->audio_url; + + mo = gf_scene_find_object(term->root_scene, the_url->OD_ID, the_url->url); + if (mo && mo->odm && mo->odm->OD) return mo->odm->OD->ServiceID; + return 0; +} static void get_codec_stats(GF_Codec *dec, GF_MediaInfo *info) @@ -195,6 +209,8 @@ GF_Err gf_term_get_object_info(GF_Terminal *term, GF_ObjectManager *odm, GF_Medi info->service_handler = odm->net_service->ifce->module_name; info->service_url = odm->net_service->url; if (odm->net_service->owner == odm) info->owns_service = 1; + } else if ((odm->subscene && odm->subscene->graph_attached) || (odm->codec)) { + info->service_url = "No associated network Service"; } else { info->service_url = "Service not found or error"; } @@ -361,7 +377,7 @@ GF_Err gf_term_dump_scene(GF_Terminal *term, char *rad_name, char **filename, Bo mode = xml_dump ? GF_SM_DUMP_AUTO_XML : GF_SM_DUMP_AUTO_TXT; /*figure out best dump format based on extension*/ - ext = strrchr(odm->net_service->url, '.'); + ext = odm->net_service ? strrchr(odm->net_service->url, '.') : NULL; if (ext) { strcpy(szExt, ext); strlwr(szExt); diff --git a/src/terminal/object_manager.c b/src/terminal/object_manager.c index 899cb38..66009aa 100644 --- a/src/terminal/object_manager.c +++ b/src/terminal/object_manager.c @@ -88,6 +88,7 @@ void gf_odm_del(GF_ObjectManager *odm) #endif if (odm->mo) odm->mo->odm = NULL; + if (odm->raw_frame_sema) gf_sema_del(odm->raw_frame_sema); gf_list_del(odm->channels); odm->channels = NULL; @@ -123,9 +124,8 @@ void gf_odm_disconnect(GF_ObjectManager *odm, Bool do_remove) { GF_Channel *ch; - if (do_remove) odm->state = GF_ODM_STATE_DESTROYED; + if (do_remove) odm->flags |= GF_ODM_DESTROYED; gf_odm_stop(odm, 1); - if (do_remove) odm->state = GF_ODM_STATE_DESTROYED; /*disconnect sub-scene*/ if (odm->subscene) gf_scene_disconnect(odm->subscene, do_remove); @@ -335,6 +335,10 @@ void gf_odm_setup_entry_point(GF_ObjectManager *odm, const char *service_sub_url gf_odm_setup_object(odm, odm->net_service); gf_term_lock_net(term, 0); + /*it may happen that this object was inserted in a dynamic scene from a service through a URL redirect. In which case, + the scene regeneration might not have been completed since the redirection was not done yet - force a scene regenerate*/ + if (odm->parentscene && odm->parentscene->is_dynamic_scene) + gf_scene_regenerate(odm->parentscene); return; err_exit: @@ -359,7 +363,7 @@ static GF_ESD *od_get_esd(GF_ObjectDescriptor *OD, u16 ESID) return NULL; } -#ifdef UNUSED_FUNC +#ifdef GPAC_UNUSED_FUNC static void ODM_SelectAlternateStream(GF_ObjectManager *odm, u32 lang_code, u8 stream_type) { u32 i; @@ -409,7 +413,7 @@ static void ODM_SelectAlternateStream(GF_ObjectManager *odm, u32 lang_code, u8 s } } } -#endif /* UNUSED_FUNC */ +#endif /*GPAC_UNUSED_FUNC*/ /*Validate the streams in this OD, and check if we have to setup an inline scene*/ @@ -556,7 +560,7 @@ void gf_odm_setup_object(GF_ObjectManager *odm, GF_ClientService *serv) gf_odf_desc_del((GF_Descriptor *)odm->OD); odm->OD = NULL; odm->net_service = NULL; - GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Object redirection to %s\n", url)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Object redirection to %s (MO %08x)\n", url, odm->mo)); /*if object is a scene, create the inline before connecting the object. This is needed in irder to register the nodes using the resource for event @@ -610,7 +614,6 @@ void gf_odm_setup_object(GF_ObjectManager *odm, GF_ClientService *serv) /*avoid channels PLAY request when confirming connection (sync network service)*/ odm->state = GF_ODM_STATE_IN_SETUP; - gf_odm_lock(odm, 1); i=0; while ((esd = (GF_ESD *)gf_list_enum(odm->OD->ESDescriptors, &i)) ) { @@ -642,7 +645,6 @@ void gf_odm_setup_object(GF_ObjectManager *odm, GF_ClientService *serv) gf_odm_start(odm, 0); } - evt.type = GF_EVENT_CONNECT; evt.connect.is_connected = 1; gf_term_forward_event(odm->term, &evt, 0, 1); @@ -670,8 +672,10 @@ void gf_odm_setup_object(GF_ObjectManager *odm, GF_ClientService *serv) } /*case 3: if the object is inserted from a broadcast, start it if not already done. This covers cases where the scene (BIFS, LASeR) and the media (images) are both carrouseled and the carrousels are interleaved. If we wait for the scene to trigger a PLAY, we will likely - have to wait for an entire image carousel period to start filling the buffers, which is sub-optimal*/ - else if (!odm->state && (odm->flags & GF_ODM_NO_TIME_CTRL)) { + have to wait for an entire image carousel period to start filling the buffers, which is sub-optimal + we also force a prefetch for object declared outside the OD stream to make sure we don't loose any data before object declaration and play + as can be the case with MPEG2 TS (first video packet right after the PMT) - this should be refined*/ + else if (!odm->state && ((odm->flags & GF_ODM_NO_TIME_CTRL) || (odm->flags & GF_ODM_NOT_IN_OD_STREAM)) && (odm->parentscene->selected_service_id == odm->OD->ServiceID)) { GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[ODM%d] Inserted from broadcast - forcing play\n", odm->OD->objectDescriptorID)); gf_odm_start(odm, 2); odm->flags |= GF_ODM_PREFETCH; @@ -748,10 +752,10 @@ GF_Err gf_odm_setup_es(GF_ObjectManager *odm, GF_ESD *esd, GF_ClientService *ser esd->OCRESID = ck->clockID; } /*for dynamic scene, force all streams to be sync on main OD stream (one timeline, no need to reload ressources)*/ - else if (odm->term->root_scene->is_dynamic_scene) { - GF_ObjectManager *root_od = odm->term->root_scene->root_od; - if (gf_list_count(root_od->net_service->Clocks)==1) { - ck = (GF_Clock*)gf_list_get(root_od->net_service->Clocks, 0); + else if (odm->parentscene && odm->parentscene->is_dynamic_scene && !odm->subscene) { + GF_ObjectManager *parent_od = odm->parentscene->root_od; + if (parent_od->net_service && (gf_list_count(parent_od->net_service->Clocks)==1)) { + ck = (GF_Clock*)gf_list_get(parent_od->net_service->Clocks, 0); esd->OCRESID = ck->clockID; goto clock_setup; } @@ -934,6 +938,15 @@ clock_setup: } } } + { + GF_CodecCapability cap; + cap.CapCode = GF_CODEC_RAW_MEDIA; + gf_codec_get_capability(dec, &cap); + if (cap.cap.valueInt) { + dec->flags |= GF_ESM_CODEC_IS_RAW_MEDIA; + dec->process = gf_codec_process_private_media; + } + } ch->es_state = GF_ESM_ES_SETUP; ch->odm = odm; @@ -1017,7 +1030,7 @@ GF_Err gf_odm_post_es_setup(GF_Channel *ch, GF_Codec *dec, GF_Err had_err) if (ch->esd->URLString) { strcpy(szURL, ch->esd->URLString); } else { - sprintf(szURL, "ES_ID=%ud", ch->esd->ESID); + sprintf(szURL, "ES_ID=%u", ch->esd->ESID); } /*connect before setup: this is needed in case the decoder cfg is wrong, we may need to get it from @@ -1181,8 +1194,6 @@ void gf_odm_start(GF_ObjectManager *odm, u32 media_queue_state) Bool skip_register = 1; gf_term_lock_media_queue(odm->term, 1); - odm->flags &= ~GF_ODM_PREFETCH; - /*only if not open & ready (not waiting for ACK on channel setup)*/ if (!odm->pending_channels && odm->OD) { /*object is not started - issue channel setup requests*/ @@ -1253,6 +1264,14 @@ void gf_odm_play(GF_ObjectManager *odm) #endif GF_Clock *parent_ck = NULL; + if (odm->codec && odm->codec->CB && !(odm->flags & GF_ODM_PREFETCH)) { + /*reset*/ + gf_cm_set_status(odm->codec->CB, CB_STOP); + odm->codec->CB->HasSeenEOS = 0; + } + odm->flags &= ~GF_ODM_PREFETCH; + + if (odm->parentscene) { parent_ck = gf_odm_get_media_clock(odm->parentscene->root_od); if (!gf_odm_shares_clock(odm, parent_ck)) parent_ck = NULL; @@ -1381,11 +1400,6 @@ void gf_odm_play(GF_ObjectManager *odm) /*start codecs last (otherwise we end up pulling data from channels not yet connected->pbs when seeking)*/ if (odm->codec) { - /*reset*/ - if (odm->codec->CB) { - gf_cm_set_status(odm->codec->CB, CB_STOP); - odm->codec->CB->HasSeenEOS = 0; - } gf_term_start_codec(odm->codec); } else if (odm->subscene) { if (odm->subscene->scene_codec) gf_term_start_codec(odm->subscene->scene_codec); @@ -1449,13 +1463,30 @@ void gf_odm_stop(GF_ObjectManager *odm, Bool force_close) gf_term_lock_media_queue(odm->term, 0); /*little opt for image codecs: don't actually stop the OD*/ - if (!force_close && odm->codec && odm->codec->CB) { + if (!force_close && odm->codec && odm->codec->CB && !odm->codec->CB->no_allocation) { if (odm->codec->CB->Capacity==1) return; } + /*if raw media, stop all channels before sending stop command to network, to avoid new media frames to be set + as pending and thereby locking the channel associated service*/ + if (odm->codec && odm->codec->flags & GF_ESM_CODEC_IS_RAW_MEDIA) { + i=0; + while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &i)) ) { + gf_es_stop(ch); + } + gf_term_stop_codec(odm->codec); + /*and wait until frame has been consumed by the renderer + we don't use semaphore wait as the raw channel may already be pending on the semaphore*/ + while (odm->codec->CB->UnitCount) { + gf_sleep(1); + } + } + + /*object was not unlocked, decoders were not started*/ if (odm->state==GF_ODM_STATE_BLOCKED) { odm->current_time = 0; + gf_sema_notify(odm->raw_frame_sema, 1); return; } diff --git a/src/terminal/scene.c b/src/terminal/scene.c index b1ce920..ebfdaab 100644 --- a/src/terminal/scene.c +++ b/src/terminal/scene.c @@ -29,9 +29,10 @@ /*for URL concatenation*/ #include #include +#include #include "media_control.h" -#include #include +#include /*SVG properties*/ #ifndef GPAC_DISABLE_SVG @@ -194,6 +195,8 @@ void gf_scene_disconnect(GF_Scene *scene, Bool for_shutdown) GF_SceneDecoder *dec = NULL; if (scene->scene_codec) dec = (GF_SceneDecoder *)scene->scene_codec->decio; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Scene] disconnecting\n")); + gf_term_lock_compositor(scene->root_od->term, 1); /*disconnect / kill all objects BEFORE reseting the scene graph since we have @@ -257,7 +260,7 @@ void gf_scene_disconnect(GF_Scene *scene, Bool for_shutdown) } #endif - if (scene->graph_attached && (scene->root_od->term->root_scene == scene)) { + if (scene->root_od->term->root_scene == scene) { gf_sc_set_scene(scene->root_od->term->compositor, NULL); } /*release the scene*/ @@ -303,51 +306,54 @@ static void gf_scene_insert_object(GF_Scene *scene, GF_MediaObject *mo, Bool loc root_od = scene->root_od; url = mo->URLs.vals[0].url; - if (!stricmp(url, "KeySensor")) { - GF_ESD *esd = gf_odf_desc_esd_new(0); - esd->decoderConfig->streamType = GF_STREAM_INTERACT; - esd->decoderConfig->objectTypeIndication = 1; - gf_free(esd->decoderConfig->decoderSpecificInfo->data); - esd->decoderConfig->decoderSpecificInfo->data = gf_strdup(" KeySensor"); - esd->decoderConfig->decoderSpecificInfo->data[0] = 9; - esd->decoderConfig->decoderSpecificInfo->dataLength = 10; - esd->ESID = esd->OCRESID = 65534; - gf_list_add(odm->OD->ESDescriptors, esd); - } else if (!stricmp(url, "StringSensor")) { - GF_ESD *esd = gf_odf_desc_esd_new(0); - esd->decoderConfig->streamType = GF_STREAM_INTERACT; - esd->decoderConfig->objectTypeIndication = 1; - gf_free(esd->decoderConfig->decoderSpecificInfo->data); - esd->decoderConfig->decoderSpecificInfo->data = gf_strdup(" StringSensor"); - esd->decoderConfig->decoderSpecificInfo->data[0] = 12; - esd->decoderConfig->decoderSpecificInfo->dataLength = 13; - esd->ESID = esd->OCRESID = 65534; - gf_list_add(odm->OD->ESDescriptors, esd); - } else if (!stricmp(url, "Mouse")) { - GF_ESD *esd = gf_odf_desc_esd_new(0); - esd->decoderConfig->streamType = GF_STREAM_INTERACT; - esd->decoderConfig->objectTypeIndication = 1; - gf_free(esd->decoderConfig->decoderSpecificInfo->data); - esd->decoderConfig->decoderSpecificInfo->data = gf_strdup(" Mouse"); - esd->decoderConfig->decoderSpecificInfo->data[0] = 5; - esd->decoderConfig->decoderSpecificInfo->dataLength = 6; - esd->ESID = esd->OCRESID = 65534; - gf_list_add(odm->OD->ESDescriptors, esd); - } else { - if (!keep_fragment) { - char *frag = strrchr(mo->URLs.vals[0].url, '#'); - if (frag) frag[0] = 0; - odm->OD->URLString = gf_strdup(mo->URLs.vals[0].url); - if (frag) frag[0] = '#'; + if (url) { + if (!stricmp(url, "KeySensor")) { + GF_ESD *esd = gf_odf_desc_esd_new(0); + esd->decoderConfig->streamType = GF_STREAM_INTERACT; + esd->decoderConfig->objectTypeIndication = 1; + gf_free(esd->decoderConfig->decoderSpecificInfo->data); + esd->decoderConfig->decoderSpecificInfo->data = gf_strdup(" KeySensor"); + esd->decoderConfig->decoderSpecificInfo->data[0] = 9; + esd->decoderConfig->decoderSpecificInfo->dataLength = 10; + esd->ESID = esd->OCRESID = 65534; + gf_list_add(odm->OD->ESDescriptors, esd); + } else if (!stricmp(url, "StringSensor")) { + GF_ESD *esd = gf_odf_desc_esd_new(0); + esd->decoderConfig->streamType = GF_STREAM_INTERACT; + esd->decoderConfig->objectTypeIndication = 1; + gf_free(esd->decoderConfig->decoderSpecificInfo->data); + esd->decoderConfig->decoderSpecificInfo->data = gf_strdup(" StringSensor"); + esd->decoderConfig->decoderSpecificInfo->data[0] = 12; + esd->decoderConfig->decoderSpecificInfo->dataLength = 13; + esd->ESID = esd->OCRESID = 65534; + gf_list_add(odm->OD->ESDescriptors, esd); + } else if (!stricmp(url, "Mouse")) { + GF_ESD *esd = gf_odf_desc_esd_new(0); + esd->decoderConfig->streamType = GF_STREAM_INTERACT; + esd->decoderConfig->objectTypeIndication = 1; + gf_free(esd->decoderConfig->decoderSpecificInfo->data); + esd->decoderConfig->decoderSpecificInfo->data = gf_strdup(" Mouse"); + esd->decoderConfig->decoderSpecificInfo->data[0] = 5; + esd->decoderConfig->decoderSpecificInfo->dataLength = 6; + esd->ESID = esd->OCRESID = 65534; + gf_list_add(odm->OD->ESDescriptors, esd); } else { - odm->OD->URLString = gf_strdup(mo->URLs.vals[0].url); + if (!keep_fragment) { + char *frag = strrchr(mo->URLs.vals[0].url, '#'); + if (frag) frag[0] = 0; + odm->OD->URLString = gf_strdup(mo->URLs.vals[0].url); + if (frag) frag[0] = '#'; + } else { + odm->OD->URLString = gf_strdup(mo->URLs.vals[0].url); + } + if (lock_timelines) odm->flags |= GF_ODM_INHERIT_TIMELINE; } - if (lock_timelines) odm->flags |= GF_ODM_INHERIT_TIMELINE; } /*HACK - temp storage of sync ref*/ if (sync_ref) odm->ocr_codec = (struct _generic_codec *)sync_ref; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Scene] Inserting new MediaObject %08x for resource %s\n", odm->mo, url)); gf_list_add(scene->resources, odm); if (original_parent_scene) { gf_odm_setup_object(odm, original_parent_scene->root_od->net_service); @@ -378,6 +384,8 @@ void gf_scene_remove_object(GF_Scene *scene, GF_ObjectManager *odm, Bool for_shu gf_list_del_item(scene->resources, odm); gf_term_lock_net(odm->term, 0); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Scene] removing ODM %d\n", odm->OD ? odm->OD->objectDescriptorID : GF_MEDIA_EXTERNAL_ID)); + i=0; while ((obj = (GF_MediaObject*)gf_list_enum(scene->scene_objects, &i))) { @@ -641,7 +649,7 @@ restart: obj = NULL; i=0; while ((obj = (GF_MediaObject *)gf_list_enum(scene->scene_objects, &i))) { - if (obj->odm && ((obj->odm->state == GF_ODM_STATE_DESTROYED) || (obj->odm->action_type == GF_ODM_ACTION_DELETE)) ) + if (obj->odm && ((obj->odm->flags & GF_ODM_DESTROYED) || (obj->odm->action_type == GF_ODM_ACTION_DELETE)) ) continue; if ( @@ -723,6 +731,8 @@ void gf_scene_setup_object(GF_Scene *scene, GF_ObjectManager *odm) GF_MediaObject *obj; u32 i; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Scene] Setup object manager %d (MO %p)\n", odm->OD->objectDescriptorID, odm->mo)); + /*an object may already be assigned (when using ESD URLs, setup is performed twice)*/ if (odm->mo != NULL) goto existing; @@ -875,7 +885,7 @@ void gf_scene_force_size_to_video(GF_Scene *scene, GF_MediaObject *mo) { u32 w, h; gf_scene_get_video_size(mo, &w, &h); - gf_scene_force_size(scene, w, h); + if (w && h) gf_scene_force_size(scene, w, h); } #ifndef GPAC_DISABLE_VRML @@ -998,7 +1008,7 @@ static void set_media_url(GF_Scene *scene, SFURL *media_url, GF_Node *node, MFU /*regenerates the scene graph for dynamic scene. This will also try to reload any previously presented streams. Note that in the usual case the scene is generated just once when receiving the first OD AU (ressources are NOT destroyed when seeking), but since the network may need -to update the OD ressources, we still kake care of it*/ +to update the OD ressources, we still take care of it*/ void gf_scene_regenerate(GF_Scene *scene) { GF_Node *n1, *n2; @@ -1180,6 +1190,7 @@ void gf_scene_select_object(GF_Scene *scene, GF_ObjectManager *odm) mt->startTime = gf_scene_get_time(scene); gf_node_changed((GF_Node *)mt, NULL); if (odm->mo) gf_scene_force_size_to_video(scene, odm->mo); + scene->selected_service_id = odm->OD->ServiceID; return; } @@ -1265,8 +1276,18 @@ void gf_scene_force_size(GF_Scene *scene, u32 width, u32 height) if (!scene->is_dynamic_scene) return; gf_sg_set_scene_size_info(scene->graph, width, height, gf_sg_use_pixel_metrics(scene->graph)); - if (scene->root_od->term->root_scene == scene) + if (scene->root_od->term->root_scene == scene) { gf_sc_set_scene(scene->root_od->term->compositor, scene->graph); + } + else if (scene->root_od->parentscene && scene->root_od->parentscene->is_dynamic_scene) { + gf_sg_set_scene_size_info(scene->root_od->parentscene->graph, width, height, gf_sg_use_pixel_metrics(scene->root_od->parentscene->graph)); + if (scene->root_od->term->root_scene == scene->root_od->parentscene) { + if (width && height) { + gf_sc_set_scene_size(scene->root_od->term->compositor, width, height, 1); + gf_sc_set_size(scene->root_od->term->compositor, width, height); + } + } + } gf_scene_notify_event(scene, GF_EVENT_SCENE_ATTACHED, NULL, NULL, GF_OK); @@ -1421,3 +1442,79 @@ Bool gf_scene_is_over(GF_SceneGraph *sg) } return 1; } + +#define USE_TEXTURES 0 + +void gf_scene_generate_views(GF_Scene *scene, char *url) +{ + GF_Node *n1, *switcher; +#if USE_TEXTURES + GF_Node *n2; + M_MovieTexture *mt; +#else + M_Inline *inl; +#endif + GF_Event evt; + gf_sg_reset(scene->graph); + + n1 = is_create_node(scene->graph, TAG_MPEG4_OrderedGroup, NULL); + gf_sg_set_root_node(scene->graph, n1); + gf_node_register(n1, NULL); + + switcher = is_create_node(scene->graph, TAG_MPEG4_Switch, NULL); + gf_node_register(switcher, n1); + gf_node_list_add_child( &((GF_ParentNode *)n1)->children, switcher); + ((M_Switch*)switcher)->whichChoice = -2; + + while (1) { + char *sep = strchr(url, ':'); + if (sep) sep[0] = 0; +#if USE_TEXTURES + /*create a shape and bitmap node*/ + n2 = is_create_node(scene->graph, TAG_MPEG4_Shape, NULL); + gf_node_list_add_child( &((M_Switch *)switcher)->choice, n2); + gf_node_register(n2, switcher); + n1 = n2; + n2 = is_create_node(scene->graph, TAG_MPEG4_Appearance, NULL); + ((M_Shape *)n1)->appearance = n2; + gf_node_register(n2, n1); + + /*note we create a movie texture even for images...*/ + mt = (M_MovieTexture *) is_create_node(scene->graph, TAG_MPEG4_MovieTexture, NULL); + mt->startTime = gf_scene_get_time(scene); + ((M_Appearance *)n2)->texture = (GF_Node *)mt; + gf_node_register((GF_Node *)mt, n2); + + n2 = is_create_node(scene->graph, TAG_MPEG4_Bitmap, NULL); + ((M_Shape *)n1)->geometry = n2; + gf_node_register(n2, n1); + + gf_sg_vrml_mf_reset(&mt->url, GF_SG_VRML_MFURL); + gf_sg_vrml_mf_append(&mt->url, GF_SG_VRML_MFURL, NULL); + mt->url.vals[0].url = gf_strdup(url); +#else + inl = (M_Inline *) is_create_node(scene->graph, TAG_MPEG4_Inline, NULL); + gf_node_list_add_child( &((M_Switch *)switcher)->choice, (GF_Node *)inl); + gf_node_register((GF_Node*) inl, switcher); + + gf_sg_vrml_mf_reset(&inl->url, GF_SG_VRML_MFURL); + gf_sg_vrml_mf_append(&inl->url, GF_SG_VRML_MFURL, NULL); + inl->url.vals[0].url = gf_strdup(url); +#endif + + if (!sep) break; + sep[0] = ':'; + url = sep+1; + } + + gf_sc_set_option(scene->root_od->term->compositor, GF_OPT_USE_OPENGL, 1); + + gf_sg_set_scene_size_info(scene->graph, 0, 0, 1); + gf_sc_set_scene(scene->root_od->term->compositor, scene->graph); + scene->graph_attached = 1; + scene->is_dynamic_scene = 1; + + evt.type = GF_EVENT_CONNECT; + evt.connect.is_connected = 1; + gf_term_send_event(scene->root_od->term, &evt); +} diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c index 661eb9b..d69dc46 100644 --- a/src/terminal/terminal.c +++ b/src/terminal/terminal.c @@ -410,6 +410,12 @@ static void gf_term_connect_from_time_ex(GF_Terminal * term, const char *URL, u6 /*render first visual frame and pause*/ if (pause_at_first_frame) gf_term_set_play_state(term, GF_STATE_STEP_PAUSE, 0, 0); + + if (!strnicmp(URL, "views://", 8)) { + odm->OD = (GF_ObjectDescriptor *)gf_odf_desc_new(GF_ODF_OD_TAG); + gf_scene_generate_views(term->root_scene, (char *) URL+8); + return; + } /*connect - we don't have any parentID */ gf_term_connect_object(term, odm, (char *) URL, (char*)parent_path); } @@ -522,6 +528,7 @@ GF_Terminal *gf_term_new(GF_User *user) tmp->net_services = gf_list_new(); tmp->net_services_to_remove = gf_list_new(); + tmp->net_services_to_connect = gf_list_new(); tmp->channels_pending = gf_list_new(); tmp->media_queue = gf_list_new(); tmp->media_queue_mx = gf_mx_new("MediaQueue"); @@ -670,6 +677,7 @@ GF_Err gf_term_del(GF_Terminal * term) gf_sc_del(term->compositor); gf_list_del(term->net_services); + gf_list_del(term->net_services_to_connect); gf_list_del(term->net_services_to_remove); gf_list_del(term->input_streams); gf_list_del(term->x3d_sensors); @@ -781,7 +789,7 @@ void gf_term_disconnect(GF_Terminal *term) GF_EXPORT const char *gf_term_get_url(GF_Terminal *term) { - if (!term || !term->root_scene) return NULL; + if (!term || !term->root_scene || !term->root_scene->root_od || !term->root_scene->root_od->net_service) return NULL; return term->root_scene->root_od->net_service->url; } @@ -892,6 +900,16 @@ u32 gf_term_get_option(GF_Terminal * term, u32 type) } } +static void gf_term_cleanup_pending_session(GF_Terminal *term, GF_ClientService *ns) +{ + if (gf_list_find(term->net_services, ns)<0) return; + + if (ns && ns->pending_service_session) { + gf_dm_sess_del(ns->pending_service_session); + ns->pending_service_session = NULL; + } +} + GF_EXPORT GF_Err gf_term_set_size(GF_Terminal * term, u32 NewWidth, u32 NewHeight) @@ -909,6 +927,25 @@ void gf_term_handle_services(GF_Terminal *term) if (!gf_mx_try_lock(term->media_queue_mx)) return; + + while (gf_list_count(term->net_services_to_connect)) { + GF_ObjectManager *odm = (GF_ObjectManager *)gf_list_get(term->net_services_to_connect, 0); + GF_ClientService *ns = odm->net_service; + gf_list_rem(term->net_services_to_connect, 0); + /*unlock media queue before connecting*/ + gf_mx_v(term->media_queue_mx); + + /*OK connect*/ + gf_term_service_media_event(odm, GF_EVENT_MEDIA_BEGIN_SESSION_SETUP); + odm->net_service->ifce->ConnectService(odm->net_service->ifce, odm->net_service, odm->net_service->url); + + /*remove pending download session if any*/ + gf_term_cleanup_pending_session(term, ns); + + /*lock media queue after connecting*/ + gf_mx_p(term->media_queue_mx); + } + /*play ODs that need it*/ while (gf_list_count(term->media_queue)) { Bool destroy = 0; @@ -1270,9 +1307,14 @@ void gf_term_connect_object(GF_Terminal *term, GF_ObjectManager *odm, char *serv odm->net_service->nb_odm_users++; gf_term_lock_net(term, 0); - /*OK connect*/ - gf_term_service_media_event(odm, GF_EVENT_MEDIA_BEGIN_SESSION_SETUP); - odm->net_service->ifce->ConnectService(odm->net_service->ifce, odm->net_service, odm->net_service->url); + ns = odm->net_service; + + gf_mx_p(term->media_queue_mx); + /*we are all set but we cannot assume it is safe to call connect from this thread, as this could be a + script callback (JS locked) and connecting the media could trigger JS calls, which would deadlock*/ + gf_list_add(term->net_services_to_connect, odm); + + gf_mx_v(term->media_queue_mx); } /*connects given channel to its URL if needed*/ @@ -1303,6 +1345,7 @@ GF_Err gf_term_connect_remote_channel(GF_Terminal *term, GF_Channel *ch, char *U ch->service = ns; ns->ifce->ConnectService(ns->ifce, ns, ns->url); + gf_term_cleanup_pending_session(term, ns); gf_term_lock_net(term, 0); return GF_OK; } @@ -1448,6 +1491,7 @@ void gf_term_attach_service(GF_Terminal *term, GF_InputService *service_hdl) Bool net_check_interface(GF_InputService *ifce); GF_Scene *scene; GF_ObjectManager *odm; + GF_ClientService *ns; if (!net_check_interface(service_hdl)) return; if (term->root_scene) gf_term_disconnect(term); @@ -1475,8 +1519,11 @@ void gf_term_attach_service(GF_Terminal *term, GF_InputService *service_hdl) gf_term_lock_net(term, 0); + ns = odm->net_service; /*OK connect*/ odm->net_service->ifce->ConnectService(odm->net_service->ifce, odm->net_service, odm->net_service->url); + + gf_term_cleanup_pending_session(term, ns); } GF_EXPORT @@ -1596,6 +1643,12 @@ GF_Err gf_term_get_screen_buffer(GF_Terminal *term, GF_VideoSurface *framebuffer return gf_sc_get_screen_buffer(term->compositor, framebuffer, 0); } +GF_Err gf_term_get_offscreen_buffer(GF_Terminal *term, GF_VideoSurface *framebuffer, u32 view_idx, u32 depth_buffer_type) +{ + if (!term) return GF_BAD_PARAM; + return gf_sc_get_offscreen_buffer(term->compositor, framebuffer, view_idx, depth_buffer_type); +} + GF_Err gf_term_release_screen_buffer(GF_Terminal *term, GF_VideoSurface *framebuffer) { if (!term) return GF_BAD_PARAM; @@ -1606,20 +1659,27 @@ GF_Err gf_term_release_screen_buffer(GF_Terminal *term, GF_VideoSurface *framebu static void gf_term_sample_scenetime(GF_Scene *scene) { u32 i, count; - gf_term_lock_net(scene->root_od->term, 1); + Bool locked = gf_mx_try_lock(scene->root_od->term->net_mx); + /*we cannot grab the network mutex, therefore we are not sure if some resources are not being destroyed. + TODO: add a dedicated mutex for this condition instead of using the global net mutex*/ + if (!locked) return; + gf_scene_sample_time(scene); count = gf_list_count(scene->resources); for (i=0; iresources, i); if (odm->subscene) gf_term_sample_scenetime(odm->subscene); } - gf_term_lock_net(scene->root_od->term, 0); + gf_mx_v(scene->root_od->term->net_mx); } u32 gf_term_sample_clocks(GF_Terminal *term) { - gf_term_sample_scenetime(term->root_scene); - return (u32) (1000*term->root_scene->simulation_time); + if (term->root_scene) { + gf_term_sample_scenetime(term->root_scene); + return (u32) (1000*term->root_scene->simulation_time); + } + return 0; } const char *gf_term_get_text_selection(GF_Terminal *term, Bool probe_only) @@ -1721,6 +1781,8 @@ enum GF_ACTION_SLOW_REWIND, GF_ACTION_NEXT, GF_ACTION_PREVIOUS, + GF_ACTION_QUALITY_UP, + GF_ACTION_QUALITY_DOWN, }; static void set_clocks_speed(GF_Terminal *term, Fixed ratio) @@ -1894,6 +1956,12 @@ void gf_term_process_shortcut(GF_Terminal *term, GF_Event *ev) set_clocks_speed(term, term->speed_ratio); } break; + case GF_ACTION_QUALITY_UP: + gf_term_switch_quality(term, 1); + break; + case GF_ACTION_QUALITY_DOWN: + gf_term_switch_quality(term, 0); + break; } break; } @@ -1951,6 +2019,8 @@ void gf_term_load_shortcuts(GF_Terminal *term) else if (!stricmp(name, "SlowRewind")) term->shortcuts[k].action = GF_ACTION_SLOW_REWIND; else if (!stricmp(name, "Next")) term->shortcuts[k].action = GF_ACTION_NEXT; else if (!stricmp(name, "Previous")) term->shortcuts[k].action = GF_ACTION_PREVIOUS; + else if (!stricmp(name, "QualityUp")) term->shortcuts[k].action = GF_ACTION_QUALITY_UP; + else if (!stricmp(name, "QualityDown")) term->shortcuts[k].action = GF_ACTION_QUALITY_DOWN; else { term->shortcuts[k].mods = 0; term->shortcuts[k].code = 0; @@ -1966,16 +2036,26 @@ void gf_scene_switch_quality(GF_Scene *scene, Bool up) u32 i; GF_ObjectManager *odm; GF_CodecCapability caps; + GF_NetworkCommand net_cmd; + if (!scene) return; caps.CapCode = GF_CODEC_MEDIA_SWITCH_QUALITY; caps.cap.valueInt = up ? 1 : 0; + net_cmd.command_type = GF_NET_SERVICE_QUALITY_SWITCH; + net_cmd.switch_quality.on_channel = NULL; + net_cmd.switch_quality.up = up; + if (scene->scene_codec) { scene->scene_codec->decio->SetCapabilities(scene->scene_codec->decio, caps); + if (scene->root_od->net_service) + scene->root_od->net_service->ifce->ServiceCommand(scene->root_od->net_service->ifce, &net_cmd); } i=0; while (NULL != (odm = gf_list_enum(scene->resources, &i))) { if (odm->codec) odm->codec->decio->SetCapabilities(odm->codec->decio, caps); + if (odm->net_service) + odm->net_service->ifce->ServiceCommand(odm->net_service->ifce, &net_cmd); if (odm->subscene) gf_scene_switch_quality(odm->subscene, up); } diff --git a/src/utils/alloc.c b/src/utils/alloc.c index 02f3184..846fbab 100644 --- a/src/utils/alloc.c +++ b/src/utils/alloc.c @@ -1,712 +1,712 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Romain Bouqueau - Jean Le Feuvre - * Copyright (c) Telecom ParisTech 2010-20XX - * - * All rights reserved - * - * This file is part of GPAC / common tools 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. - * - */ - -#if !defined(WIN32) && !defined(_WIN32_WCE) -/* This is needed for asprintf */ -#define _GNU_SOURCE -#include -#include -#endif - -#include - - -#define STD_MALLOC 0 -#define GOOGLE_MALLOC 1 -#define INTEL_MALLOC 2 -#define DL_MALLOC 3 - -#ifdef WIN32 -#define USE_MALLOC STD_MALLOC -#else -#define USE_MALLOC STD_MALLOC -#endif - - -#if defined(_WIN32_WCE) && !defined(strdup) -#define strdup _strdup -#endif - -/* - WARNING - you must enable C++ style compilation of this file (error.c) to be able to compile - with google malloc. This is not set by default in the project settings. -*/ -#if (USE_MALLOC==GOOGLE_MALLOC) -#include -#include -#include - -#ifdef WIN32 -#pragma comment(lib, "libtcmalloc_minimal") -#endif - -#define MALLOC malloc -#define CALLOC calloc -#define REALLOC realloc -#define FREE free -#define STRDUP(a) return strdup(a); - -/*we must use c++ compiler for google malloc :( */ -#define CDECL extern "C" -#endif - -#if (USE_MALLOC==INTEL_MALLOC) -#define CDECL -CDECL void * scalable_malloc(size_t size); -CDECL void * scalable_realloc(void* ptr, size_t size); -CDECL void * scalable_calloc(size_t num, size_t size); -CDECL void scalable_free(void* ptr); - -#ifdef WIN32 -#pragma comment(lib, "tbbmalloc.lib") -#endif - -#define MALLOC scalable_malloc -#define CALLOC scalable_calloc -#define REALLOC scalable_realloc -#define FREE scalable_free -#define STRDUP(_a) if (_a) { unsigned int len = strlen(_a)+1; char *ptr = (char *) scalable_malloc(len); strcpy(ptr, _a); return ptr; } else { return NULL; } - -#endif - -#ifndef CDECL -#define CDECL -#endif - -#if (USE_MALLOC==DL_MALLOC) - -CDECL void * dlmalloc(size_t size); -CDECL void * dlrealloc(void* ptr, size_t size); -CDECL void * dlcalloc(size_t num, size_t size); -CDECL void dlfree(void* ptr); - -#define MALLOC dlmalloc -#define CALLOC dlcalloc -#define REALLOC dlrealloc -#define FREE dlfree -#define STRDUP(_a) if (_a) { unsigned int len = strlen(_a)+1; char *ptr = (char *) dlmalloc(len); strcpy(ptr, _a); return ptr; } else { return NULL; } - -#endif - -#if (USE_MALLOC==STD_MALLOC) - -#include - -#define MALLOC malloc -#define CALLOC calloc -#define REALLOC realloc -#define FREE free -#define STRDUP(a) return strdup(a); - -#endif - - - -#ifndef _WIN32_WCE -#include -#endif - -/*This is to handle cases where config.h is generated at the root of the gpac build tree (./configure) -This is only needed when building libgpac and modules when libgpac is not installed*/ -#ifdef GPAC_HAVE_CONFIG_H -# include "config.h" -#else -# include -#endif - -/*GPAC memory tracking*/ -#ifndef GPAC_MEMORY_TRACKING - -CDECL -void *gf_malloc(size_t size) -{ - return MALLOC(size); -} -CDECL -void *gf_calloc(size_t num, size_t size_of) -{ - return CALLOC(num, size_of); -} -CDECL -void *gf_realloc(void *ptr, size_t size) -{ - return REALLOC(ptr, size); -} -CDECL -void gf_free(void *ptr) -{ - FREE(ptr); -} -CDECL -char *gf_strdup(const char *str) -{ - STRDUP(str); -} - -#else - - -CDECL -size_t gpac_allocated_memory = 0; -size_t gpac_nb_alloc_blocs = 0; - -#ifdef _WIN32_WCE -#define assert(p) -#endif - -static void register_address(void *ptr, size_t size, char *filename, int line); -static int unregister_address(void *ptr, char *filename, int line); - -static void gf_memory_log(unsigned int level, const char *fmt, ...); -enum -{ - /*! Log message describes an error*/ - GF_MEMORY_ERROR = 1, - /*! Log message describes a warning*/ - GF_MEMORY_WARNING, - /*! Log message is informational (state, etc..)*/ - GF_MEMORY_INFO, - /*! Log message is a debug info*/ - GF_MEMORY_DEBUG, -}; - -static void *gf_mem_malloc_basic(size_t size, char *filename, int line) -{ - return MALLOC(size); -} -static void *gf_mem_calloc_basic(size_t num, size_t size_of, char *filename, int line) -{ - return CALLOC(num, size_of); -} -static void *gf_mem_realloc_basic(void *ptr, size_t size, char *filename, int line) -{ - return REALLOC(ptr, size); -} -static void gf_mem_free_basic(void *ptr, char *filename, int line) -{ - FREE(ptr); -} -static char *gf_mem_strdup_basic(const char *str, char *filename, int line) -{ - STRDUP(str); -} - -void *gf_mem_malloc_tracker(size_t size, char *filename, int line) -{ - void *ptr = MALLOC(size); - if (!ptr) { - gf_memory_log(GF_MEMORY_ERROR, "[MemTracker] malloc() has returned a NULL pointer\n"); - assert(0); - } else { - register_address(ptr, size, filename, line); - } - gf_memory_log(GF_MEMORY_DEBUG, "[MemTracker] malloc %3d bytes at 0x%08X\n in file %s at line %d\n", size, ptr, filename, line); - return ptr; -} - -void *gf_mem_calloc_tracker(size_t num, size_t size_of, char *filename, int line) -{ - size_t size = num*size_of; - void *ptr = CALLOC(num, size_of); - if (!ptr) { - gf_memory_log(GF_MEMORY_ERROR, "[MemTracker] calloc() has returned a NULL pointer\n"); - assert(0); - } else { - register_address(ptr, size, filename, line); - } - gf_memory_log(GF_MEMORY_DEBUG, "[MemTracker] calloc %3d bytes at 0x%08X\n in file %s at line %d\n", size, ptr, filename, line); - return ptr; -} - -void gf_mem_free_tracker(void *ptr, char *filename, int line) -{ - int size_prev; - if (ptr && (size_prev=unregister_address(ptr, filename, line))) { - gf_memory_log(GF_MEMORY_DEBUG, "[MemTracker] free %3d bytes at 0x%08X\n in file %s at line %d\n", size_prev, ptr, filename, line); - FREE(ptr); - } -} - -void *gf_mem_realloc_tracker(void *ptr, size_t size, char *filename, int line) -{ - void *ptr_g; - int size_prev; - if (!ptr) { - gf_memory_log(GF_MEMORY_DEBUG, "[MemTracker] realloc() from a null pointer: calling malloc() instead\n"); - return gf_mem_malloc_tracker(size, filename, line); - } - /*a) The return value is NULL if the size is zero and the buffer argument is not NULL. In this case, the original block is freed.*/ - if (!size) { - gf_memory_log(GF_MEMORY_DEBUG, "[MemTracker] realloc() with a null size: calling free() instead\n"); - gf_mem_free_tracker(ptr, filename, line); - return NULL; - } - ptr_g = REALLOC(ptr, size); - if (!ptr_g) { - /*b) The return value is NULL if there is not enough available memory to expand the block to the given size. In this case, the original block is unchanged.*/ - gf_memory_log(GF_MEMORY_ERROR, "[MemTracker] realloc() has returned a NULL pointer\n"); - assert(0); - } else { - size_prev = unregister_address(ptr, filename, line); - register_address(ptr_g, size, filename, line); - gf_memory_log(GF_MEMORY_DEBUG, "[MemTracker] realloc %3d (instead of %3d) bytes at 0x%08X (instead of 0x%08X)\n in file %s at line %d\n", size, size_prev, ptr_g, ptr, filename, line); - } - return ptr_g; -} - -char *gf_mem_strdup_tracker(const char *str, char *filename, int line) -{ - char *ptr; - if (!str) return NULL; - ptr = (char*)gf_mem_malloc_tracker(strlen(str)+1, filename, line); - strcpy(ptr, str); - return ptr; -} - -static void *(*gf_mem_malloc_proto)(size_t size, char *filename, int line) = gf_mem_malloc_basic; -static void *(*gf_mem_calloc_proto)(size_t num, size_t size_of, char *filename, int line) = gf_mem_calloc_basic; -static void *(*gf_mem_realloc_proto)(void *ptr, size_t size, char *filename, int line) = gf_mem_realloc_basic; -static void (*gf_mem_free_proto)(void *ptr, char *filename, int line) = gf_mem_free_basic; -static char *(*gf_mem_strdup_proto)(const char *str, char *filename, int line) = gf_mem_strdup_basic; - -CDECL -void *gf_mem_malloc(size_t size, char *filename, int line) -{ - return gf_mem_malloc_proto(size, filename, line); -} -CDECL -void *gf_mem_calloc(size_t num, size_t size_of, char *filename, int line) -{ - return gf_mem_calloc_proto(num, size_of, filename, line); -} -CDECL -void *gf_mem_realloc(void *ptr, size_t size, char *filename, int line) -{ - return gf_mem_realloc_proto(ptr, size, filename, line); -} -CDECL -void gf_mem_free(void *ptr, char *filename, int line) -{ - gf_mem_free_proto(ptr, filename, line); -} -CDECL -char *gf_mem_strdup(const char *str, char *filename, int line) -{ - return gf_mem_strdup_proto(str, filename, line); -} - -CDECL -void gf_mem_enable_tracker() -{ - gf_mem_malloc_proto = gf_mem_malloc_tracker; - gf_mem_calloc_proto = gf_mem_calloc_tracker; - gf_mem_realloc_proto = gf_mem_realloc_tracker; - gf_mem_free_proto = gf_mem_free_tracker; - gf_mem_strdup_proto = gf_mem_strdup_tracker; -} - - -#define GPAC_MEMORY_TRACKING_HASH_TABLE 1 -#if GPAC_MEMORY_TRACKING_HASH_TABLE - -#define HASH_ENTRIES 4096 - -typedef struct s_memory_element -{ - void *ptr; - int size; - struct s_memory_element *next; - int line; - char *filename; -} memory_element; - -/*pointer to the first element of the list*/ -typedef memory_element** memory_list; - -static unsigned int gf_memory_hash(void *ptr) -{ - return (((unsigned int)ptr>>4)+(unsigned int)ptr)%HASH_ENTRIES; -} - -#else - -typedef struct s_memory_element -{ - void *ptr; - int size; - struct s_memory_element *next; - int line; - char *filename; -} memory_element; - -/*pointer to the first element of the list*/ -typedef memory_element* memory_list; - -#endif - - -/*base functions (add, find, del_item, del) are implemented upon a stack model*/ -static void gf_memory_add_stack(memory_element **p, void *ptr, int size, char *filename, int line) -{ - memory_element *element = (memory_element*)MALLOC(sizeof(memory_element)+strlen(filename)+1); - element->ptr = ptr; - element->size = size; - element->line = line; - element->next = *p; - element->filename = (char*)&(element->filename)+sizeof(element->filename); - strcpy(element->filename, filename); - *p = element; -} - -/*returns the position of a ptr from a memory_element, 0 if not found*/ -static int gf_memory_find_stack(memory_element *p, void *ptr) -{ - int i = 1; - memory_element *element = p; - while (element) { - if (element->ptr == ptr) { - return i; - } - element = element->next; - i++; - } - return 0; -} - -/*returns the size of the deleted item*/ -static int gf_memory_del_item_stack(memory_element **p, void *ptr) -{ - int size; - memory_element *curr_element=*p, *prev_element=NULL; - while (curr_element) { - if (curr_element->ptr == ptr) { - if (prev_element) prev_element->next = curr_element->next; - else *p = curr_element->next; - size = curr_element->size; - FREE(curr_element); - return size; - } - prev_element = curr_element; - curr_element = curr_element->next; - } - return 0; -} - -static void gf_memory_del_stack(memory_element **p) -{ - memory_element *curr_element=*p, *next_element; - while (curr_element) { - next_element = curr_element->next; - FREE(curr_element); - curr_element = next_element; - } - *p = NULL; -} - - -#if GPAC_MEMORY_TRACKING_HASH_TABLE - -/*this list is implemented as a stack to minimise the cost of freeing recent allocations*/ -static void gf_memory_add(memory_list *p, void *ptr, int size, char *filename, int line) -{ - unsigned int hash; - if (!*p) *p = (memory_list) CALLOC(HASH_ENTRIES, sizeof(memory_element*)); - assert(*p); - - hash = gf_memory_hash(ptr); - gf_memory_add_stack(&((*p)[hash]), ptr, size, filename, line); -} - - -static int gf_memory_find(memory_list p, void *ptr) -{ - unsigned int hash; - assert(p); - if (!p) return 0; - hash = gf_memory_hash(ptr); - return gf_memory_find_stack(p[hash], ptr); -} - -static int gf_memory_del_item(memory_list *p, void *ptr) -{ - unsigned int hash; - int ret; - memory_element **sub_list; - if (!*p) *p = (memory_list) CALLOC(HASH_ENTRIES, sizeof(memory_element*)); - assert(*p); - hash = gf_memory_hash(ptr); - sub_list = &((*p)[hash]); - if (!sub_list) return 0; - ret = gf_memory_del_item_stack(sub_list, ptr); - if (ret && !((*p)[hash])) { - /*check for deletion*/ - int i; - for (i=0; i - - -/*GPAC memory tracking*/ -#ifdef GPAC_MEMORY_TRACKING - -#include - -/*global lists of allocations and deallocations*/ -memory_list memory_add = NULL, memory_rem = NULL; -GF_Mutex *gpac_allocations_lock = NULL; - -static void register_address(void *ptr, size_t size, char *filename, int line) -{ - /*mutex initialization*/ - if (gpac_allocations_lock == 0) { - assert(!memory_add); - assert(!memory_rem); - gpac_allocations_lock = (GF_Mutex*)1; /*must be non-null to avoid a recursive infinite call*/ - gpac_allocations_lock = gf_mx_new("gpac_allocations_lock"); - } - else if (gpac_allocations_lock == (void*)1) { - /*we're initializing the mutex (ie called by the gf_mx_new() above)*/ - return; - } - - /*lock*/ - gf_mx_p(gpac_allocations_lock); - - gf_memory_add(&memory_add, ptr, size, filename, line); - gf_memory_del_item(&memory_rem, ptr); /*the same block can be reallocated, so remove it from the deallocation list*/ - - /*update stats*/ - gpac_allocated_memory += size; - gpac_nb_alloc_blocs++; - - /*gf_memory_log(GF_MEMORY_DEBUG, "[MemTracker] register %6d bytes at 0x%08X (%8d Bytes in %4d Blocks allocated)\n", size, ptr, gpac_allocated_memory, gpac_nb_alloc_blocs);*/ - - /*unlock*/ - gf_mx_v(gpac_allocations_lock); -} - -/*returns the size of the unregistered block*/ -static int unregister_address(void *ptr, char *filename, int line) -{ - int size = 0; /*default: failure*/ - - /*lock*/ - gf_mx_p(gpac_allocations_lock); - - if (!memory_add) { - if (!memory_rem) { - /*assume we're rather destroying the mutex (ie calling the gf_mx_del() below) - than being called by free() before the first allocation occured*/ - return 1; - /*gf_memory_log(GF_MEMORY_ERROR, "[MemTracker] calling free() before the first allocation occured\n"); - assert(0); */ - } - } else { - if (!gf_memory_find(memory_add, ptr)) { - int pos; - if (!(pos=gf_memory_find(memory_rem, ptr))) { - gf_memory_log(GF_MEMORY_ERROR, "[MemTracker] trying to free a never allocated block (0x%08X)\n", ptr); - /* assert(0); */ /*don't assert since this is often due to allocations that occured out of gpac (fonts, etc.)*/ - } else { - int i; - unsigned int hash = gf_memory_hash(ptr); - memory_element *element = memory_rem[hash]; - assert(element); - for (i=1; inext; - assert(element); - gf_memory_log(GF_MEMORY_ERROR, "[MemTracker] the block 0x%08X trying to be deleted\n in file %s at line %d\n has already been freed\n in file %s at line %d\n", ptr, filename, line, element->filename, element->line); - assert(0); - } - } else { - size = gf_memory_del_item(&memory_add, ptr); - assert(size>=0); - - /*update stats*/ - gpac_allocated_memory -= size; - gpac_nb_alloc_blocs--; - - /*gf_memory_log(GF_MEMORY_DEBUG, "[MemTracker] unregister %6d bytes at 0x%08X (%8d bytes in %4d blocks remaining)\n", size, ptr, gpac_allocated_memory, gpac_nb_alloc_blocs); */ - - /*the allocation list is empty: free the lists to avoid a leak (we should be exiting)*/ - if (!memory_add) { - assert(!gpac_allocated_memory); - assert(!gpac_nb_alloc_blocs); - - /*we destroy the mutex we own, then we return*/ - gf_mx_del(gpac_allocations_lock); - gpac_allocations_lock = NULL; - - gf_memory_log(GF_MEMORY_DEBUG, "[MemTracker] the allocated-blocks-list is empty: the freed-blocks-list will be emptied too.\n"); - gf_memory_del(&memory_rem); - - return size; - } else { - gf_memory_add(&memory_rem, ptr, size, filename, line); - } - } - } - - /*unlock*/ - gf_mx_v(gpac_allocations_lock); - - return size; -} - -static void gf_memory_log(unsigned int level, const char *fmt, ...) -{ - va_list vl; - char msg[1024]; - assert(strlen(fmt) < 200); - va_start(vl, fmt); - vsprintf(msg, fmt, vl); - GF_LOG(level, GF_LOG_MEMORY, (msg)); - va_end(vl); -} - -/*prints allocations sum-up*/ -void gf_memory_size() -{ - unsigned int level = gpac_nb_alloc_blocs ? GF_MEMORY_WARNING : GF_MEMORY_INFO; - gf_memory_log(level, "[MemTracker] Total: %d bytes allocated on %d blocks\n", gpac_allocated_memory, gpac_nb_alloc_blocs); -} - -/*prints the state of current allocations*/ -void gf_memory_print() -{ - /*if lists are empty, the mutex is also NULL*/ - if (!memory_add) { - assert(!gpac_allocations_lock); - gf_memory_log(GF_MEMORY_INFO, "[MemTracker] gf_memory_print(): the memory tracker is not initialized.\n"); - } else { - int i=0; - assert(gpac_allocations_lock); - - gf_memory_log(GF_MEMORY_INFO, "\n[MemTracker] Printing the current state of allocations:\n"); - - /*lock*/ - gf_mx_p(gpac_allocations_lock); -#if GPAC_MEMORY_TRACKING_HASH_TABLE - for (i=0; inext; - gf_memory_log(GF_MEMORY_INFO, "[MemTracker] Memory Block 0x%08X (size %d) allocated\n in file %s at line %d\n", curr_element->ptr, curr_element->size, curr_element->filename, curr_element->line); - curr_element = next_element; - } - } - gf_memory_size(); - - /*unlock*/ - gf_mx_v(gpac_allocations_lock); - } -} - -#endif /*GPAC_MEMORY_TRACKING*/ - - -/*gf_asprintf(): as_printf portable implementation*/ -#if defined(WIN32) || defined(_WIN32_WCE) -static GFINLINE int gf_vasprintf (char **strp, const char *fmt, va_list ap) -{ - int vsn_ret, size; - char *buffer, *realloc_buffer; - - size = 2*strlen(fmt); /*first guess for the size*/ - buffer = (char*)gf_malloc(size); - if (buffer == NULL) - return -1; - - while (1) { - vsn_ret = _vsnprintf(buffer, size, fmt, ap); - - /* If that worked, return the string. */ - if (vsn_ret>-1 && vsn_ret +#include +#endif + +#include + + +#define STD_MALLOC 0 +#define GOOGLE_MALLOC 1 +#define INTEL_MALLOC 2 +#define DL_MALLOC 3 + +#ifdef WIN32 +#define USE_MALLOC STD_MALLOC +#else +#define USE_MALLOC STD_MALLOC +#endif + + +#if defined(_WIN32_WCE) && !defined(strdup) +#define strdup _strdup +#endif + +/* + WARNING - you must enable C++ style compilation of this file (error.c) to be able to compile + with google malloc. This is not set by default in the project settings. +*/ +#if (USE_MALLOC==GOOGLE_MALLOC) +#include +#include +#include + +#ifdef WIN32 +#pragma comment(lib, "libtcmalloc_minimal") +#endif + +#define MALLOC malloc +#define CALLOC calloc +#define REALLOC realloc +#define FREE free +#define STRDUP(a) return strdup(a); + +/*we must use c++ compiler for google malloc :( */ +#define CDECL extern "C" +#endif + +#if (USE_MALLOC==INTEL_MALLOC) +#define CDECL +CDECL void * scalable_malloc(size_t size); +CDECL void * scalable_realloc(void* ptr, size_t size); +CDECL void * scalable_calloc(size_t num, size_t size); +CDECL void scalable_free(void* ptr); + +#ifdef WIN32 +#pragma comment(lib, "tbbmalloc.lib") +#endif + +#define MALLOC scalable_malloc +#define CALLOC scalable_calloc +#define REALLOC scalable_realloc +#define FREE scalable_free +#define STRDUP(_a) if (_a) { unsigned int len = strlen(_a)+1; char *ptr = (char *) scalable_malloc(len); strcpy(ptr, _a); return ptr; } else { return NULL; } + +#endif + +#ifndef CDECL +#define CDECL +#endif + +#if (USE_MALLOC==DL_MALLOC) + +CDECL void * dlmalloc(size_t size); +CDECL void * dlrealloc(void* ptr, size_t size); +CDECL void * dlcalloc(size_t num, size_t size); +CDECL void dlfree(void* ptr); + +#define MALLOC dlmalloc +#define CALLOC dlcalloc +#define REALLOC dlrealloc +#define FREE dlfree +#define STRDUP(_a) if (_a) { unsigned int len = strlen(_a)+1; char *ptr = (char *) dlmalloc(len); strcpy(ptr, _a); return ptr; } else { return NULL; } + +#endif + +#if (USE_MALLOC==STD_MALLOC) + +#include + +#define MALLOC malloc +#define CALLOC calloc +#define REALLOC realloc +#define FREE free +#define STRDUP(a) return strdup(a); + +#endif + + + +#ifndef _WIN32_WCE +#include +#endif + +/*This is to handle cases where config.h is generated at the root of the gpac build tree (./configure) +This is only needed when building libgpac and modules when libgpac is not installed*/ +#ifdef GPAC_HAVE_CONFIG_H +# include "config.h" +#else +# include +#endif + +/*GPAC memory tracking*/ +#ifndef GPAC_MEMORY_TRACKING + +CDECL +void *gf_malloc(size_t size) +{ + return MALLOC(size); +} +CDECL +void *gf_calloc(size_t num, size_t size_of) +{ + return CALLOC(num, size_of); +} +CDECL +void *gf_realloc(void *ptr, size_t size) +{ + return REALLOC(ptr, size); +} +CDECL +void gf_free(void *ptr) +{ + FREE(ptr); +} +CDECL +char *gf_strdup(const char *str) +{ + STRDUP(str); +} + +#else + + +CDECL +size_t gpac_allocated_memory = 0; +size_t gpac_nb_alloc_blocs = 0; + +#ifdef _WIN32_WCE +#define assert(p) +#endif + +static void register_address(void *ptr, size_t size, char *filename, int line); +static int unregister_address(void *ptr, char *filename, int line); + +static void gf_memory_log(unsigned int level, const char *fmt, ...); +enum +{ + /*! Log message describes an error*/ + GF_MEMORY_ERROR = 1, + /*! Log message describes a warning*/ + GF_MEMORY_WARNING, + /*! Log message is informational (state, etc..)*/ + GF_MEMORY_INFO, + /*! Log message is a debug info*/ + GF_MEMORY_DEBUG, +}; + +static void *gf_mem_malloc_basic(size_t size, char *filename, int line) +{ + return MALLOC(size); +} +static void *gf_mem_calloc_basic(size_t num, size_t size_of, char *filename, int line) +{ + return CALLOC(num, size_of); +} +static void *gf_mem_realloc_basic(void *ptr, size_t size, char *filename, int line) +{ + return REALLOC(ptr, size); +} +static void gf_mem_free_basic(void *ptr, char *filename, int line) +{ + FREE(ptr); +} +static char *gf_mem_strdup_basic(const char *str, char *filename, int line) +{ + STRDUP(str); +} + +void *gf_mem_malloc_tracker(size_t size, char *filename, int line) +{ + void *ptr = MALLOC(size); + if (!ptr) { + gf_memory_log(GF_MEMORY_ERROR, "[MemTracker] malloc() has returned a NULL pointer\n"); + assert(0); + } else { + register_address(ptr, size, filename, line); + } + gf_memory_log(GF_MEMORY_DEBUG, "[MemTracker] malloc %3d bytes at %p\n in file %s at line %d\n", size, ptr, filename, line); + return ptr; +} + +void *gf_mem_calloc_tracker(size_t num, size_t size_of, char *filename, int line) +{ + size_t size = num*size_of; + void *ptr = CALLOC(num, size_of); + if (!ptr) { + gf_memory_log(GF_MEMORY_ERROR, "[MemTracker] calloc() has returned a NULL pointer\n"); + assert(0); + } else { + register_address(ptr, size, filename, line); + } + gf_memory_log(GF_MEMORY_DEBUG, "[MemTracker] calloc %3d bytes at %p\n in file %s at line %d\n", size, ptr, filename, line); + return ptr; +} + +void gf_mem_free_tracker(void *ptr, char *filename, int line) +{ + int size_prev; + if (ptr && (size_prev=unregister_address(ptr, filename, line))) { + gf_memory_log(GF_MEMORY_DEBUG, "[MemTracker] free %3d bytes at %p\n in file %s at line %d\n", size_prev, ptr, filename, line); + FREE(ptr); + } +} + +void *gf_mem_realloc_tracker(void *ptr, size_t size, char *filename, int line) +{ + void *ptr_g; + int size_prev; + if (!ptr) { + gf_memory_log(GF_MEMORY_DEBUG, "[MemTracker] realloc() from a null pointer: calling malloc() instead\n"); + return gf_mem_malloc_tracker(size, filename, line); + } + /*a) The return value is NULL if the size is zero and the buffer argument is not NULL. In this case, the original block is freed.*/ + if (!size) { + gf_memory_log(GF_MEMORY_DEBUG, "[MemTracker] realloc() with a null size: calling free() instead\n"); + gf_mem_free_tracker(ptr, filename, line); + return NULL; + } + ptr_g = REALLOC(ptr, size); + if (!ptr_g) { + /*b) The return value is NULL if there is not enough available memory to expand the block to the given size. In this case, the original block is unchanged.*/ + gf_memory_log(GF_MEMORY_ERROR, "[MemTracker] realloc() has returned a NULL pointer\n"); + assert(0); + } else { + size_prev = unregister_address(ptr, filename, line); + register_address(ptr_g, size, filename, line); + gf_memory_log(GF_MEMORY_DEBUG, "[MemTracker] realloc %3d (instead of %3d) bytes at %p (instead of %p)\n in file %s at line %d\n", size, size_prev, ptr_g, ptr, filename, line); + } + return ptr_g; +} + +char *gf_mem_strdup_tracker(const char *str, char *filename, int line) +{ + char *ptr; + if (!str) return NULL; + ptr = (char*)gf_mem_malloc_tracker(strlen(str)+1, filename, line); + strcpy(ptr, str); + return ptr; +} + +static void *(*gf_mem_malloc_proto)(size_t size, char *filename, int line) = gf_mem_malloc_basic; +static void *(*gf_mem_calloc_proto)(size_t num, size_t size_of, char *filename, int line) = gf_mem_calloc_basic; +static void *(*gf_mem_realloc_proto)(void *ptr, size_t size, char *filename, int line) = gf_mem_realloc_basic; +static void (*gf_mem_free_proto)(void *ptr, char *filename, int line) = gf_mem_free_basic; +static char *(*gf_mem_strdup_proto)(const char *str, char *filename, int line) = gf_mem_strdup_basic; + +CDECL +void *gf_mem_malloc(size_t size, char *filename, int line) +{ + return gf_mem_malloc_proto(size, filename, line); +} +CDECL +void *gf_mem_calloc(size_t num, size_t size_of, char *filename, int line) +{ + return gf_mem_calloc_proto(num, size_of, filename, line); +} +CDECL +void *gf_mem_realloc(void *ptr, size_t size, char *filename, int line) +{ + return gf_mem_realloc_proto(ptr, size, filename, line); +} +CDECL +void gf_mem_free(void *ptr, char *filename, int line) +{ + gf_mem_free_proto(ptr, filename, line); +} +CDECL +char *gf_mem_strdup(const char *str, char *filename, int line) +{ + return gf_mem_strdup_proto(str, filename, line); +} + +CDECL +void gf_mem_enable_tracker() +{ + gf_mem_malloc_proto = gf_mem_malloc_tracker; + gf_mem_calloc_proto = gf_mem_calloc_tracker; + gf_mem_realloc_proto = gf_mem_realloc_tracker; + gf_mem_free_proto = gf_mem_free_tracker; + gf_mem_strdup_proto = gf_mem_strdup_tracker; +} + + +#define GPAC_MEMORY_TRACKING_HASH_TABLE 1 +#if GPAC_MEMORY_TRACKING_HASH_TABLE + +#define HASH_ENTRIES 4096 + +typedef struct s_memory_element +{ + void *ptr; + int size; + struct s_memory_element *next; + int line; + char *filename; +} memory_element; + +/*pointer to the first element of the list*/ +typedef memory_element** memory_list; + +static unsigned int gf_memory_hash(void *ptr) +{ + return (((unsigned int)ptr>>4)+(unsigned int)ptr)%HASH_ENTRIES; +} + +#else + +typedef struct s_memory_element +{ + void *ptr; + int size; + struct s_memory_element *next; + int line; + char *filename; +} memory_element; + +/*pointer to the first element of the list*/ +typedef memory_element* memory_list; + +#endif + + +/*base functions (add, find, del_item, del) are implemented upon a stack model*/ +static void gf_memory_add_stack(memory_element **p, void *ptr, int size, char *filename, int line) +{ + memory_element *element = (memory_element*)MALLOC(sizeof(memory_element)+strlen(filename)+1); + element->ptr = ptr; + element->size = size; + element->line = line; + element->next = *p; + element->filename = (char*)&(element->filename)+sizeof(element->filename); + strcpy(element->filename, filename); + *p = element; +} + +/*returns the position of a ptr from a memory_element, 0 if not found*/ +static int gf_memory_find_stack(memory_element *p, void *ptr) +{ + int i = 1; + memory_element *element = p; + while (element) { + if (element->ptr == ptr) { + return i; + } + element = element->next; + i++; + } + return 0; +} + +/*returns the size of the deleted item*/ +static int gf_memory_del_item_stack(memory_element **p, void *ptr) +{ + int size; + memory_element *curr_element=*p, *prev_element=NULL; + while (curr_element) { + if (curr_element->ptr == ptr) { + if (prev_element) prev_element->next = curr_element->next; + else *p = curr_element->next; + size = curr_element->size; + FREE(curr_element); + return size; + } + prev_element = curr_element; + curr_element = curr_element->next; + } + return 0; +} + +static void gf_memory_del_stack(memory_element **p) +{ + memory_element *curr_element=*p, *next_element; + while (curr_element) { + next_element = curr_element->next; + FREE(curr_element); + curr_element = next_element; + } + *p = NULL; +} + + +#if GPAC_MEMORY_TRACKING_HASH_TABLE + +/*this list is implemented as a stack to minimise the cost of freeing recent allocations*/ +static void gf_memory_add(memory_list *p, void *ptr, int size, char *filename, int line) +{ + unsigned int hash; + if (!*p) *p = (memory_list) CALLOC(HASH_ENTRIES, sizeof(memory_element*)); + assert(*p); + + hash = gf_memory_hash(ptr); + gf_memory_add_stack(&((*p)[hash]), ptr, size, filename, line); +} + + +static int gf_memory_find(memory_list p, void *ptr) +{ + unsigned int hash; + assert(p); + if (!p) return 0; + hash = gf_memory_hash(ptr); + return gf_memory_find_stack(p[hash], ptr); +} + +static int gf_memory_del_item(memory_list *p, void *ptr) +{ + unsigned int hash; + int ret; + memory_element **sub_list; + if (!*p) *p = (memory_list) CALLOC(HASH_ENTRIES, sizeof(memory_element*)); + assert(*p); + hash = gf_memory_hash(ptr); + sub_list = &((*p)[hash]); + if (!sub_list) return 0; + ret = gf_memory_del_item_stack(sub_list, ptr); + if (ret && !((*p)[hash])) { + /*check for deletion*/ + int i; + for (i=0; i + + +/*GPAC memory tracking*/ +#ifdef GPAC_MEMORY_TRACKING + +#include + +/*global lists of allocations and deallocations*/ +memory_list memory_add = NULL, memory_rem = NULL; +GF_Mutex *gpac_allocations_lock = NULL; + +static void register_address(void *ptr, size_t size, char *filename, int line) +{ + /*mutex initialization*/ + if (gpac_allocations_lock == 0) { + assert(!memory_add); + assert(!memory_rem); + gpac_allocations_lock = (GF_Mutex*)1; /*must be non-null to avoid a recursive infinite call*/ + gpac_allocations_lock = gf_mx_new("gpac_allocations_lock"); + } + else if (gpac_allocations_lock == (void*)1) { + /*we're initializing the mutex (ie called by the gf_mx_new() above)*/ + return; + } + + /*lock*/ + gf_mx_p(gpac_allocations_lock); + + gf_memory_add(&memory_add, ptr, size, filename, line); + gf_memory_del_item(&memory_rem, ptr); /*the same block can be reallocated, so remove it from the deallocation list*/ + + /*update stats*/ + gpac_allocated_memory += size; + gpac_nb_alloc_blocs++; + + /*gf_memory_log(GF_MEMORY_DEBUG, "[MemTracker] register %6d bytes at %p (%8d Bytes in %4d Blocks allocated)\n", size, ptr, gpac_allocated_memory, gpac_nb_alloc_blocs);*/ + + /*unlock*/ + gf_mx_v(gpac_allocations_lock); +} + +/*returns the size of the unregistered block*/ +static int unregister_address(void *ptr, char *filename, int line) +{ + int size = 0; /*default: failure*/ + + /*lock*/ + gf_mx_p(gpac_allocations_lock); + + if (!memory_add) { + if (!memory_rem) { + /*assume we're rather destroying the mutex (ie calling the gf_mx_del() below) + than being called by free() before the first allocation occured*/ + return 1; + /*gf_memory_log(GF_MEMORY_ERROR, "[MemTracker] calling free() before the first allocation occured\n"); + assert(0); */ + } + } else { + if (!gf_memory_find(memory_add, ptr)) { + int pos; + if (!(pos=gf_memory_find(memory_rem, ptr))) { + gf_memory_log(GF_MEMORY_ERROR, "[MemTracker] trying to free a never allocated block (%p)\n", ptr); + /* assert(0); */ /*don't assert since this is often due to allocations that occured out of gpac (fonts, etc.)*/ + } else { + int i; + unsigned int hash = gf_memory_hash(ptr); + memory_element *element = memory_rem[hash]; + assert(element); + for (i=1; inext; + assert(element); + gf_memory_log(GF_MEMORY_ERROR, "[MemTracker] the block %p trying to be deleted\n in file %s at line %d\n has already been freed\n in file %s at line %d\n", ptr, filename, line, element->filename, element->line); + assert(0); + } + } else { + size = gf_memory_del_item(&memory_add, ptr); + assert(size>=0); + + /*update stats*/ + gpac_allocated_memory -= size; + gpac_nb_alloc_blocs--; + + /*gf_memory_log(GF_MEMORY_DEBUG, "[MemTracker] unregister %6d bytes at %p (%8d bytes in %4d blocks remaining)\n", size, ptr, gpac_allocated_memory, gpac_nb_alloc_blocs); */ + + /*the allocation list is empty: free the lists to avoid a leak (we should be exiting)*/ + if (!memory_add) { + assert(!gpac_allocated_memory); + assert(!gpac_nb_alloc_blocs); + + /*we destroy the mutex we own, then we return*/ + gf_mx_del(gpac_allocations_lock); + gpac_allocations_lock = NULL; + + gf_memory_log(GF_MEMORY_DEBUG, "[MemTracker] the allocated-blocks-list is empty: the freed-blocks-list will be emptied too.\n"); + gf_memory_del(&memory_rem); + + return size; + } else { + gf_memory_add(&memory_rem, ptr, size, filename, line); + } + } + } + + /*unlock*/ + gf_mx_v(gpac_allocations_lock); + + return size; +} + +static void gf_memory_log(unsigned int level, const char *fmt, ...) +{ + va_list vl; + char msg[1024]; + assert(strlen(fmt) < 200); + va_start(vl, fmt); + vsprintf(msg, fmt, vl); + GF_LOG(level, GF_LOG_MEMORY, (msg)); + va_end(vl); +} + +/*prints allocations sum-up*/ +void gf_memory_size() +{ + unsigned int level = gpac_nb_alloc_blocs ? GF_MEMORY_ERROR : GF_MEMORY_INFO; + gf_memory_log(level, "[MemTracker] Total: %d bytes allocated on %d blocks\n", gpac_allocated_memory, gpac_nb_alloc_blocs); +} + +/*prints the state of current allocations*/ +void gf_memory_print() +{ + /*if lists are empty, the mutex is also NULL*/ + if (!memory_add) { + assert(!gpac_allocations_lock); + gf_memory_log(GF_MEMORY_INFO, "[MemTracker] gf_memory_print(): the memory tracker is not initialized.\n"); + } else { + int i=0; + assert(gpac_allocations_lock); + + gf_memory_log(GF_MEMORY_INFO, "\n[MemTracker] Printing the current state of allocations:\n"); + + /*lock*/ + gf_mx_p(gpac_allocations_lock); +#if GPAC_MEMORY_TRACKING_HASH_TABLE + for (i=0; inext; + gf_memory_log(GF_MEMORY_INFO, "[MemTracker] Memory Block %p (size %d) allocated\n in file %s at line %d\n", curr_element->ptr, curr_element->size, curr_element->filename, curr_element->line); + curr_element = next_element; + } + } + gf_memory_size(); + + /*unlock*/ + gf_mx_v(gpac_allocations_lock); + } +} + +#endif /*GPAC_MEMORY_TRACKING*/ + + +/*gf_asprintf(): as_printf portable implementation*/ +#if defined(WIN32) || defined(_WIN32_WCE) +static GFINLINE int gf_vasprintf (char **strp, const char *fmt, va_list ap) +{ + int vsn_ret, size; + char *buffer, *realloc_buffer; + + size = 2*strlen(fmt); /*first guess for the size*/ + buffer = (char*)gf_malloc(size); + if (buffer == NULL) + return -1; + + while (1) { + vsn_ret = _vsnprintf(buffer, size, fmt, ap); + + /* If that worked, return the string. */ + if (vsn_ret>-1 && vsn_retbsmode) { + case GF_BITSTREAM_WRITE: + if (bs->position + repeat_count > bs->size) + return 0; + memset(bs->original + bs->position, byte, repeat_count); + bs->position += repeat_count; + return repeat_count; + case GF_BITSTREAM_WRITE_DYN: + /*need to gf_realloc ...*/ + if (bs->position+repeat_count> bs->size) { + if (bs->size + repeat_count > 0xFFFFFFFF) + return 0; + bs->original = (char*)gf_realloc(bs->original, sizeof(u32)*((u32) bs->size + repeat_count)); + if (!bs->original) + return 0; + bs->size += repeat_count; + } + memset(bs->original + bs->position, byte, repeat_count); + bs->position += repeat_count; + return repeat_count; + case GF_BITSTREAM_FILE_READ: + case GF_BITSTREAM_FILE_WRITE: + if (fwrite(&byte, 1, repeat_count, bs->stream) != repeat_count) return 0; + if (bs->size == bs->position) bs->size += repeat_count; + bs->position += repeat_count; + return repeat_count; + default: + return 0; + } +} + + + GF_EXPORT void gf_bs_write_float(GF_BitStream *bs, Float value) { diff --git a/src/utils/cache.c b/src/utils/cache.c index 80139d8..318d45d 100644 --- a/src/utils/cache.c +++ b/src/utils/cache.c @@ -1,27 +1,27 @@ /* - * GPAC Multimedia Framework - * - * Authors: Jean Le Feuvre - * Copyright (c) 2005-2005 ENST - * All rights reserved - * - * This file is part of GPAC / common tools 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. - * - */ +* GPAC Multimedia Framework +* +* Authors: Jean Le Feuvre +* Copyright (c) 2005-2005 ENST +* All rights reserved +* +* This file is part of GPAC / common tools 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 #include @@ -44,6 +44,8 @@ static const char * CACHE_SECTION_NAME = "cache"; static const char * CACHE_SECTION_NAME_URL = "url"; +static const char * CACHE_SECTION_NAME_RANGE = "range"; + static const char * CACHE_SECTION_NAME_ETAG = "ETag"; static const char * CACHE_SECTION_NAME_MIME_TYPE = "Content-Type"; @@ -54,283 +56,303 @@ static const char * CACHE_SECTION_NAME_LAST_MODIFIED = "Last-Modified"; enum CacheValid { - NO_VALIDATION = 0, - MUST_REVALIDATE = 1, - IS_HTTPS = 2, - CORRUPTED = 4, - NO_CACHE = 8 + NO_VALIDATION = 0, + MUST_REVALIDATE = 1, + IS_HTTPS = 2, + CORRUPTED = 4, + NO_CACHE = 8 }; struct __CacheReaderStruct { - FILE * readPtr; - s64 readPosition; + FILE * readPtr; + s64 readPosition; }; typedef struct __DownloadedRangeStruc { - u32 start; - u32 end; - const char * filename; + u32 start; + u32 end; + const char * filename; } * DownloadedRange; +//#define ENABLE_WRITE_MX /** - * This opaque structure handles the data from the cache - */ +* This opaque structure handles the data from the cache +*/ struct __DownloadedCacheEntryStruct { - /** - * URL of the cache (never NULL) - */ - char * url; - /** - * Hash of the cache (never NULL) - */ - char * hash; - /** - * Name of the cache filename, (can be NULL) - */ - char * cache_filename; - /** - * Name of the cached properties filename , (can be NULL) - */ - GF_Config * properties; - /** - * Theorical size of cache if any - */ - u32 contentLength; - /** - * Real size of cache - */ - u32 cacheSize; - /** - * GMT timestamp for revalidation - */ - u32 validity; - /** - * The last modification time on the server - */ - char * serverLastModified; - /** - * The last modification time of the cache if any - */ - char * diskLastModified; - /** - * ETag if any - */ - char * serverETag; - /** - * ETag if any - */ - char * diskETag; - /** - * Mime-type (never NULL) - */ - char * mimeType; - /** - * Write pointer for the cache - */ - FILE * writeFilePtr; - /** - * Bytes written during this cache session - */ - u32 written_in_cache; - /** - * Flag indicating whether we have to revalidate - */ - enum CacheValid flags; - - const GF_DownloadSession * write_session; - - GF_Mutex * write_mutex; - - GF_List * sessions; - - Bool deletableFilesOnDelete; - - GF_DownloadManager * dm; + /** + * URL of the cache (never NULL) + */ + char * url; + /** + * Hash of the cache (never NULL) + */ + char * hash; + /** + * Name of the cache filename, (can be NULL) + */ + char * cache_filename; + /** + * Name of the cached properties filename , (can be NULL) + */ + GF_Config * properties; + /** + * Theorical size of cache if any + */ + u32 contentLength; + /** + * Real size of cache + */ + u32 cacheSize; + /** + * GMT timestamp for revalidation + */ + u32 validity; + /** + * The last modification time on the server + */ + char * serverLastModified; + /** + * The last modification time of the cache if any + */ + char * diskLastModified; + /** + * ETag if any + */ + char * serverETag; + /** + * ETag if any + */ + char * diskETag; + /** + * Mime-type (never NULL) + */ + char * mimeType; + /** + * Write pointer for the cache + */ + FILE * writeFilePtr; + /** + * Bytes written during this cache session + */ + u32 written_in_cache; + /** + * Flag indicating whether we have to revalidate + */ + enum CacheValid flags; + + const GF_DownloadSession * write_session; + +#ifdef ENABLE_WRITE_MX + GF_Mutex * write_mutex; +#endif + + GF_List * sessions; + + Bool deletableFilesOnDelete; + + GF_DownloadManager * dm; + + /*start and end range of the cache*/ + u64 range_start, range_end; + }; -Bool enum_cache_files(void *cbck, char *item_name, char *item_path) { - const char * startPattern; - int sz; - assert( cbck ); - assert( item_name ); - assert( item_path); - startPattern = (const char *) cbck; - sz = strlen( startPattern ); - if (!strncmp(startPattern, item_name, sz)) { - if (GF_OK != gf_delete_file(item_path)) - GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[CACHE] : failed to cleanup file %s\n", item_path)); - } - return 0; +Bool delete_cache_files(void *cbck, char *item_name, char *item_path) { + const char * startPattern; + int sz; + assert( cbck ); + assert( item_name ); + assert( item_path); + startPattern = (const char *) cbck; + sz = strlen( startPattern ); + if (!strncmp(startPattern, item_name, sz)) { + if (GF_OK != gf_delete_file(item_path)) + GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[CACHE] : failed to cleanup file %s\n", item_path)); + } + return 0; } static const char * cache_file_prefix = "gpac_cache_"; GF_Err gf_cache_delete_all_cached_files(const char * directory) { - gf_enum_dir_item item = &enum_cache_files; - GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("Deleting cached files in %s...\n", directory)); - return gf_enum_directory( directory, 0, item, (void*)cache_file_prefix, NULL); + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("Deleting cached files in %s...\n", directory)); + return gf_enum_directory( directory, 0, delete_cache_files, (void*)cache_file_prefix, NULL); } void gf_cache_entry_set_delete_files_when_deleted(const DownloadedCacheEntry entry) { - if (entry) - entry->deletableFilesOnDelete = 1; + if (entry) + entry->deletableFilesOnDelete = 1; } Bool gf_cache_entry_is_delete_files_when_deleted(const DownloadedCacheEntry entry) { - if (!entry) - return 0; - return entry->deletableFilesOnDelete; + if (!entry) + return 0; + return entry->deletableFilesOnDelete; } #define CHECK_ENTRY if (!entry) { GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[CACHE] entry is null at " __FILE__ ":%d\n", __LINE__)); return GF_BAD_PARAM; } /* - * Getters functions - */ +* Getters functions +*/ const char * gf_cache_get_etag_on_server ( const DownloadedCacheEntry entry ) { - return entry ? entry->serverETag : NULL; + return entry ? entry->serverETag : NULL; } const char * gf_cache_get_etag_on_disk ( const DownloadedCacheEntry entry ) { - return entry ? entry->serverETag : NULL; + return entry ? entry->serverETag : NULL; } const char * gf_cache_get_mime_type ( const DownloadedCacheEntry entry ) { - return entry ? entry->mimeType : NULL; + return entry ? entry->mimeType : NULL; } GF_Err gf_cache_set_etag_on_server(const DownloadedCacheEntry entry, const char * eTag ) { - if (!entry) - return GF_BAD_PARAM; - if (entry->serverETag) - gf_free(entry->serverETag); - entry->serverETag = eTag ? gf_strdup(eTag) : NULL; - return GF_OK; + if (!entry) + return GF_BAD_PARAM; + if (entry->serverETag) + gf_free(entry->serverETag); + entry->serverETag = eTag ? gf_strdup(eTag) : NULL; + return GF_OK; } GF_Err gf_cache_set_etag_on_disk(const DownloadedCacheEntry entry, const char * eTag ) { - if (!entry) - return GF_BAD_PARAM; - if (entry->diskETag) - gf_free(entry->diskETag); - entry->diskETag = eTag ? gf_strdup(eTag) : NULL; - return GF_OK; + if (!entry) + return GF_BAD_PARAM; + if (entry->diskETag) + gf_free(entry->diskETag); + entry->diskETag = eTag ? gf_strdup(eTag) : NULL; + return GF_OK; } GF_Err gf_cache_set_mime_type(const DownloadedCacheEntry entry, const char * mime_type ) { - if (!entry) - return GF_BAD_PARAM; - if (entry->mimeType) - gf_free(entry->mimeType); - entry->mimeType = mime_type? gf_strdup( mime_type) : NULL; - return GF_OK; + if (!entry) + return GF_BAD_PARAM; + if (entry->mimeType) + gf_free(entry->mimeType); + entry->mimeType = mime_type? gf_strdup( mime_type) : NULL; + return GF_OK; } Bool gf_cache_is_cached_on_disk(const DownloadedCacheEntry entry ) { - if (entry == NULL) - return 0; - return entry->flags & NO_CACHE; + if (entry == NULL) + return 0; + return entry->flags & NO_CACHE; +} + +u64 gf_cache_get_start_range( const DownloadedCacheEntry entry ) +{ + return entry ? entry->range_start : 0; +} + +u64 gf_cache_get_end_range( const DownloadedCacheEntry entry ) +{ + return entry ? entry->range_end : 0; } const char * gf_cache_get_url ( const DownloadedCacheEntry entry ) { - return entry ? entry->url : NULL; + return entry ? entry->url : NULL; } const char * gf_cache_get_hash ( const DownloadedCacheEntry entry ) { - return entry ? entry->hash : NULL; + return entry ? entry->hash : NULL; } const char * gf_cache_get_last_modified_on_server ( const DownloadedCacheEntry entry ) { - return entry ? entry->serverLastModified : NULL; + return entry ? entry->serverLastModified : NULL; } const char * gf_cache_get_last_modified_on_disk ( const DownloadedCacheEntry entry ) { - return entry ? entry->diskLastModified : NULL; + return entry ? entry->diskLastModified : NULL; } GF_Err gf_cache_set_last_modified_on_server ( const DownloadedCacheEntry entry, const char * newLastModified ) { - if (!entry) - return GF_BAD_PARAM; - if (entry->serverLastModified) - gf_free(entry->serverLastModified); - entry->serverLastModified = newLastModified ? gf_strdup(newLastModified) : NULL; - return GF_OK; + if (!entry) + return GF_BAD_PARAM; + if (entry->serverLastModified) + gf_free(entry->serverLastModified); + entry->serverLastModified = newLastModified ? gf_strdup(newLastModified) : NULL; + return GF_OK; } GF_Err gf_cache_set_last_modified_on_disk ( const DownloadedCacheEntry entry, const char * newLastModified ) { - if (!entry) - return GF_BAD_PARAM; - if (entry->diskLastModified) - gf_free(entry->diskLastModified); - entry->diskLastModified = newLastModified ? gf_strdup(newLastModified) : NULL; - return GF_OK; + if (!entry) + return GF_BAD_PARAM; + if (entry->diskLastModified) + gf_free(entry->diskLastModified); + entry->diskLastModified = newLastModified ? gf_strdup(newLastModified) : NULL; + return GF_OK; } #define _CACHE_TMP_SIZE 4096 GF_Err gf_cache_flush_disk_cache ( const DownloadedCacheEntry entry ) { - CHECK_ENTRY; - if ( !entry->properties) - return GF_OK; - GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[CACHE] gf_cache_flush_disk_cache:%d for entry=%p\n", __LINE__, entry)); - gf_cfg_set_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_URL, entry->url); - if (entry->mimeType) - gf_cfg_set_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_MIME_TYPE, entry->mimeType); - if (entry->diskETag) - gf_cfg_set_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_ETAG, entry->diskETag); - if (entry->diskLastModified) - gf_cfg_set_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_LAST_MODIFIED, entry->diskLastModified); - { - char buff[16]; - snprintf(buff, 16, "%d", entry->contentLength); - gf_cfg_set_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_CONTENT_SIZE, buff); - } - return gf_cfg_save ( entry->properties ); + char buff[100]; + CHECK_ENTRY; + if ( !entry->properties) + return GF_OK; + GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[CACHE] gf_cache_flush_disk_cache:%d for entry=%p\n", __LINE__, entry)); + gf_cfg_set_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_URL, entry->url); + + sprintf(buff, LLD"-"LLD, entry->range_start, entry->range_end); + gf_cfg_set_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_RANGE, buff); + + if (entry->mimeType) + gf_cfg_set_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_MIME_TYPE, entry->mimeType); + if (entry->diskETag) + gf_cfg_set_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_ETAG, entry->diskETag); + if (entry->diskLastModified) + gf_cfg_set_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_LAST_MODIFIED, entry->diskLastModified); + { + snprintf(buff, 16, "%d", entry->contentLength); + gf_cfg_set_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_CONTENT_SIZE, buff); + } + return gf_cfg_save ( entry->properties ); } u32 gf_cache_get_cache_filesize ( const DownloadedCacheEntry entry ) { - return entry ? entry->cacheSize : -1; + return entry ? entry->cacheSize : -1; } const char * gf_cache_get_cache_filename( const DownloadedCacheEntry entry ) { - return entry ? entry->cache_filename : NULL; + return entry ? entry->cache_filename : NULL; } GF_Err appendHttpCacheHeaders(const DownloadedCacheEntry entry, char * httpRequest) { - if (!entry || !httpRequest) - return GF_BAD_PARAM; - if (entry->flags) - return GF_OK; - if (gf_cache_check_if_cache_file_is_corrupted(entry)) - return GF_OK; - /* OK, this is potentially bad if httpRequest is not big enough */ - if (entry->diskETag) { - strcat(httpRequest, "If-None-Match: "); - strcat(httpRequest, entry->diskETag); - strcat(httpRequest, "\r\n"); - } - if (entry->diskLastModified) { - strcat(httpRequest, "If-Modified-Since: "); - strcat(httpRequest, entry->diskLastModified); - strcat(httpRequest, "\r\n"); - } - return GF_OK; + if (!entry || !httpRequest) + return GF_BAD_PARAM; + if (entry->flags) + return GF_OK; + if (gf_cache_check_if_cache_file_is_corrupted(entry)) + return GF_OK; + /* OK, this is potentially bad if httpRequest is not big enough */ + if (entry->diskETag) { + strcat(httpRequest, "If-None-Match: "); + strcat(httpRequest, entry->diskETag); + strcat(httpRequest, "\r\n"); + } + if (entry->diskLastModified) { + strcat(httpRequest, "If-Modified-Since: "); + strcat(httpRequest, entry->diskLastModified); + strcat(httpRequest, "\r\n"); + } + return GF_OK; } #define _CACHE_HASH_SIZE 20 @@ -341,266 +363,284 @@ static const char * default_cache_file_suffix = ".dat"; static const char * cache_file_info_suffix = ".txt"; -DownloadedCacheEntry gf_cache_create_entry ( GF_DownloadManager * dm, const char * cache_directory, const char * url ) +DownloadedCacheEntry gf_cache_create_entry ( GF_DownloadManager * dm, const char * cache_directory, const char * url , u64 start_range, u64 end_range) { - char tmp[_CACHE_TMP_SIZE]; - u8 hash[_CACHE_HASH_SIZE]; - int sz; - char ext[_CACHE_MAX_EXTENSION_SIZE]; - DownloadedCacheEntry entry = NULL; - if ( !dm || !url || !cache_directory) { - GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, - ("[CACHE] gf_cache_create_entry :%d, dm=%p, url=%s cache_directory=%s, aborting.\n", __LINE__, dm, url, cache_directory)); - return entry; - } - sz = strlen ( url ); - if ( sz > _CACHE_TMP_SIZE ) - { - GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, - ("[CACHE] gf_cache_create_entry:%d : ERROR, URL is too long (%d chars), more than %d chars.\n", __LINE__, sz, _CACHE_TMP_SIZE )); - return entry; - } - tmp[0] = '\0'; - /*generate hash of the full url*/ - strcpy ( tmp, url ); - gf_sha1_csum ( tmp, strlen ( tmp ), hash ); - tmp[0] = 0; - { - int i; - for ( i=0; i<20; i++ ) - { - char t[3]; - t[2] = 0; - sprintf ( t, "%02X", hash[i] ); - strcat ( tmp, t ); - } - } - assert ( strlen ( tmp ) == (_CACHE_HASH_SIZE * 2) ); - - entry = gf_malloc ( sizeof ( struct __DownloadedCacheEntryStruct ) ); - if ( !entry ) { - GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("gf_cache_create_entry:%d : OUT of memory !\n", __LINE__)); - return NULL; - } - GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, - ("[CACHE] gf_cache_create_entry:%d, entry=%p\n", __LINE__, entry)); - entry->properties = NULL; - entry->writeFilePtr = NULL; - entry->url = gf_strdup ( url ); - entry->hash = gf_strdup ( tmp ); - entry->mimeType = NULL; - /* Sizeof cache directory + hash + possible extension */ - entry->cache_filename = gf_malloc ( strlen ( cache_directory ) + strlen(cache_file_prefix) + strlen(tmp) + _CACHE_MAX_EXTENSION_SIZE + 1); - - entry->cacheSize = 0; - entry->contentLength = 0; - entry->serverETag = NULL; - entry->diskETag = NULL; - entry->flags = NO_VALIDATION; - entry->validity = 0; - entry->diskLastModified = NULL; - entry->serverLastModified = NULL; - entry->dm = dm; - { - char name[1024]; - snprintf(name, 1024, "CachedEntryWriteMx=%p, url=%s", (void*) entry, url); - entry->write_mutex = gf_mx_new(name); - assert( entry->write_mutex); - } - entry->deletableFilesOnDelete = 0; - entry->write_session = NULL; - entry->sessions = gf_list_new(); - if ( !entry->hash || !entry->url || !entry->cache_filename || !entry->sessions) - { - GF_Err err; - /* Probably out of memory */ - GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[CACHE] gf_cache_create_entry:%d, aborting due to OUT of MEMORY !\n", __LINE__)); - err = gf_cache_delete_entry ( entry ); - assert ( err == GF_OK ); - return NULL; - } - tmp[0] = '\0'; - strcpy ( entry->cache_filename, cache_directory ); - strcat( entry->cache_filename, cache_file_prefix ); - strcat ( entry->cache_filename, entry->hash ); - strcpy ( tmp, url ); - - { - char * parser; - parser = strrchr ( tmp, '?' ); - if ( parser ) - parser[0] = '\0'; - parser = strrchr ( tmp, '#' ); - if ( parser ) - parser[0] = '\0'; - parser = strrchr ( tmp, '.' ); - if ( parser && ( strlen ( parser ) < _CACHE_MAX_EXTENSION_SIZE ) ) - strncpy(ext, parser, _CACHE_MAX_EXTENSION_SIZE); - else - strncpy(ext, default_cache_file_suffix, _CACHE_MAX_EXTENSION_SIZE); - assert (strlen(ext)); - strcat( entry->cache_filename, ext); - } - tmp[0] = '\0'; - strcpy( tmp, cache_file_prefix); - strcat( tmp, entry->hash ); - strcat( tmp , ext); - strcat ( tmp, cache_file_info_suffix ); - entry->properties = gf_cfg_force_new ( cache_directory, tmp ); - if ( !entry->properties ) - { - GF_Err err; - /* OUT of memory ? */ - GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[CACHE] gf_cache_create_entry:%d, aborting due to OUT of MEMORY !\n", __LINE__)); - err = gf_cache_delete_entry ( entry ); - assert ( err == GF_OK ); - return NULL; - } - gf_cache_set_etag_on_disk(entry, gf_cfg_get_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_ETAG)); - gf_cache_set_etag_on_server(entry, gf_cfg_get_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_ETAG)); - gf_cache_set_mime_type(entry, gf_cfg_get_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_MIME_TYPE)); - gf_cache_set_last_modified_on_disk(entry, gf_cfg_get_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_LAST_MODIFIED)); - gf_cache_set_last_modified_on_server(entry, gf_cfg_get_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_LAST_MODIFIED)); - { - const char * keyValue = gf_cfg_get_key ( entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_URL ); - if ( keyValue == NULL || stricmp ( url, keyValue ) ) - entry->flags |= CORRUPTED; - } - gf_cache_check_if_cache_file_is_corrupted(entry); - - return entry; + char tmp[_CACHE_TMP_SIZE]; + u8 hash[_CACHE_HASH_SIZE]; + int sz; + char ext[_CACHE_MAX_EXTENSION_SIZE]; + DownloadedCacheEntry entry = NULL; + if ( !dm || !url || !cache_directory) { + GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, + ("[CACHE] gf_cache_create_entry :%d, dm=%p, url=%s cache_directory=%s, aborting.\n", __LINE__, dm, url, cache_directory)); + return entry; + } + sz = strlen ( url ); + if ( sz > _CACHE_TMP_SIZE ) + { + GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, + ("[CACHE] gf_cache_create_entry:%d : ERROR, URL is too long (%d chars), more than %d chars.\n", __LINE__, sz, _CACHE_TMP_SIZE )); + return entry; + } + tmp[0] = '\0'; + /*generate hash of the full url*/ + if (start_range && end_range) { + sprintf(tmp, "%s_"LLD"-"LLD, url, start_range, end_range ); + } else { + strcpy ( tmp, url ); + } + gf_sha1_csum ( tmp, strlen ( tmp ), hash ); + tmp[0] = 0; + { + int i; + for ( i=0; i<20; i++ ) + { + char t[3]; + t[2] = 0; + sprintf ( t, "%02X", hash[i] ); + strcat ( tmp, t ); + } + } + assert ( strlen ( tmp ) == (_CACHE_HASH_SIZE * 2) ); + + GF_SAFEALLOC(entry, struct __DownloadedCacheEntryStruct); + + if ( !entry ) { + GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("gf_cache_create_entry:%d : OUT of memory !\n", __LINE__)); + return NULL; + } + GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, + ("[CACHE] gf_cache_create_entry:%d, entry=%p\n", __LINE__, entry)); + + entry->url = gf_strdup ( url ); + entry->hash = gf_strdup ( tmp ); + + /* Sizeof cache directory + hash + possible extension */ + entry->cache_filename = gf_malloc ( strlen ( cache_directory ) + strlen(cache_file_prefix) + strlen(tmp) + _CACHE_MAX_EXTENSION_SIZE + 1); + + entry->cacheSize = 0; + entry->contentLength = 0; + entry->serverETag = NULL; + entry->diskETag = NULL; + entry->flags = NO_VALIDATION; + entry->validity = 0; + entry->diskLastModified = NULL; + entry->serverLastModified = NULL; + entry->dm = dm; + entry->range_start = start_range; + entry->range_end = end_range; + + { + char name[1024]; + snprintf(name, 1024, "CachedEntryWriteMx=%p, url=%s", (void*) entry, url); +#ifdef ENABLE_WRITE_MX + entry->write_mutex = gf_mx_new(name); + assert( entry->write_mutex); +#endif + } + entry->deletableFilesOnDelete = 0; + entry->write_session = NULL; + entry->sessions = gf_list_new(); + if ( !entry->hash || !entry->url || !entry->cache_filename || !entry->sessions) + { + GF_Err err; + /* Probably out of memory */ + GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[CACHE] gf_cache_create_entry:%d, aborting due to OUT of MEMORY !\n", __LINE__)); + err = gf_cache_delete_entry ( entry ); + assert ( err == GF_OK ); + return NULL; + } + tmp[0] = '\0'; + strcpy ( entry->cache_filename, cache_directory ); + strcat( entry->cache_filename, cache_file_prefix ); + strcat ( entry->cache_filename, entry->hash ); + strcpy ( tmp, url ); + + { + char * parser; + parser = strrchr ( tmp, '?' ); + if ( parser ) + parser[0] = '\0'; + parser = strrchr ( tmp, '#' ); + if ( parser ) + parser[0] = '\0'; + parser = strrchr ( tmp, '.' ); + if ( parser && ( strlen ( parser ) < _CACHE_MAX_EXTENSION_SIZE ) ) + strncpy(ext, parser, _CACHE_MAX_EXTENSION_SIZE); + else + strncpy(ext, default_cache_file_suffix, _CACHE_MAX_EXTENSION_SIZE); + assert (strlen(ext)); + strcat( entry->cache_filename, ext); + } + tmp[0] = '\0'; + strcpy( tmp, cache_file_prefix); + strcat( tmp, entry->hash ); + strcat( tmp , ext); + strcat ( tmp, cache_file_info_suffix ); + entry->properties = gf_cfg_force_new ( cache_directory, tmp ); + if ( !entry->properties ) + { + GF_Err err; + /* OUT of memory ? */ + GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[CACHE] gf_cache_create_entry:%d, aborting due to OUT of MEMORY !\n", __LINE__)); + err = gf_cache_delete_entry ( entry ); + assert ( err == GF_OK ); + return NULL; + } + gf_cache_set_etag_on_disk(entry, gf_cfg_get_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_ETAG)); + gf_cache_set_etag_on_server(entry, gf_cfg_get_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_ETAG)); + gf_cache_set_mime_type(entry, gf_cfg_get_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_MIME_TYPE)); + gf_cache_set_last_modified_on_disk(entry, gf_cfg_get_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_LAST_MODIFIED)); + gf_cache_set_last_modified_on_server(entry, gf_cfg_get_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_LAST_MODIFIED)); + { + const char * keyValue = gf_cfg_get_key ( entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_URL ); + if ( keyValue == NULL || stricmp ( url, keyValue ) ) + entry->flags |= CORRUPTED; + + keyValue = gf_cfg_get_key(entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_RANGE); + if (keyValue) sscanf(keyValue, LLD"-"LLD, &entry->range_start, &entry->range_end); + } + gf_cache_check_if_cache_file_is_corrupted(entry); + + return entry; } GF_Err gf_cache_set_content_length( const DownloadedCacheEntry entry, u32 length ) { - CHECK_ENTRY; - entry->contentLength = length; - return GF_OK; + CHECK_ENTRY; + entry->contentLength = length; + return GF_OK; } u32 gf_cache_get_content_length( const DownloadedCacheEntry entry) { - return entry ? entry->contentLength : 0; + return entry ? entry->contentLength : 0; } GF_Err gf_cache_close_write_cache( const DownloadedCacheEntry entry, const GF_DownloadSession * sess, Bool success ) { - GF_Err e = GF_OK; - CHECK_ENTRY; - if (!sess || !entry->write_session || entry->write_session != sess) - return GF_OK; - assert( sess == entry->write_session ); - if (entry->writeFilePtr) { - GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, - ("[CACHE] Closing file %s, %d bytes written.\n", entry->cache_filename, entry->written_in_cache)); - if (fflush( entry->writeFilePtr ) || fclose( entry->writeFilePtr )) - e = GF_IO_ERR; - e|= gf_cache_flush_disk_cache(entry); - if (e == GF_OK && success) { - e|= gf_cache_set_last_modified_on_disk( entry, gf_cache_get_last_modified_on_server(entry)); - e|= gf_cache_set_etag_on_disk( entry, gf_cache_get_etag_on_server(entry)); - } - e|= gf_cache_flush_disk_cache(entry); + GF_Err e = GF_OK; + CHECK_ENTRY; + if (!sess || !entry->write_session || entry->write_session != sess) + return GF_OK; + assert( sess == entry->write_session ); + if (entry->writeFilePtr) { + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, + ("[CACHE] Closing file %s, %d bytes written.\n", entry->cache_filename, entry->written_in_cache)); + if (fflush( entry->writeFilePtr ) || fclose( entry->writeFilePtr )) + e = GF_IO_ERR; + e|= gf_cache_flush_disk_cache(entry); + if (e == GF_OK && success) { + e|= gf_cache_set_last_modified_on_disk( entry, gf_cache_get_last_modified_on_server(entry)); + e|= gf_cache_set_etag_on_disk( entry, gf_cache_get_etag_on_server(entry)); + } + e|= gf_cache_flush_disk_cache(entry); #if defined(_BSD_SOURCE) || _XOPEN_SOURCE >= 500 - /* On UNIX, be sure to flush all the data */ - sync(); + /* On UNIX, be sure to flush all the data */ + sync(); #endif - entry->writeFilePtr = NULL; - if (GF_OK != e) { - GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[CACHE] Failed to fully write file on cache, e=%d\n", e)); - } - } - entry->write_session = NULL; - gf_mx_v(entry->write_mutex); - return e; + entry->writeFilePtr = NULL; + if (GF_OK != e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[CACHE] Failed to fully write file on cache, e=%d\n", e)); + } + } + entry->write_session = NULL; +#ifdef ENABLE_WRITE_MX + gf_mx_v(entry->write_mutex); +#endif + return e; } GF_Err gf_cache_open_write_cache( const DownloadedCacheEntry entry, const GF_DownloadSession * sess ) { - CHECK_ENTRY; - if (!sess) - return GF_BAD_PARAM; - GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK,("[CACHE] Locking write mutex %p for entry=%s\n", (void*) (entry->write_mutex), entry->url) ); - gf_mx_p(entry->write_mutex); - entry->write_session = sess; - assert( ! entry->writeFilePtr); - GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, - ("[CACHE] Opening cache file %s for write (%s)...", entry->cache_filename, entry->url)); - entry->writeFilePtr = gf_f64_open(entry->cache_filename, "wb"); - if (!entry->writeFilePtr) { - GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, - ("[CACHE] Error while opening cache file %s for writting.", entry->cache_filename)); - entry->write_session = NULL; - gf_mx_v(entry->write_mutex); - return GF_IO_ERR; - } - entry->written_in_cache = 0; - return GF_OK; + CHECK_ENTRY; + if (!sess) + return GF_BAD_PARAM; +#ifdef ENABLE_WRITE_MX + GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK,("[CACHE] Locking write mutex %p for entry=%s\n", (void*) (entry->write_mutex), entry->url) ); + gf_mx_p(entry->write_mutex); +#endif + entry->write_session = sess; + assert( ! entry->writeFilePtr); + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, + ("[CACHE] Opening cache file %s for write (%s)...", entry->cache_filename, entry->url)); + entry->writeFilePtr = gf_f64_open(entry->cache_filename, "wb"); + if (!entry->writeFilePtr) { + GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, + ("[CACHE] Error while opening cache file %s for writting.", entry->cache_filename)); + entry->write_session = NULL; +#ifdef ENABLE_WRITE_MX + gf_mx_v(entry->write_mutex); +#endif + return GF_IO_ERR; + } + entry->written_in_cache = 0; + return GF_OK; } GF_Err gf_cache_write_to_cache( const DownloadedCacheEntry entry, const GF_DownloadSession * sess, const char * data, const u32 size) { - u32 readen; - GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[CACHE] gf_cache_write_to_cache:%d\n", __LINE__)); - CHECK_ENTRY; - if (!data || !entry->writeFilePtr || sess != entry->write_session) { - GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("Incorrect parameter : data=%p, entry->writeFilePtr=%p at "__FILE__, data, entry->writeFilePtr)); - return GF_BAD_PARAM; - } - readen = fwrite(data, sizeof(char), size, entry->writeFilePtr); - if (readen > 0) - entry->written_in_cache+= readen; - if (readen != size) { - /* Something bad happened */ - GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, - ("[CACHE] Error while writting %d bytes of data to cache : has written only %d bytes.", size, readen)); - gf_cache_close_write_cache(entry, sess, 0); - gf_delete_file(entry->cache_filename); - return GF_IO_ERR; - } - if (fflush(entry->writeFilePtr)) { - GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, - ("[CACHE] Error while flushing data bytes to cache file : %s.", entry->cache_filename)); - gf_cache_close_write_cache(entry, sess, 0); - gf_delete_file(entry->cache_filename); - return GF_IO_ERR; - } - return GF_OK; + u32 readen; + GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[CACHE] gf_cache_write_to_cache:%d\n", __LINE__)); + CHECK_ENTRY; + if (!data || !entry->writeFilePtr || sess != entry->write_session) { + GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("Incorrect parameter : data=%p, entry->writeFilePtr=%p at "__FILE__, data, entry->writeFilePtr)); + return GF_BAD_PARAM; + } + readen = fwrite(data, sizeof(char), size, entry->writeFilePtr); + if (readen > 0) + entry->written_in_cache+= readen; + if (readen != size) { + /* Something bad happened */ + GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, + ("[CACHE] Error while writting %d bytes of data to cache : has written only %d bytes.", size, readen)); + gf_cache_close_write_cache(entry, sess, 0); + gf_delete_file(entry->cache_filename); + return GF_IO_ERR; + } + if (fflush(entry->writeFilePtr)) { + GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, + ("[CACHE] Error while flushing data bytes to cache file : %s.", entry->cache_filename)); + gf_cache_close_write_cache(entry, sess, 0); + gf_delete_file(entry->cache_filename); + return GF_IO_ERR; + } + return GF_OK; } GF_CacheReader gf_cache_reader_new(const DownloadedCacheEntry entry) { - GF_CacheReader reader; - if (entry == NULL) - return NULL; - reader = gf_malloc(sizeof(struct __CacheReaderStruct)); - if (reader == NULL) - return NULL; - reader->readPtr = gf_f64_open( entry->cache_filename, "rb" ); - reader->readPosition = 0; - if (!reader->readPtr) { - gf_cache_reader_del(reader); - return NULL; - } - return reader; + GF_CacheReader reader; + if (entry == NULL) + return NULL; + reader = gf_malloc(sizeof(struct __CacheReaderStruct)); + if (reader == NULL) + return NULL; + reader->readPtr = gf_f64_open( entry->cache_filename, "rb" ); + reader->readPosition = 0; + if (!reader->readPtr) { + gf_cache_reader_del(reader); + return NULL; + } + return reader; } GF_Err gf_cache_reader_del( GF_CacheReader handle ) { - if (!handle) - return GF_BAD_PARAM; - if (handle->readPtr) - fclose(handle->readPtr); - handle->readPtr = NULL; - handle->readPosition = -1; - return GF_OK; + if (!handle) + return GF_BAD_PARAM; + if (handle->readPtr) + fclose(handle->readPtr); + handle->readPtr = NULL; + handle->readPosition = -1; + return GF_OK; } s64 gf_cache_reader_seek_at( GF_CacheReader reader, u64 seekPosition) { - if (!reader) - return -1; - reader->readPosition = gf_f64_seek(reader->readPtr, seekPosition, SEEK_SET); - return reader->readPosition; + if (!reader) + return -1; + reader->readPosition = gf_f64_seek(reader->readPtr, seekPosition, SEEK_SET); + return reader->readPosition; } s64 gf_cache_reader_get_position( const GF_CacheReader reader) { - if (!reader) - return -1; - return reader->readPosition; + if (!reader) + return -1; + return reader->readPosition; } s64 gf_cache_reader_get_currentSize( GF_CacheReader reader ); @@ -608,144 +648,148 @@ s64 gf_cache_reader_get_currentSize( GF_CacheReader reader ); s64 gf_cache_reader_full_size( GF_CacheReader reader ); s32 gf_cache_reader_read( GF_CacheReader reader, char * buff, s32 length) { - s32 readen; - if (!reader || !buff || length < 0 || !reader->readPtr) - return -1; - readen = fread(buff, sizeof(char), length, reader->readPtr); - if (readen > 0) - reader->readPosition+= readen; - return readen; + s32 readen; + if (!reader || !buff || length < 0 || !reader->readPtr) + return -1; + readen = fread(buff, sizeof(char), length, reader->readPtr); + if (readen > 0) + reader->readPosition+= readen; + return readen; } GF_Err gf_cache_delete_entry ( const DownloadedCacheEntry entry ) { - if ( !entry ) - return GF_OK; - GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[CACHE] gf_cache_delete_entry:%d, entry=%p\n", __LINE__, entry)); - if (entry->writeFilePtr) { - /** Cache should have been close before, abornormal situation */ - GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[CACHE] gf_cache_delete_entry:%d, entry=%p, cache has not been closed properly\n", __LINE__, entry)); - fclose(entry->writeFilePtr); - } - if (entry->write_mutex) { - gf_mx_del(entry->write_mutex); - } - if (entry->deletableFilesOnDelete) { - GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[CACHE] url %s cleanup, deleting %s...\n", entry->url, entry->cache_filename)); - if (GF_OK != gf_delete_file(entry->cache_filename)) - GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[CACHE] gf_cache_delete_entry:%d, failed to delete file %s\n", __LINE__, entry->cache_filename)); - } - entry->write_mutex = NULL; - entry->write_session = NULL; - entry->writeFilePtr = NULL; - if (entry->serverETag) - gf_free(entry->serverETag); - entry->serverETag = NULL; - - if (entry->diskETag) - gf_free(entry->diskETag); - entry->diskETag = NULL; - - if (entry->serverLastModified) - gf_free(entry->serverLastModified); - entry->serverLastModified = NULL; - - if (entry->diskLastModified) - gf_free(entry->diskLastModified); - entry->diskLastModified = NULL; - - if ( entry->hash ) - { - gf_free ( entry->hash ); - entry->hash = NULL; - } - if ( entry->url ) - { - gf_free ( entry->url ); - entry->url = NULL; - } - if ( entry->mimeType ) - { - gf_free ( entry->mimeType ); - entry->mimeType = NULL; - } - if ( entry->cache_filename ) - { - gf_free ( entry->cache_filename ); - entry->cache_filename = NULL; - } - if ( entry->properties ) - { - char * propfile; - if (entry->deletableFilesOnDelete) - propfile = gf_cfg_get_filename(entry->properties); - else - propfile = NULL; - gf_cfg_del ( entry->properties ); - entry->properties = NULL; - if (propfile) { - if (GF_OK != gf_delete_file( propfile )) - GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[CACHE] gf_cache_delete_entry:%d, failed to delete file %s\n", __LINE__, propfile)); - gf_free ( propfile ); - } - } - entry->dm = NULL; - if (entry->sessions) { - assert( gf_list_count(entry->sessions) == 0); - gf_list_del(entry->sessions); - entry->sessions = NULL; - } - gf_free (entry); - return GF_OK; + if ( !entry ) + return GF_OK; + GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[CACHE] gf_cache_delete_entry:%d, entry=%p\n", __LINE__, entry)); + if (entry->writeFilePtr) { + /** Cache should have been close before, abornormal situation */ + GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[CACHE] gf_cache_delete_entry:%d, entry=%p, cache has not been closed properly\n", __LINE__, entry)); + fclose(entry->writeFilePtr); + } +#ifdef ENABLE_WRITE_MX + if (entry->write_mutex) { + gf_mx_del(entry->write_mutex); + } +#endif + if (entry->deletableFilesOnDelete) { + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[CACHE] url %s cleanup, deleting %s...\n", entry->url, entry->cache_filename)); + if (GF_OK != gf_delete_file(entry->cache_filename)) + GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[CACHE] gf_cache_delete_entry:%d, failed to delete file %s\n", __LINE__, entry->cache_filename)); + } +#ifdef ENABLE_WRITE_MX + entry->write_mutex = NULL; +#endif + entry->write_session = NULL; + entry->writeFilePtr = NULL; + if (entry->serverETag) + gf_free(entry->serverETag); + entry->serverETag = NULL; + + if (entry->diskETag) + gf_free(entry->diskETag); + entry->diskETag = NULL; + + if (entry->serverLastModified) + gf_free(entry->serverLastModified); + entry->serverLastModified = NULL; + + if (entry->diskLastModified) + gf_free(entry->diskLastModified); + entry->diskLastModified = NULL; + + if ( entry->hash ) + { + gf_free ( entry->hash ); + entry->hash = NULL; + } + if ( entry->url ) + { + gf_free ( entry->url ); + entry->url = NULL; + } + if ( entry->mimeType ) + { + gf_free ( entry->mimeType ); + entry->mimeType = NULL; + } + if ( entry->cache_filename ) + { + gf_free ( entry->cache_filename ); + entry->cache_filename = NULL; + } + if ( entry->properties ) + { + char * propfile; + if (entry->deletableFilesOnDelete) + propfile = gf_cfg_get_filename(entry->properties); + else + propfile = NULL; + gf_cfg_del ( entry->properties ); + entry->properties = NULL; + if (propfile) { + if (GF_OK != gf_delete_file( propfile )) + GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[CACHE] gf_cache_delete_entry:%d, failed to delete file %s\n", __LINE__, propfile)); + gf_free ( propfile ); + } + } + entry->dm = NULL; + if (entry->sessions) { + assert( gf_list_count(entry->sessions) == 0); + gf_list_del(entry->sessions); + entry->sessions = NULL; + } + gf_free (entry); + return GF_OK; } Bool gf_cache_check_if_cache_file_is_corrupted(const DownloadedCacheEntry entry) { - FILE *the_cache = gf_f64_open ( entry->cache_filename, "rb" ); - if ( the_cache ) - { - char * endPtr; - const char * keyValue = gf_cfg_get_key ( entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_CONTENT_SIZE ); - - gf_f64_seek ( the_cache, 0, SEEK_END ); - entry->cacheSize = ( u32 ) gf_f64_tell ( the_cache ); - fclose ( the_cache ); - if (keyValue) { - entry->contentLength = strtoul( keyValue, &endPtr, 10); - if (*endPtr!='\0' || entry->contentLength != entry->cacheSize) { - entry->flags |= CORRUPTED; - GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[CACHE] gf_cache_create_entry:%d, cached file and cache info size mismatch.\n", __LINE__)); - } - } else - entry->flags |= CORRUPTED; - - } else { - entry->flags |= CORRUPTED; - } - if (entry->flags & CORRUPTED) - GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[CACHE] gf_cache_create_entry:%d, CACHE is corrupted !\n", __LINE__)); - - return entry->flags & CORRUPTED; + FILE *the_cache = gf_f64_open ( entry->cache_filename, "rb" ); + if ( the_cache ) + { + char * endPtr; + const char * keyValue = gf_cfg_get_key ( entry->properties, CACHE_SECTION_NAME, CACHE_SECTION_NAME_CONTENT_SIZE ); + + gf_f64_seek ( the_cache, 0, SEEK_END ); + entry->cacheSize = ( u32 ) gf_f64_tell ( the_cache ); + fclose ( the_cache ); + if (keyValue) { + entry->contentLength = strtoul( keyValue, &endPtr, 10); + if (*endPtr!='\0' || entry->contentLength != entry->cacheSize) { + entry->flags |= CORRUPTED; + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[CACHE] gf_cache_create_entry:%d, cached file and cache info size mismatch.\n", __LINE__)); + } + } else + entry->flags |= CORRUPTED; + + } else { + entry->flags |= CORRUPTED; + } + if (entry->flags & CORRUPTED) + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[CACHE] gf_cache_create_entry:%d, CACHE is corrupted !\n", __LINE__)); + + return entry->flags & CORRUPTED; } s32 gf_cache_remove_session_from_cache_entry(DownloadedCacheEntry entry, GF_DownloadSession * sess) { - u32 i; - s32 count; - if (!entry || !sess || !entry->sessions) - return -1; - count = gf_list_count(entry->sessions); - for (i = 0 ; i < (u32)count; i++) { - GF_DownloadSession * s = gf_list_get(entry->sessions, i); - if (s == sess) { - gf_list_rem(entry->sessions, i); - count --; + u32 i; + s32 count; + if (!entry || !sess || !entry->sessions) + return -1; + count = gf_list_count(entry->sessions); + for (i = 0 ; i < (u32)count; i++) { + GF_DownloadSession * s = gf_list_get(entry->sessions, i); + if (s == sess) { + gf_list_rem(entry->sessions, i); + count --; break; - } - } - if (entry->write_session == sess) { + } + } + if (entry->write_session == sess) { /* OK, this is not optimal to close it since we are in a mutex, - * but we don't want to risk to have another session opening - * a not fully closed cache entry */ + * but we don't want to risk to have another session opening + * a not fully closed cache entry */ if (entry->writeFilePtr){ if (fclose(entry->writeFilePtr)) { GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[CACHE] gf_cache_remove_session_from_cache_entry:%d, Failed to properly fclose cache file '%s' of url '%s', cache may be corrupted !\n", __LINE__, entry->cache_filename, entry->url)); @@ -753,31 +797,39 @@ s32 gf_cache_remove_session_from_cache_entry(DownloadedCacheEntry entry, GF_Down } entry->writeFilePtr = NULL; entry->write_session = NULL; - gf_mx_v(entry->write_mutex); +#ifdef ENABLE_WRITE_MX + gf_mx_v(entry->write_mutex); +#endif } - return count; + return count; } u32 gf_cache_get_sessions_count_for_cache_entry(const DownloadedCacheEntry entry) { - if (!entry) - return 0; - return gf_list_count(entry->sessions); + if (!entry) + return 0; + return gf_list_count(entry->sessions); } s32 gf_cache_add_session_to_cache_entry(DownloadedCacheEntry entry, GF_DownloadSession * sess) { - u32 i; - s32 count; - if (!entry || !sess || !entry->sessions) - return -1; - count = gf_list_count(entry->sessions); - for (i = 0 ; i < (u32)count; i++) { - GF_DownloadSession * s = gf_list_get(entry->sessions, i); - if (s == sess) { - return count; - } - } - gf_list_add(entry->sessions, sess); - return count + 1; + u32 i; + s32 count; + if (!entry || !sess || !entry->sessions) + return -1; + count = gf_list_count(entry->sessions); + for (i = 0 ; i < (u32)count; i++) { + GF_DownloadSession * s = gf_list_get(entry->sessions, i); + if (s == sess) { + return count; + } + } + gf_list_add(entry->sessions, sess); + return count + 1; +} + +FILE *gf_cache_get_file_pointer(const DownloadedCacheEntry entry) +{ + if (entry) return entry->writeFilePtr; + return NULL; } diff --git a/src/utils/color.c b/src/utils/color.c index 69a53e3..9162063 100644 --- a/src/utils/color.c +++ b/src/utils/color.c @@ -71,7 +71,7 @@ static void yuv2rgb_init(void) } } -static void gf_yuv_load_lines(unsigned char *dst, s32 dststride, unsigned char *y_src, unsigned char *u_src, unsigned char * v_src, s32 y_stride, s32 uv_stride, s32 width) +static void gf_yuv_load_lines_planar(unsigned char *dst, s32 dststride, unsigned char *y_src, unsigned char *u_src, unsigned char * v_src, s32 y_stride, s32 uv_stride, s32 width) { u32 hw, x; unsigned char *dst2 = (unsigned char *) dst + dststride; @@ -122,6 +122,40 @@ static void gf_yuv_load_lines(unsigned char *dst, s32 dststride, unsigned char * } } +static void gf_yuv_load_lines_packed(unsigned char *dst, s32 dststride, unsigned char *y_src, unsigned char *u_src, unsigned char * v_src, s32 width) +{ + u32 hw, x; + + hw = width / 2; + for (x = 0; x < hw; x++) { + s32 u, v; + s32 b_u, g_uv, r_v, rgb_y; + + u = *u_src; + v = *v_src; + + b_u = B_U[u]; + g_uv = G_U[u] + G_V[v]; + r_v = R_V[v]; + + rgb_y = RGB_Y[*y_src]; + dst[0] = col_clip( (rgb_y + r_v) >> SCALEBITS_OUT); + dst[1] = col_clip( (rgb_y - g_uv) >> SCALEBITS_OUT); + dst[2] = col_clip( (rgb_y + b_u) >> SCALEBITS_OUT); + dst[3] = 0xFF; + + rgb_y = RGB_Y[*(y_src+2)]; + dst[4] = col_clip( (rgb_y + r_v) >> SCALEBITS_OUT); + dst[5] = col_clip( (rgb_y - g_uv) >> SCALEBITS_OUT); + dst[6] = col_clip( (rgb_y + b_u) >> SCALEBITS_OUT); + dst[7] = 0xFF; + + dst += 8; + y_src += 4; + u_src += 4; + v_src += 4; + } +} static void gf_yuva_load_lines(unsigned char *dst, s32 dststride, unsigned char *y_src, unsigned char *u_src, unsigned char *v_src, unsigned char *a_src, @@ -713,7 +747,7 @@ static void load_line_yv12(char *src_bits, u32 x_offset, u32 y_offset, u32 y_pit pY += x_offset + y_offset*y_pitch; pU += x_offset/2 + y_offset*y_pitch/4; pV += x_offset/2 + y_offset*y_pitch/4; - gf_yuv_load_lines((unsigned char*)dst_bits, 4*width, pY, pU, pV, y_pitch, y_pitch/2, width); + gf_yuv_load_lines_planar((unsigned char*)dst_bits, 4*width, pY, pU, pV, y_pitch, y_pitch/2, width); } static void load_line_yuva(char *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u32 height, u8 *dst_bits) @@ -731,6 +765,16 @@ static void load_line_yuva(char *src_bits, u32 x_offset, u32 y_offset, u32 y_pit gf_yuva_load_lines(dst_bits, 4*width, pY, pU, pV, pA, y_pitch, y_pitch/2, width); } +static void load_line_yuyv(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u8 *dst_bits) +{ + u8 *pY, *pU, *pV; + pY = (u8 *)src_bits + x_offset + y_offset*y_pitch; + pU = (u8 *)pY + 1; + pV = (u8 *)pY + 3; + gf_yuv_load_lines_packed((unsigned char*)dst_bits, 4*width, pY, pU, pV, width); +} + + static void gf_cmx_apply_argb(GF_ColorMatrix *_this, u8 *a_, u8 *r_, u8 *g_, u8 *b_); GF_EXPORT @@ -739,7 +783,7 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds u8 *tmp, *rows; u8 ka, kr, kg, kb, kl, kh; s32 src_row; - u32 i, yuv_type = 0; + u32 i, yuv_planar_type = 0; Bool no_memcpy; Bool yuv_init = 0; Bool has_alpha = (alpha!=0xFF) ? 1 : 0; @@ -793,13 +837,18 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds case GF_PIXEL_IYUV: case GF_PIXEL_I420: yuv2rgb_init(); - yuv_type = 1; + yuv_planar_type = 1; break; case GF_PIXEL_YUVA: has_alpha = 1; case GF_PIXEL_YUVD: - yuv_type = 2; + yuv_planar_type = 2; + yuv2rgb_init(); + break; + case GF_PIXEL_YUY2: + yuv_planar_type = 0; yuv2rgb_init(); + load_line = load_line_yuyv; break; default: return GF_NOT_SUPPORTED; @@ -855,9 +904,9 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds dst_w = dst_wnd ? dst_wnd->w : dst->width; dst_h = dst_wnd ? dst_wnd->h : dst->height; - if (yuv_type && (src_w%2)) src_w++; + if (yuv_planar_type && (src_w%2)) src_w++; - tmp = (u8 *) gf_malloc(sizeof(u8) * src_w * (yuv_type ? 8 : 4) ); + tmp = (u8 *) gf_malloc(sizeof(u8) * src_w * (yuv_planar_type ? 8 : 4) ); rows = tmp; src_bits = (u8 *) src->video_buffer; @@ -903,13 +952,13 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds /*new row, check if conversion is needed*/ if (prev_row != src_row) { u32 the_row = src_row - 1; - if (yuv_type) { + if (yuv_planar_type) { if ( the_row % 2) { if (!yuv_init) { yuv_init = 1; the_row --; if (flip) the_row = src->height-2 - the_row; - if (yuv_type==1) { + if (yuv_planar_type==1) { load_line_yv12(src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp); } else { load_line_yuva(src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp); @@ -919,7 +968,7 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds rows = flip ? tmp : tmp + src_w * 4; } else { if (flip) the_row = src->height-2 - the_row; - if (yuv_type==1) { + if (yuv_planar_type==1) { load_line_yv12(src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp); } else { load_line_yuva(src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp); diff --git a/src/utils/configfile.c b/src/utils/configfile.c index b97b57d..0556fac 100644 --- a/src/utils/configfile.c +++ b/src/utils/configfile.c @@ -42,33 +42,10 @@ typedef struct struct __tag_config { char *fileName; - char *filePath; GF_List *sections; Bool hasChanged; }; -/*! - * \brief Build a full absolute path from a directory and a file_name - * \param dest The destination absolute file name properly allocated - * \param directory The directory file path - * \param file_name The filename - * \return NULL if bad parameters specified, dest otherwise - */ -static const char * gf_build_full_path( char * dest, const char * directory, const char * file_name){ - if (!dest || !file_name) - return NULL; - if (directory) { - if (directory[strlen(directory)-1] == GF_PATH_SEPARATOR) { - strcpy(dest, directory); - strcat(dest, file_name); - } else { - sprintf(dest, "%s%c%s", directory, GF_PATH_SEPARATOR, file_name); - } - } else { - strcpy(dest, file_name); - } - return dest; -} static void DelSection(IniSection *ptr) { @@ -105,25 +82,33 @@ static void gf_cfg_clear(GF_Config * iniFile){ } if (iniFile->fileName) gf_free(iniFile->fileName); - if (iniFile->filePath) - gf_free(iniFile->filePath); memset((void *)iniFile, 0, sizeof(GF_Config)); } /*! * \brief Parses the config file if any and clears the existing structure */ -static GF_Err gf_cfg_parse_config_file(GF_Config * tmp, const char * filePath, const char * file_name){ - IniSection *p; +GF_Err gf_cfg_parse_config_file(GF_Config * tmp, const char * filePath, const char * file_name) +{ + IniSection *p; IniKey *k; FILE *file; char *ret; char *line; u32 line_alloc = MAX_INI_LINE; char fileName[GF_MAX_PATH]; - gf_build_full_path(fileName, filePath, file_name); + gf_cfg_clear(tmp); - tmp->filePath = gf_strdup(filePath); + + if (filePath && ((filePath[strlen(filePath)-1] == '/') || (filePath[strlen(filePath)-1] == '\\')) ) { + strcpy(fileName, filePath); + strcat(fileName, file_name); + } else if (filePath) { + sprintf(fileName, "%s%c%s", filePath, GF_PATH_SEPARATOR, file_name); + } else { + strcpy(fileName, file_name); + } + tmp->fileName = gf_strdup(fileName); tmp->sections = gf_list_new(); file = gf_f64_open(fileName, "rt"); @@ -170,7 +155,6 @@ static GF_Err gf_cfg_parse_config_file(GF_Config * tmp, const char * filePath, c if (!p) { gf_list_del(tmp->sections); gf_free(tmp->fileName); - gf_free(tmp->filePath); gf_free(tmp); fclose(file); gf_free(line); diff --git a/src/utils/downloader.c b/src/utils/downloader.c index 3901459..3b4e063 100644 --- a/src/utils/downloader.c +++ b/src/utils/downloader.c @@ -34,7 +34,6 @@ #include #include - #ifdef GPAC_HAS_SSL #include #include @@ -48,10 +47,15 @@ #define SIZE_IN_STREAM ( 2 << 29 ) -static void gf_dm_connect(GF_DownloadSession *sess); + +#define SESSION_RETRY_COUNT 20 #define GF_DOWNLOAD_AGENT_NAME "GPAC/" GPAC_FULL_VERSION #define GF_DOWNLOAD_BUFFER_SIZE 8192 +#define GF_WAIT_REPLY_SLEEP 20 + + +static void gf_dm_connect(GF_DownloadSession *sess); /*internal flags*/ enum @@ -100,6 +104,7 @@ struct __gf_download_session u16 port; char *orig_url; + char *orig_url_before_redirect; char *remote_path; gf_user_credentials_struct * creds; char cookie[GF_MAX_PATH]; @@ -111,12 +116,11 @@ struct __gf_download_session u32 flags; u32 total_size, bytes_done, start_time, icy_metaint, icy_count, icy_bytes; - u32 bytes_per_sec, window_start, bytes_in_wnd; - u32 limit_data_rate; + u32 bytes_per_sec; /* Range information if needed for the download (cf flag) */ Bool needs_range; - u32 range_start, range_end; + u64 range_start, range_end; /*0: GET 1: HEAD @@ -130,6 +134,7 @@ struct __gf_download_session Bool server_only_understand_get; /* True if cache file must be stored on disk */ Bool use_cache_file; + Bool disable_cache; #ifdef GPAC_HAS_SSL SSL *ssl; @@ -157,6 +162,8 @@ struct __gf_download_manager u32 head_timeout; GF_Config *cfg; GF_List *sessions; + Bool disable_cache; + u32 limit_data_rate; GF_List *skip_proxy_servers; GF_List *credentials; @@ -226,6 +233,14 @@ GF_Err gf_cache_close_write_cache( const DownloadedCacheEntry entry, const GF_Do */ GF_Err gf_cache_open_write_cache( const DownloadedCacheEntry entry, const GF_DownloadSession * sess ); +/** + * \brief Returns write file pointer + * This function returns the current cache file pointer + * \param entry The entry to use + * \return cache file pointer or NULL + */ +FILE *gf_cache_get_file_pointer(const DownloadedCacheEntry entry) ; + /** * Find a User's credentials for a given site */ @@ -367,9 +382,11 @@ static int ssl_init(GF_DownloadManager *dm, u32 mode) case 0: meth = SSLv23_client_method(); break; +#if 0 /*SSL v2 is no longer supported in OpenSSL 1.0*/ case 1: meth = SSLv2_client_method(); break; +#endif case 2: meth = SSLv3_client_method(); break; @@ -437,10 +454,12 @@ DownloadedCacheEntry gf_dm_find_cached_entry_by_url(GF_DownloadSession * sess) { assert(e); url = gf_cache_get_url(e); assert( url ); - if (!strcmp(url, sess->orig_url)) { - gf_mx_v( sess->dm->cache_mx ); - return e; - } + if (strcmp(url, sess->orig_url)) continue; + if (sess->range_start != gf_cache_get_start_range(e)) continue; + if (sess->range_end != gf_cache_get_end_range(e)) continue; + /*OK that's ours*/ + gf_mx_v( sess->dm->cache_mx ); + return e; } gf_mx_v( sess->dm->cache_mx ); return NULL; @@ -452,7 +471,7 @@ DownloadedCacheEntry gf_dm_find_cached_entry_by_url(GF_DownloadSession * sess) { * \param url The full URL * \return The DownloadedCacheEntry */ -DownloadedCacheEntry gf_cache_create_entry( GF_DownloadManager * dm, const char * cache_directory, const char * url); +DownloadedCacheEntry gf_cache_create_entry( GF_DownloadManager * dm, const char * cache_directory, const char * url, u64 start_range, u64 end_range); /*! * Removes a session for a DownloadedCacheEntry @@ -473,7 +492,8 @@ void gf_dm_remove_cache_entry_from_session(GF_DownloadSession * sess) { if (sess->dm /*JLF - not sure what the rationale of this test is, and it prevents cleanup of cache entry which then results to crash when restarting the session (entry->writeFilePtr i snot set back to NULL)*/ - && gf_cache_entry_is_delete_files_when_deleted(sess->cache_entry) + && gf_cache_entry_is_delete_files_when_deleted(sess->cache_entry) + && (0 == gf_cache_get_sessions_count_for_cache_entry(sess->cache_entry))) { u32 i, count; @@ -504,11 +524,11 @@ s32 gf_cache_add_session_to_cache_entry(DownloadedCacheEntry entry, GF_DownloadS void gf_dm_configure_cache(GF_DownloadSession *sess) { DownloadedCacheEntry entry; - GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[Downloader] gf_dm_configure_cache(%p), cached=%s\n", sess, sess->flags&GF_NETIO_SESSION_NOT_CACHED?"no":"yes" )); + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[Downloader] gf_dm_configure_cache(%p), cached=%s\n", sess, sess->flags & GF_NETIO_SESSION_NOT_CACHED ? "no" : "yes" )); gf_dm_remove_cache_entry_from_session(sess); entry = gf_dm_find_cached_entry_by_url(sess); if (!entry) { - entry = gf_cache_create_entry(sess->dm, sess->dm->cache_directory, sess->orig_url); + entry = gf_cache_create_entry(sess->dm, sess->dm->cache_directory, sess->orig_url, sess->range_start, sess->range_end); gf_mx_p( sess->dm->cache_mx ); gf_list_add(sess->dm->cache_entries, entry); gf_mx_v( sess->dm->cache_mx ); @@ -573,22 +593,25 @@ void gf_dm_delete_cached_file_entry_session(const GF_DownloadSession * sess, co } -static void gf_dm_disconnect(GF_DownloadSession *sess) +static void gf_dm_disconnect(GF_DownloadSession *sess, Bool force_close) { GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Downloader] gf_dm_disconnect(%p)\n", sess )); if (sess->mx) gf_mx_p(sess->mx); + + if (force_close || !(sess->flags & GF_NETIO_SESSION_PERSISTENT)) { #ifdef GPAC_HAS_SSL - if (sess->ssl) { - SSL_shutdown(sess->ssl); - SSL_free(sess->ssl); - sess->ssl = NULL; - } + if (sess->ssl) { + SSL_shutdown(sess->ssl); + SSL_free(sess->ssl); + sess->ssl = NULL; + } #endif - if (sess->sock) { - gf_sk_del(sess->sock); - sess->sock = NULL; - } + if (sess->sock) { + gf_sk_del(sess->sock); + sess->sock = NULL; + } + } sess->status = GF_NETIO_DISCONNECTED; if (sess->num_retry) sess->num_retry--; if (sess->mx) @@ -605,7 +628,7 @@ void gf_dm_sess_del(GF_DownloadSession *sess) sess->destroy = 1; return; } - gf_dm_disconnect(sess); + gf_dm_disconnect(sess, 1); /*if threaded wait for thread exit*/ if (sess->th) { @@ -634,6 +657,7 @@ void gf_dm_sess_del(GF_DownloadSession *sess) gf_dm_remove_cache_entry_from_session(sess); sess->cache_entry = NULL; if (sess->orig_url) gf_free(sess->orig_url); + if (sess->orig_url_before_redirect) gf_free(sess->orig_url_before_redirect); if (sess->server_name) gf_free(sess->server_name); sess->server_name = NULL; if (sess->remote_path) gf_free(sess->remote_path); @@ -754,12 +778,19 @@ GF_Err gf_dm_get_url_info(const char * url, GF_URL_Info * info, const char * bas /*relative URL*/ if (!strstr(url, "://")) { u32 i; - info->protocol = "file:/"; - if (baseURL){ + info->protocol = "file://"; + if (baseURL) { urlConcatenateWithBaseURL = gf_url_concatenate(baseURL, url); + /*relative file path*/ + if (!strstr(baseURL, "://")) { + info->canonicalRepresentation = urlConcatenateWithBaseURL; + return GF_OK; + } proto_offset = gf_dm_parse_protocol(urlConcatenateWithBaseURL, info); - } else + } else { proto_offset = -1; + } + if (proto_offset < 0){ tmp = urlConcatenateWithBaseURL; assert( ! info->remotePath ); @@ -841,59 +872,84 @@ GF_Err gf_dm_get_url_info(const char * url, GF_URL_Info * info, const char * bas return GF_OK; } -GF_Err gf_dm_setup_from_url(GF_DownloadSession *sess, const char *url) +GF_Err gf_dm_sess_setup_from_url(GF_DownloadSession *sess, const char *url) { + Bool socket_changed = 0; GF_Err e; GF_URL_Info info; gf_dm_url_info_init(&info); e = gf_dm_get_url_info(url, &info, sess->remote_path); - sess->port = info.port; + if (e) return e; + + if (!sess->sock) socket_changed = 1; + else if (sess->status>GF_NETIO_DISCONNECTED) socket_changed = 1; + + if (sess->port != info.port) { + socket_changed = 1; + sess->port = info.port; + } + if (!strcmp("http://", info.protocol) || !strcmp("https://", info.protocol)) { - sess->do_requests = http_do_requests; - if (!strcmp("https://", info.protocol)) - sess->flags |= GF_DOWNLOAD_SESSION_USE_SSL; + if (sess->do_requests != http_do_requests) { + sess->do_requests = http_do_requests; + socket_changed = 1; + } + if (!strcmp("https://", info.protocol)) { + if (!(sess->flags & GF_DOWNLOAD_SESSION_USE_SSL)) { + sess->flags |= GF_DOWNLOAD_SESSION_USE_SSL; + socket_changed = 1; + } + } else if (sess->flags & GF_DOWNLOAD_SESSION_USE_SSL) { + sess->flags &= ~GF_DOWNLOAD_SESSION_USE_SSL; + socket_changed = 1; + } } else { sess->do_requests = NULL; } - if (sess->orig_url) - gf_free(sess->orig_url); - sess->orig_url = NULL; - if (info.server_name && sess->server_name) - { - gf_free(sess->server_name); - sess->server_name = NULL; - } - if (e == GF_OK) { - const char *opt; - sess->orig_url = gf_strdup(info.canonicalRepresentation); - if (sess->remote_path) - gf_free(sess->remote_path); - sess->remote_path = NULL; - sess->remote_path = gf_strdup(info.remotePath); - sess->server_name = info.server_name ? gf_strdup(info.server_name) : NULL; - if (info.userName) { - if (! sess->dm) { - GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[HTTP] Did not found any download manager, credentials not supported\n")); - } else - sess->creds = gf_user_credentials_register(sess->dm, sess->server_name, info.userName, info.password, info.userName && info.password); - } - /*setup BW limiter*/ - sess->limit_data_rate = 0; - if (sess->dm && sess->dm->cfg) { - opt = gf_cfg_get_key(sess->dm->cfg, "Downloader", "MaxRate"); - if (opt) { - /*use it in in BYTES per second*/ - sess->limit_data_rate = 1024 * atoi(opt) / 8; - } - } - } + if (sess->server_name && info.server_name && !strcmp(sess->server_name, info.server_name)) { + } else { + socket_changed = 1; + if (sess->server_name) gf_free(sess->server_name); + sess->server_name = info.server_name ? gf_strdup(info.server_name) : NULL; + } + + if (sess->orig_url) gf_free(sess->orig_url); + sess->orig_url = gf_strdup(info.canonicalRepresentation); + + if (!sess->orig_url_before_redirect) + sess->orig_url_before_redirect = gf_strdup(url); + + if (sess->remote_path) gf_free(sess->remote_path); + sess->remote_path = gf_strdup(info.remotePath); + + if (!socket_changed && info.userName && sess->creds->username && !strcmp(info.userName, sess->creds->username)) { + } else { + sess->creds = NULL; + if (info.userName ) { + if (! sess->dm) { + GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[HTTP] Did not found any download manager, credentials not supported\n")); + } else + sess->creds = gf_user_credentials_register(sess->dm, sess->server_name, info.userName, info.password, info.userName && info.password); + } + } gf_dm_url_info_del(&info); + + if (sess->sock && !socket_changed) { + sess->status = GF_NETIO_CONNECTED; + sess->num_retry = SESSION_RETRY_COUNT; + /*this should be done when building HTTP GET request in case we have range directives*/ + gf_dm_configure_cache(sess); + } else { + if (sess->sock) gf_sk_del(sess->sock); + sess->sock = NULL; + sess->status = GF_NETIO_SETUP; + } return e; } -#define GF_WAIT_REPLY_SLEEP 20 + static u32 gf_dm_session_thread(void *par) { GF_DownloadSession *sess = (GF_DownloadSession *)par; @@ -916,14 +972,13 @@ static u32 gf_dm_session_thread(void *par) gf_sleep(2); } /*destroy all sessions*/ - gf_dm_disconnect(sess); + gf_dm_disconnect(sess, 0); sess->status = GF_NETIO_STATE_ERROR; sess->last_error = 0; sess->flags |= GF_DOWNLOAD_SESSION_THREAD_DEAD; return 1; } -#define SESSION_RETRY_COUNT 20 GF_DownloadSession *gf_dm_sess_new_simple(GF_DownloadManager * dm, const char *url, u32 dl_flags, gf_dm_user_io user_io, @@ -942,9 +997,10 @@ GF_DownloadSession *gf_dm_sess_new_simple(GF_DownloadManager * dm, const char *u sess->usr_cbk = usr_cbk; sess->creds = NULL; sess->dm = dm; + sess->disable_cache = dm->disable_cache; assert( dm ); - *e = gf_dm_setup_from_url(sess, url); + *e = gf_dm_sess_setup_from_url(sess, url); if (*e) { GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("%s:%d gf_dm_sess_new_simple: error=%s at setup for '%s'\n", __FILE__, __LINE__, gf_error_to_string(*e), url)); gf_dm_sess_del(sess); @@ -956,8 +1012,6 @@ GF_DownloadSession *gf_dm_sess_new_simple(GF_DownloadManager * dm, const char *u sess->mx = gf_mx_new(url); gf_th_run(sess->th, gf_dm_session_thread, sess); } - if (!(sess->flags & GF_NETIO_SESSION_FORCE_NO_CACHE)) - sess->use_cache_file = 0; sess->num_retry = SESSION_RETRY_COUNT; return sess; } @@ -1101,27 +1155,28 @@ static void gf_dm_connect(GF_DownloadSession *sess) } GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[HTTP] Connecting to %s:%d\n", proxy, proxy_port)); - e = gf_sk_connect(sess->sock, (char *) proxy, proxy_port, (char *)ip); + if (sess->status == GF_NETIO_SETUP) { + e = gf_sk_connect(sess->sock, (char *) proxy, proxy_port, (char *)ip); - /*retry*/ - if ((e == GF_IP_SOCK_WOULD_BLOCK) && sess->num_retry) { - sess->status = GF_NETIO_SETUP; - sess->num_retry--; - return; - } + /*retry*/ + if ((e == GF_IP_SOCK_WOULD_BLOCK) && sess->num_retry) { + sess->status = GF_NETIO_SETUP; + sess->num_retry--; + return; + } - /*failed*/ - if (e) { - sess->status = GF_NETIO_STATE_ERROR; - sess->last_error = e; - gf_dm_sess_notify_state(sess, sess->status, e); - return; - } + /*failed*/ + if (e) { + sess->status = GF_NETIO_STATE_ERROR; + sess->last_error = e; + gf_dm_sess_notify_state(sess, sess->status, e); + return; + } - sess->status = GF_NETIO_CONNECTED; - gf_dm_sess_notify_state(sess, GF_NETIO_CONNECTED, GF_OK); - gf_sk_set_buffer_size(sess->sock, 0, GF_DOWNLOAD_BUFFER_SIZE); - gf_dm_configure_cache(sess); + sess->status = GF_NETIO_CONNECTED; + gf_dm_sess_notify_state(sess, GF_NETIO_CONNECTED, GF_OK); + gf_sk_set_buffer_size(sess->sock, 0, GF_DOWNLOAD_BUFFER_SIZE); + } #ifdef GPAC_HAS_SSL if (!sess->ssl && (sess->flags & GF_DOWNLOAD_SESSION_USE_SSL)) { @@ -1154,7 +1209,7 @@ static void gf_dm_connect(GF_DownloadSession *sess) X509_free(cert); if (!success) { - gf_dm_disconnect(sess); + gf_dm_disconnect(sess, 1); sess->status = GF_NETIO_STATE_ERROR; sess->last_error = GF_AUTHENTICATION_FAILURE; gf_dm_sess_notify_state(sess, sess->status, sess->last_error); @@ -1163,6 +1218,10 @@ static void gf_dm_connect(GF_DownloadSession *sess) } } #endif + + /*this should be done when building HTTP GET request in case we have range directives*/ + gf_dm_configure_cache(sess); + } DownloadedCacheEntry gf_dm_refresh_cache_entry(GF_DownloadSession *sess) { @@ -1190,11 +1249,11 @@ DownloadedCacheEntry gf_dm_refresh_cache_entry(GF_DownloadSession *sess) { /* Since HEAD is not understood by this server, we use a GET instead */ sess->http_read_type = GET; sess->flags |= GF_NETIO_SESSION_NOT_CACHED; - gf_dm_disconnect(sess); + gf_dm_disconnect(sess, 0); sess->status = GF_NETIO_SETUP; sess->server_only_understand_get = 1; GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("gf_dm_refresh_cache_entry() : Timeout with HEAD, try with GET\n")); - e = gf_dm_setup_from_url(sess, sess->orig_url); + e = gf_dm_sess_setup_from_url(sess, sess->orig_url); if (e) { GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("gf_dm_refresh_cache_entry() : Error with GET %d\n", e)); sess->status = GF_NETIO_STATE_ERROR; @@ -1237,7 +1296,16 @@ const char *gf_dm_sess_mime_type(GF_DownloadSession *sess) return gf_cache_get_mime_type( sess->cache_entry ); } - +GF_Err gf_dm_sess_set_range(GF_DownloadSession *sess, u64 start_range, u64 end_range) +{ + if (!sess) return GF_BAD_PARAM; + if (sess->cache_entry) return GF_BAD_PARAM; + if (sess->status != GF_NETIO_SETUP) return GF_BAD_PARAM; + sess->range_start = start_range; + sess->range_end = end_range; + sess->needs_range = 1; + return GF_OK; +} GF_Err gf_dm_sess_process(GF_DownloadSession *sess) { @@ -1266,6 +1334,33 @@ GF_Err gf_dm_sess_process(GF_DownloadSession *sess) return sess->last_error; } +GF_Err gf_dm_sess_process_headers(GF_DownloadSession *sess) +{ + Bool go; + go = 1; + while (go) { + switch (sess->status) { + /*setup download*/ + case GF_NETIO_SETUP: + gf_dm_connect(sess); + if (sess->status == GF_NETIO_SETUP) + gf_sleep(16); + break; + case GF_NETIO_WAIT_FOR_REPLY: + gf_sleep(16); + case GF_NETIO_CONNECTED: + sess->do_requests(sess); + break; + case GF_NETIO_DATA_EXCHANGE: + case GF_NETIO_DISCONNECTED: + case GF_NETIO_STATE_ERROR: + go = 0; + break; + } + } + return sess->last_error; +} + static Bool gf_dm_needs_to_delete_cache(GF_DownloadManager * dm) { const char * opt; if (!dm || !dm->cfg) @@ -1320,7 +1415,18 @@ GF_DownloadManager *gf_dm_new(GF_Config *cfg) sprintf(dm->cache_directory, "%s%c", opt, GF_PATH_SEPARATOR); } else { dm->cache_directory = gf_strdup(opt); + } + + opt = cfg ? gf_cfg_get_key(cfg, "Downloader", "MaxRate") : NULL; + /*use it in in BYTES per second*/ + if (opt) dm->limit_data_rate = 1024 * atoi(opt) / 8; + + if (cfg) { + opt = gf_cfg_get_key(cfg, "Downloader", "DisableCache"); + if (!opt) gf_cfg_set_key(cfg, "Downloader", "DisableCache", "no"); + if (opt && !strcmp(opt, "yes")) dm->disable_cache = 1; + } dm->head_timeout = 5000; if (cfg) { @@ -1512,7 +1618,7 @@ static GFINLINE void gf_dm_data_received(GF_DownloadSession *sess, const char *d } if (sess->total_size && (sess->bytes_done == sess->total_size)) { - gf_dm_disconnect(sess); + gf_dm_disconnect(sess, 0); par.msg_type = GF_NETIO_DATA_TRANSFERED; par.error = GF_OK; gf_dm_sess_user_io(sess, &par); @@ -1525,16 +1631,11 @@ static GFINLINE void gf_dm_data_received(GF_DownloadSession *sess, const char *d } /*update state if not done*/ if (rcv) { - sess->bytes_in_wnd += rcv; - runtime = gf_sys_clock() - sess->window_start; + runtime = gf_sys_clock() - sess->start_time; if (!runtime) { sess->bytes_per_sec = 0; } else { - sess->bytes_per_sec = (1000 * (sess->bytes_in_wnd)) / runtime; - if (runtime>1000) { - sess->window_start += runtime/2; - sess->bytes_in_wnd = sess->bytes_per_sec / 2; - } + sess->bytes_per_sec = (1000 * sess->bytes_done) / runtime; } } } @@ -1554,11 +1655,11 @@ GF_Err gf_dm_sess_fetch_data(GF_DownloadSession *sess, char *buffer, u32 buffer_ if (sess->status == GF_NETIO_SETUP) { gf_dm_connect(sess); + if (sess->last_error) return sess->last_error; return GF_OK; } else if (sess->status < GF_NETIO_DATA_EXCHANGE) { sess->do_requests(sess); - if (sess->status > GF_NETIO_DATA_TRANSFERED) return GF_SERVICE_ERROR; - return GF_OK; + return sess->last_error; } /*we're running but we had data previously*/ if (sess->init_data) { @@ -1589,7 +1690,10 @@ GF_Err gf_dm_sess_get_stats(GF_DownloadSession * sess, const char **server, cons if (!sess) return GF_BAD_PARAM; if (server) *server = sess->server_name; if (path) *path = sess->remote_path; - if (total_size) *total_size = sess->total_size; + if (total_size) { + if (sess->total_size==SIZE_IN_STREAM) *total_size = 0; + else *total_size = sess->total_size; + } if (bytes_done) *bytes_done = sess->bytes_done; if (bytes_per_sec) *bytes_per_sec = sess->bytes_per_sec; if (net_status) *net_status = sess->status; @@ -1617,11 +1721,11 @@ void gf_dm_sess_abort(GF_DownloadSession * sess) { if (sess->mx) { gf_mx_p(sess->mx); - gf_dm_disconnect(sess); + gf_dm_disconnect(sess, 1); sess->status = GF_NETIO_STATE_ERROR; gf_mx_v(sess->mx); } else { - gf_dm_disconnect(sess); + gf_dm_disconnect(sess, 1); } } void *gf_dm_sess_get_private(GF_DownloadSession * sess) @@ -1666,7 +1770,7 @@ static GF_Err http_send_headers(GF_DownloadSession *sess, char * sHTTP) { const char *url; const char *user_profile; const char *param_string; - Bool has_accept, has_connection, has_range, has_agent, has_language, send_profile; + Bool has_accept, has_connection, has_range, has_agent, has_language, send_profile, has_mime; assert (sess->status == GF_NETIO_CONNECTED); /*setup authentification*/ strcpy(pass_buf, ""); @@ -1715,11 +1819,8 @@ static GF_Err http_send_headers(GF_DownloadSession *sess, char * sHTTP) { par.name ? par.name : "GET", url, sess->server_name); } - /*signal we support title streaming*/ - if (!strcmp(sess->remote_path, "/")) strcat(sHTTP, "icy-metadata:1\r\n"); - /*get all headers*/ - has_agent = has_accept = has_connection = has_range = has_language = 0; + has_agent = has_accept = has_connection = has_range = has_language = has_mime = 0; while (1) { par.msg_type = GF_NETIO_GET_HEADER; par.value = NULL; @@ -1734,6 +1835,7 @@ static GF_Err http_send_headers(GF_DownloadSession *sess, char * sHTTP) { else if (!strcmp(par.name, "Range")) has_range = 1; else if (!strcmp(par.name, "User-Agent")) has_agent = 1; else if (!strcmp(par.name, "Accept-Language")) has_language = 1; + else if (!strcmp(par.name, "Content-Type")) has_mime = 1; if (!par.msg_type) break; } if (!has_agent) { @@ -1741,12 +1843,14 @@ static GF_Err http_send_headers(GF_DownloadSession *sess, char * sHTTP) { strcat(sHTTP, user_agent); strcat(sHTTP, "\r\n"); } - if (!has_accept) strcat(sHTTP, "Accept: */*\r\n"); + /*no mime and POST/PUT, default to octet stream*/ + if (!has_mime && (sess->http_read_type==OTHER)) strcat(sHTTP, "Content-Type: application/octet-stream\r\n"); + if (!has_accept && (sess->http_read_type!=OTHER) ) strcat(sHTTP, "Accept: */*\r\n"); if (sess->proxy_enabled==1) strcat(sHTTP, "Proxy-Connection: Keep-alive\r\n"); else if (!has_connection) strcat(sHTTP, "Connection: Keep-Alive\r\n"); if (!has_range && sess->needs_range) { - if (!sess->range_end) sprintf(range_buf, "Range: bytes=%d-\r\n", sess->range_start); - else sprintf(range_buf, "Range: bytes=%d-%d\r\n", sess->range_start, sess->range_end); + if (!sess->range_end) sprintf(range_buf, "Range: bytes="LLD"-\r\n", sess->range_start); + else sprintf(range_buf, "Range: bytes="LLD"-"LLD"\r\n", sess->range_start, sess->range_end); /* FIXME : cache should not be used here */ strcat(sHTTP, range_buf); } @@ -1811,26 +1915,28 @@ static GF_Err http_send_headers(GF_DownloadSession *sess, char * sHTTP) { strcat(sHTTP, range_buf); } } - /*{ - const char * mime = gf_cache_get_mime_type(sess->cache_entry); - if (sess->server_only_understand_get || mime && !strcmp("audio/mpeg", mime)){*/ - /* This will force the server to respond with Icy-Metaint */ - strcat(sHTTP, "Icy-Metadata: 1\r\n"); - /* } - }*/ - if (GF_OK < appendHttpCacheHeaders( sess->cache_entry, sHTTP)) { - GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("Cache Entry : %p, FAILED to append cache directives.", sess->cache_entry)); - } + if (sess->http_read_type!=OTHER) { + /*signal we support title streaming*/ + if (!strcmp(sess->remote_path, "/")) strcat(sHTTP, "icy-metadata:1\r\n"); + /* This will force the server to respond with Icy-Metaint */ + strcat(sHTTP, "Icy-Metadata: 1\r\n"); + + /*cached headers are not appended in POST*/ + if (!sess->disable_cache && (GF_OK < appendHttpCacheHeaders( sess->cache_entry, sHTTP)) ) { + GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("Cache Entry : %p, FAILED to append cache directives.", sess->cache_entry)); + } + } strcat(sHTTP, "\r\n"); if (send_profile || par.data) { u32 len = strlen(sHTTP); - char *tmp_buf = gf_malloc(sizeof(char)*(len+par.size)); + char *tmp_buf = gf_malloc(sizeof(char)*(len+par.size+1)); strcpy(tmp_buf, sHTTP); if (par.data) { memcpy(tmp_buf+len, par.data, par.size); + tmp_buf[len+par.size] = 0; } else { FILE *profile; assert( sess->dm ); @@ -1903,18 +2009,18 @@ static GF_Err http_parse_remaining_body(GF_DownloadSession * sess, char * sHTTP) return GF_REMOTE_SERVICE_ERROR; #if 1 - if (sess->limit_data_rate && sess->bytes_per_sec) { - if (sess->bytes_per_sec>sess->limit_data_rate) { + if (sess->dm && sess->dm->limit_data_rate && sess->bytes_per_sec) { + if (sess->bytes_per_sec > sess->dm->limit_data_rate) { /*update state*/ - u32 runtime = gf_sys_clock() - sess->window_start; - sess->bytes_per_sec = (1000 * (sess->bytes_in_wnd)) / runtime; - if (sess->bytes_per_sec > sess->limit_data_rate) return GF_OK; + u32 runtime = gf_sys_clock() - sess->start_time; + sess->bytes_per_sec = (1000 * sess->bytes_done) / runtime; + if (sess->bytes_per_sec > sess->dm->limit_data_rate) return GF_OK; } } #endif e = gf_dm_read_data(sess, sHTTP, GF_DOWNLOAD_BUFFER_SIZE, &size); if (e!= GF_IP_CONNECTION_CLOSED && (!size || e == GF_IP_NETWORK_EMPTY)) { - if (e == GF_IP_CONNECTION_CLOSED || (!sess->total_size && (gf_sys_clock() - sess->window_start > 5000))) { + if (e == GF_IP_CONNECTION_CLOSED || (!sess->total_size && (gf_sys_clock() - sess->start_time > 5000))) { sess->total_size = sess->bytes_done; gf_dm_sess_notify_state(sess, GF_NETIO_DATA_TRANSFERED, GF_OK); assert(sess->server_name); @@ -1940,7 +2046,7 @@ static GF_Err http_parse_remaining_body(GF_DownloadSession * sess, char * sHTTP) e = GF_OK; } } - gf_dm_disconnect(sess); + gf_dm_disconnect(sess, 1); sess->last_error = e; gf_dm_sess_notify_state(sess, sess->status, e); return e; @@ -1980,12 +2086,14 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) continue; /*socket has been closed while configuring, retry (not sure if the server got the GET)*/ case GF_IP_CONNECTION_CLOSED: - gf_dm_disconnect(sess); - if (!strncmp("HEAD", sHTTP, 4)) { + if (sess->http_read_type == HEAD) { /* Some servers such as shoutcast directly close connection if HEAD or an unknown method is issued */ sess->server_only_understand_get = 1; } - if (sess->num_retry) + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[HTTP] Connection closed by server when getting %s - retrying\n", sess->remote_path)); + gf_dm_disconnect(sess, 1); + + if (sess->num_retry) sess->status = GF_NETIO_SETUP; else { sess->last_error = e; @@ -2097,10 +2205,9 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) if (hdr_val[0] == ':') hdr_val += 1; hdr_val += http_skip_space(hdr_val); if (hdr_val[0] == '*') { - sscanf(hdr_val, "*/%ud", &total_size); + sscanf(hdr_val, "*/%u", &total_size); } else { - /*do not use %ud here, broken on Win32 (sscanf returns 1)*/ - sscanf(hdr_val, "%d-%d/%d", &first_byte, &last_byte, &total_size); + sscanf(hdr_val, "%u-%u/%u", &first_byte, &last_byte, &total_size); } } } @@ -2136,6 +2243,9 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) if (sep) sep[0]=':'; if (hdr_sep) hdr_sep[0] = '\r'; + + + if (sess->status==GF_NETIO_DISCONNECTED) return GF_OK; } if (no_range) first_byte = 0; @@ -2175,9 +2285,9 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) new_location[strlen(new_location)-1] = 0; /*reset and reconnect*/ - gf_dm_disconnect(sess); + gf_dm_disconnect(sess, 1); sess->status = GF_NETIO_SETUP; - e = gf_dm_setup_from_url(sess, new_location); + e = gf_dm_sess_setup_from_url(sess, new_location); if (e) { sess->status = GF_NETIO_STATE_ERROR; sess->last_error = e; @@ -2188,7 +2298,7 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) { sess->status = GF_NETIO_PARSE_REPLY; gf_dm_sess_notify_state(sess, GF_NETIO_PARSE_REPLY, GF_OK); - gf_dm_disconnect(sess); + gf_dm_disconnect(sess, 0); if (sess->user_proc) { /* For modules that do not use cache and have problems with GF_NETIO_DATA_TRANSFERED ... */ const char * filename; @@ -2200,9 +2310,9 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) if (!f) { GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[HTTP] FAILED to open cache file %s for reading contents !\n", filename)); /* Ooops, no cache, redowload everything ! */ - gf_dm_disconnect(sess); + gf_dm_disconnect(sess, 0); sess->status = GF_NETIO_SETUP; - e = gf_dm_setup_from_url(sess, sess->orig_url); + e = gf_dm_sess_setup_from_url(sess, sess->orig_url); sess->total_size = gf_cache_get_cache_filesize(sess->cache_entry); if (e) { sess->status = GF_NETIO_STATE_ERROR; @@ -2212,7 +2322,7 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) return e; } sess->status = GF_NETIO_DATA_EXCHANGE; - { + if (! (sess->flags & GF_NETIO_SESSION_NOT_THREADED)) { char file_cache_buff[16384]; int read = 0; u32 total_size = gf_cache_get_cache_filesize(sess->cache_entry); @@ -2248,7 +2358,7 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) sess->creds = gf_user_credentials_register(sess->dm, sess->server_name, NULL, NULL, 0); if (!sess->creds) { /* User credentials have not been filled properly, we have to abort */ - gf_dm_disconnect(sess); + gf_dm_disconnect(sess, 1); sess->status = GF_NETIO_STATE_ERROR; par.error = GF_AUTHENTICATION_FAILURE; par.msg_type = GF_NETIO_DISCONNECTED; @@ -2257,9 +2367,9 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) sess->last_error = e; goto exit; } - gf_dm_disconnect(sess); + gf_dm_disconnect(sess, 0); sess->status = GF_NETIO_SETUP; - e = gf_dm_setup_from_url(sess, sess->orig_url); + e = gf_dm_sess_setup_from_url(sess, sess->orig_url); if (e) { sess->status = GF_NETIO_STATE_ERROR; sess->last_error = e; @@ -2282,15 +2392,15 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) case 400: case 501: /* Method not implemented ! */ - if (sess->http_read_type != GET) { + if (sess->http_read_type == HEAD) { /* Since HEAD is not understood by this server, we use a GET instead */ sess->http_read_type = GET; sess->flags |= GF_NETIO_SESSION_NOT_CACHED; - gf_dm_disconnect(sess); + gf_dm_disconnect(sess, 0); sess->status = GF_NETIO_SETUP; sess->server_only_understand_get = 1; GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("Method not supported, try with GET.\n")); - e = gf_dm_setup_from_url(sess, sess->orig_url); + e = gf_dm_sess_setup_from_url(sess, sess->orig_url); if (e) { sess->status = GF_NETIO_STATE_ERROR; sess->last_error = e; @@ -2298,12 +2408,16 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) } return e; } - return GF_URL_ERROR; + + gf_dm_sess_user_io(sess, &par); + e = GF_REMOTE_SERVICE_ERROR; + goto exit; + case 503: /*retry without proxy*/ if (sess->proxy_enabled==1) { sess->proxy_enabled=2; - gf_dm_disconnect(sess); + gf_dm_disconnect(sess, 1); sess->status = GF_NETIO_SETUP; return GF_OK; } @@ -2317,7 +2431,7 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) sess->use_cache_file = 0; if (sess->http_read_type==HEAD) { - gf_dm_disconnect(sess); + gf_dm_disconnect(sess, 0); gf_dm_sess_notify_state(sess, GF_NETIO_DATA_TRANSFERED, GF_OK); sess->status = GF_NETIO_DISCONNECTED; sess->http_read_type = 0; @@ -2352,7 +2466,7 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) sess->bytes_done = 0; } else { /*we don't expect anything*/ - gf_dm_disconnect(sess); + gf_dm_disconnect(sess, 0); gf_dm_sess_notify_state(sess, GF_NETIO_DATA_TRANSFERED, GF_OK); sess->status = GF_NETIO_DISCONNECTED; return GF_OK; @@ -2371,9 +2485,7 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) } } - sess->window_start = sess->start_time = gf_sys_clock(); - sess->bytes_in_wnd = 0; - + sess->start_time = gf_sys_clock(); /* we may have existing data in this buffer ... */ if (!e && (BodyStart < (s32) bytesRead)) { @@ -2386,13 +2498,15 @@ static GF_Err wait_for_header_and_parse(GF_DownloadSession *sess, char * sHTTP) exit: if (e) { GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[HTTP] Error parsing reply: %s for URL %s\n", gf_error_to_string(e), sess->orig_url )); - gf_dm_disconnect(sess); + gf_dm_disconnect(sess, 1); sess->status = GF_NETIO_STATE_ERROR; sess->last_error = e; gf_dm_sess_notify_state(sess, sess->status, e); return e; } - return http_parse_remaining_body(sess, sHTTP); + /*DO NOT call parse_body yet, as the final user may not be connected to our session*/ + //return http_parse_remaining_body(sess, sHTTP); + return GF_OK; } /** @@ -2415,49 +2529,6 @@ void http_do_requests(GF_DownloadSession *sess) } } -#define FILE_W_BUFFER_SZ 1024 - -GF_Err gf_dm_copy(const char * file_source, const char * file_dest) { - FILE * source, * dest; - char buff[FILE_W_BUFFER_SZ]; - u32 readen, written; - GF_Err e = GF_OK; - source = gf_f64_open(file_source, "rb"); - dest = gf_f64_open( file_dest, "wb"); - if (!source || !dest) { - e = GF_IO_ERR; - goto cleanup; - } - readen = fread(buff, sizeof(char), FILE_W_BUFFER_SZ, source); - while (readen > 1) { - written = fwrite(buff, sizeof(char), readen, dest); - if (written != readen) { - e = GF_IO_ERR; - goto cleanup; - } - readen = fread(buff, sizeof(char), FILE_W_BUFFER_SZ, source); - } - -cleanup: - if (source) - fclose(source); - if (dest) - fclose(dest); - return e; -} - - -GF_Err gf_dm_copy_or_link(const char * file_source, const char * file_dest) { -#ifdef __USE_POSIX - if (link( file_source, file_dest)) { -#endif /* __USE_POSIX */ - return gf_dm_copy(file_source, file_dest); -#ifdef __USE_POSIX - } - return GF_OK; -#endif /* #ifdef __POSIX__ */ -} - /** * NET IO for MPD, we don't need this anymore since mime-type can be given by session @@ -2509,30 +2580,91 @@ GF_Err gf_dm_wget_with_cache(GF_DownloadManager * dm, e = gf_dm_sess_process(dnload); } e|= gf_cache_close_write_cache(dnload->cache_entry, dnload, e == GF_OK); - /* e|= gf_dm_copy_or_link( gf_cache_get_cache_filename(dnload->cache_entry), filename ); */ fclose(f); gf_dm_sess_del(dnload); return e; } +GF_Err gf_dm_get_file_memory(const char *url, char **out_data, u32 *out_size, char **out_mime) +{ + GF_Err e; + FILE * f; + GF_DownloadSession *dnload; + GF_DownloadManager *dm; + + if (!url || !out_data || !out_size) + return GF_BAD_PARAM; + f = gf_temp_file_new(); + if (!f) { + GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[WGET] Failed to create temp file for write.\n")); + return GF_IO_ERR; + } + + dm = gf_dm_new(NULL); + if (!dm) { + fclose(f); + return GF_OUT_OF_MEM; + } + + dnload = gf_dm_sess_new_simple(dm, (char *)url, GF_NETIO_SESSION_NOT_THREADED, &wget_NetIO, f, &e); + if (!dnload) { + gf_dm_del(dm); + return GF_BAD_PARAM; + } + dnload->use_cache_file = 0; + dnload->disable_cache = 1; + if (!e) + e = gf_dm_sess_process(dnload); + + if (!e) + e = gf_cache_close_write_cache(dnload->cache_entry, dnload, e == GF_OK); + + if (!e) { + u32 size = ftell(f); + *out_size = size; + *out_data = gf_malloc(sizeof(char)* ( 1 + size)); + fseek(f, 0, SEEK_SET); + fread(*out_data, 1, size, f); + (*out_data)[size] = 0; + if (out_mime) { + const char *mime = gf_dm_sess_mime_type(dnload); + if (mime) *out_mime = gf_strdup(mime); + } + } + fclose(f); + gf_dm_sess_del(dnload); + gf_dm_del(dm); + return e; +} + const char *gf_dm_sess_get_resource_name(GF_DownloadSession *dnload) { return dnload ? dnload->orig_url : NULL; } +const char *gf_dm_sess_get_original_resource_name(GF_DownloadSession *dnload) +{ + if (dnload) return dnload->orig_url_before_redirect ? dnload->orig_url_before_redirect : dnload->orig_url; + return NULL; +} + +u32 gf_dm_sess_get_status(GF_DownloadSession *dnload) +{ + return dnload ? dnload->status : GF_NETIO_STATE_ERROR; +} + GF_Err gf_dm_sess_reset(GF_DownloadSession *sess) { if (!sess) return GF_BAD_PARAM; sess->status = GF_NETIO_SETUP; sess->needs_range = 0; sess->range_start = sess->range_end = 0; - sess->bytes_done = sess->bytes_in_wnd = sess->bytes_per_sec = 0; + sess->bytes_done = sess->bytes_per_sec = 0; if (sess->init_data) gf_free(sess->init_data); sess->init_data = NULL; sess->init_data_size = 0; sess->last_error = GF_OK; sess->total_size = 0; - sess->window_start = 0; sess->start_time = 0; return GF_OK; } @@ -2627,3 +2759,88 @@ const char * gf_cache_get_cache_filename_range( const GF_DownloadSession * sess, } } } + +GF_Err gf_dm_sess_reassign(GF_DownloadSession *sess, u32 flags, gf_dm_user_io user_io, void *cbk) +{ + /*shall only be called for non-threaded sessions!! */ + if (sess->th) return GF_BAD_PARAM; + +#if 0 + /*if the user requests non-cached (eg callback-sent) data, but the session was configured to use file, we need to copy back existing + data to the session init_data */ + if (sess->use_cache_file && (flags & GF_NETIO_SESSION_NOT_CACHED)) { + if (sess->cache_entry) { + FILE *fptr = gf_cache_get_file_pointer(sess->cache_entry); + if (fptr) { + gf_f64_seek(fptr, 0, SEEK_END); + sess->init_data_size = (u32) gf_f64_tell(fptr); + gf_f64_seek(fptr, 0, SEEK_SET); + if (sess->init_data) gf_free(sess->init_data); + sess->init_data = gf_malloc(sess->init_data_size); + sess->init_data_size = fread(sess->init_data, 1, sess->init_data_size, fptr); + gf_cache_close_write_cache(sess->cache_entry, sess, 0); + } + gf_dm_remove_cache_entry_from_session(sess); + sess->cache_entry = NULL; + } + sess->use_cache_file = 0; + } +#endif + + +#if 0 + /*the case where the user wants file but the session is configured as live is simply ignored*/ + else if (!sess->use_cache_file && (sess->flags & GF_NETIO_SESSION_NOT_CACHED)) { + sess->use_cache_file = 1; + gf_dm_configure_cache(sess); + + if (sess->http_read_type == GET ) { + e = gf_cache_open_write_cache(sess->cache_entry, sess); + if (e) return e; + + if (sess->init_data && sess->init_data_size) { + gf_cache_write_to_cache(sess->cache_entry, sess, sess->init_data, sess->init_data_size); + if (sess->init_data) { + gf_free(sess->init_data); + sess->init_data = NULL; + } + sess->init_data_size = 0; + } + } + } +#endif + + sess->flags = flags; + sess->user_proc = user_io; + sess->usr_cbk = cbk; + + sess->num_retry = SESSION_RETRY_COUNT; + + if (sess->status==GF_NETIO_DISCONNECTED) + sess->status = GF_NETIO_SETUP; + + if ( ! (flags & GF_NETIO_SESSION_NOT_THREADED) ) { + sess->th = gf_th_new(sess->orig_url); + sess->mx = gf_mx_new(sess->orig_url); + gf_th_run(sess->th, gf_dm_session_thread, sess); + } + + return GF_OK; +} + +GF_EXPORT +void gf_dm_set_data_rate(GF_DownloadManager *dm, u32 rate_in_byte_per_sec) +{ + dm->limit_data_rate = rate_in_byte_per_sec; + if (dm->cfg) { + char szBuf[100]; + sprintf(szBuf, "%d", rate_in_byte_per_sec*128/*8/1024*/); + gf_cfg_set_key(dm->cfg, "Downloader", "MaxRate", szBuf); + } +} + +u32 gf_dm_get_data_rate(GF_DownloadManager *dm) +{ + return dm->limit_data_rate; +} + diff --git a/src/utils/error.c b/src/utils/error.c index 65eb92b..ea44a57 100644 --- a/src/utils/error.c +++ b/src/utils/error.c @@ -133,10 +133,12 @@ u32 global_log_tools = 0; u32 gf_log_parse_level(const char *val) { #ifndef GPAC_DISABLE_LOG + if (!val) return 0; if (!stricmp(val, "error")) return GF_LOG_ERROR; if (!stricmp(val, "warning")) return GF_LOG_WARNING; if (!stricmp(val, "info")) return GF_LOG_INFO; if (!stricmp(val, "debug")) return GF_LOG_DEBUG; + fprintf(stderr, "Unknown log level specified: %s\n", val); #endif return 0; } @@ -165,14 +167,18 @@ u32 gf_log_parse_tools(const char *val) else if (!stricmp(val, "smil")) flags |= GF_LOG_SMIL; else if (!stricmp(val, "compose")) flags |= GF_LOG_COMPOSE; else if (!stricmp(val, "mmio")) flags |= GF_LOG_MMIO; - else if (!stricmp(val, "none")) flags = 0; - else if (!stricmp(val, "all")) flags = 0xFFFFFFFF; else if (!stricmp(val, "rti")) flags |= GF_LOG_RTI; else if (!stricmp(val, "cache")) flags |= GF_LOG_CACHE; else if (!stricmp(val, "audio")) flags |= GF_LOG_AUDIO; else if (!stricmp(val, "mem")) flags |= GF_LOG_MEMORY; else if (!stricmp(val, "module")) flags |= GF_LOG_MODULE; else if (!stricmp(val, "mutex")) flags |= GF_LOG_MUTEX; + else if (!stricmp(val, "none")) flags = 0; + else if (!stricmp(val, "all")) flags = 0xFFFFFFFF; + else { + fprintf(stderr, "Unknown log tool specified: %s\n", val); + return 0; + } if (!sep) break; sep[0] = ':'; val = sep+1; @@ -198,9 +204,9 @@ void default_log_callback(void *cbck, u32 level, u32 tool, const char* fmt, va_l #endif } - static void *user_log_cbk = NULL; static gf_log_cbk log_cbk = default_log_callback; +static Bool log_exit_on_error = 0; GF_EXPORT void gf_log(const char *fmt, ...) @@ -209,6 +215,8 @@ void gf_log(const char *fmt, ...) va_start(vl, fmt); log_cbk(user_log_cbk, call_lev, call_tool, fmt, vl); va_end(vl); + if (log_exit_on_error && call_lev==GF_LOG_ERROR) + exit(1); } GF_EXPORT @@ -216,11 +224,19 @@ void gf_log_set_level(u32 level) { global_log_level = level; } + +GF_EXPORT +void gf_log_set_strict_error(Bool strict) +{ + log_exit_on_error = strict; +} + GF_EXPORT void gf_log_set_tools(u32 modules) { global_log_tools = modules; } + GF_EXPORT void gf_log_lt(u32 ll, u32 lt) { @@ -251,6 +267,10 @@ void gf_log_set_level(u32 level) { } GF_EXPORT +void gf_log_set_strict_error(Bool strict) +{ +} +GF_EXPORT void gf_log_set_tools(u32 modules) { } diff --git a/src/utils/math.c b/src/utils/math.c index ce7d706..97586bb 100644 --- a/src/utils/math.c +++ b/src/utils/math.c @@ -1146,7 +1146,9 @@ GF_EXPORT void gf_vec_norm(GF_Vec *v) { Fixed __res = gf_vec_len(*v); - if (__res ) __res = 1.0f/__res ; + if (!__res ) return; + if (__res == FIX_ONE) return; + __res = 1.0f/__res; v->x *= __res; v->y *= __res; v->z *= __res; diff --git a/src/utils/module.c b/src/utils/module.c index 6128f5c..45df7ea 100644 --- a/src/utils/module.c +++ b/src/utils/module.c @@ -183,10 +183,10 @@ GF_BaseInterface *gf_modules_load_interface(GF_ModuleManager *pm, u32 whichplug, if (!strcmp(inst->name, "gm_sdl_out.dylib")) { if (InterfaceFamily == GF_VIDEO_OUTPUT_INTERFACE) { ifce = SDL_Module_Load_Video(); - fprintf(stderr, "*** Loading SDL Video: 0x%p ***\n", ifce); + fprintf(stderr, "*** Loading SDL Video: %p ***\n", ifce); } else if (InterfaceFamily == GF_AUDIO_OUTPUT_INTERFACE) { ifce = SDL_Module_Load_Audio(); - fprintf(stderr, "*** Loading SDL Audio: 0x%p ***\n", ifce); + fprintf(stderr, "*** Loading SDL Audio: %p ***\n", ifce); } } #endif @@ -197,13 +197,13 @@ GF_BaseInterface *gf_modules_load_interface(GF_ModuleManager *pm, u32 whichplug, gf_list_add(inst->interfaces, ifce); /*keep track of parent*/ ifce->HPLUG = inst; - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Load interface %s DONE.\n", inst->name)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Load interface %s DONE.\n", inst->name)); return ifce; err_exit: - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Load interface %s exit label, freing library...\n", inst->name)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Load interface %s exit label, freing library...\n", inst->name)); gf_modules_unload_library(inst); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Load interface %s EXIT.\n", inst->name)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Load interface %s EXIT.\n", inst->name)); return NULL; } @@ -236,7 +236,7 @@ GF_BaseInterface *gf_modules_load_interface_by_name(GF_ModuleManager *pm, const for (i=0; imodule_name && !stricmp(ifce->module_name, plug_name)) { + if (ifce->module_name && !strnicmp(ifce->module_name, plug_name, MIN(strlen(ifce->module_name), strlen(plug_name)) )) { /*update cache entry*/ gf_cfg_set_key(pm->cfg, "PluginsCache", plug_name, ((ModuleInstance*)ifce->HPLUG)->name); GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Core] Added plugin cache %s for %s\n", plug_name, ((ModuleInstance*)ifce->HPLUG)->name)); diff --git a/src/utils/os_config_init.c b/src/utils/os_config_init.c new file mode 100644 index 0000000..c25aa41 --- /dev/null +++ b/src/utils/os_config_init.c @@ -0,0 +1,518 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Telecom ParisTech 2011- + * All rights reserved + * Authors: Jean Le Feuvre + * + * This file is part of GPAC / common tools 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 + + +#if defined(WIN32) || defined(_WIN32_WCE) +#include /*for GetModuleFileName*/ + +#ifndef _WIN32_WCE +#include /*for _mkdir*/ +#include /*for getting user-dir*/ + +#ifndef SHGFP_TYPE_CURRENT +#define SHGFP_TYPE_CURRENT 0 /*needed for MinGW*/ +#endif + +#endif + +#define CFG_FILE_NAME "GPAC.cfg" +#define TEST_MODULE "gm_dummy_in.dll" + +#elif (defined(__DARWIN__) || defined(__APPLE__) ) +#include /*for _NSGetExecutablePath */ + +#define TEST_MODULE "gm_dummy_in.dylib" +#define CFG_FILE_NAME ".gpacrc" + +#else +#ifdef GPAC_CONFIG_LINUX +#include +#endif +#define CFG_FILE_NAME ".gpacrc" +#define TEST_MODULE "gm_dummy_in.so" +#endif + + +static Bool check_file_exists(char *name, char *path, char *outPath) +{ + char szPath[GF_MAX_PATH]; + FILE *f; + sprintf(szPath, "%s%c%s", path, GF_PATH_SEPARATOR, name); + f = fopen(szPath, "rb"); + if (!f) return 0; + fclose(f); + if (outPath != path) strcpy(outPath, path); + return 1; +} + +enum +{ + GF_PATH_APP, + GF_PATH_CFG, + GF_PATH_GUI, + GF_PATH_MODULES, +}; + +#if defined(WIN32) || defined(_WIN32_WCE) +static Bool get_default_install_path(char *file_path, u32 path_type) +{ + FILE *f; + char *sep; + char szPath[GF_MAX_PATH]; + + +#ifdef _WIN32_WCE + TCHAR w_szPath[GF_MAX_PATH]; + GetModuleFileName(NULL, w_szPath, GF_MAX_PATH); + CE_WideToChar((u16 *) w_szPath, file_path); +#else + GetModuleFileNameA(NULL, file_path, GF_MAX_PATH); +#endif + + /*remove exe name*/ + if (strstr(file_path, ".exe")) { + sep = strrchr(file_path, '\\'); + if (sep) sep[0] = 0; + } + + strcpy(szPath, file_path); + strlwr(szPath); + + /*if this is run from a browser, we do not get our app path - fortunately on Windows, we always use 'GPAC' in the + installation path*/ + if (!strstr(file_path, "gpac")) { + HKEY hKey = NULL; + DWORD dwSize = GF_MAX_PATH; + DWORD dwType = REG_SZ; + + /*locate the key in current user, then in local machine*/ +#ifdef _WIN32_WCE + u16 w_path[1024]; + RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\GPAC"), 0, KEY_READ, &hKey); +#ifdef _DEBUG + if (RegQueryValueEx(hKey, TEXT("DebugDir"), 0, &dwType, (LPBYTE) w_path, &dwSize) != ERROR_SUCCESS) +#endif + RegQueryValueEx(hKey, TEXT("InstallDir"), 0, &dwType, (LPBYTE) w_path, &dwSize); + CE_WideToChar(w_path, (char *)file_path); + RegCloseKey(hKey); +#else + if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\GPAC", 0, KEY_READ, &hKey) != ERROR_SUCCESS) + RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\GPAC", 0, KEY_READ, &hKey); + + dwSize = GF_MAX_PATH; + +#ifdef _DEBUG + if (RegQueryValueEx(hKey, "DebugDir", NULL, NULL,(unsigned char*) file_path, &dwSize) != ERROR_SUCCESS) +#endif + RegQueryValueEx(hKey, "InstallDir", NULL, NULL,(unsigned char*) file_path, &dwSize); + + RegCloseKey(hKey); +#endif + } + + + if (path_type==GF_PATH_APP) return 1; + + if (path_type==GF_PATH_GUI) { + char *sep; + strcat(file_path, "\\gui"); + if (check_file_exists("gui.bt", file_path, file_path)) return 1; + sep = strstr(file_path, "\\bin\\"); + if (sep) { + sep[0] = 0; + strcat(file_path, "\\gui"); + if (check_file_exists("gui.bt", file_path, file_path)) return 1; + } + return 0; + } + /*modules are stored in the GPAC directory (should be changed to GPAC/modules)*/ + if (path_type==GF_PATH_MODULES) return 1; + + /*we are looking for the config file path - make sure it is writable*/ + + strcpy(szPath, file_path); + strcat(szPath, "\\gpaccfgtest.txt"); + f = gf_f64_open(szPath, "wb"); + if (f != NULL) { + fclose(f); + gf_delete_file(szPath); + return 1; + } +#ifdef _WIN32_WCE + return 0; +#else + /*no write access, get user home directory*/ + SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, file_path); + if (file_path[strlen(file_path)-1] != '\\') strcat(file_path, "\\"); + strcat(file_path, "GPAC"); + /*create GPAC dir*/ + _mkdir(file_path); + strcpy(szPath, file_path); + strcat(szPath, "\\gpaccfgtest.txt"); + f = gf_f64_open(szPath, "wb"); + /*COMPLETE FAILURE*/ + if (!f) return 0; + + fclose(f); + gf_delete_file(szPath); + return 1; +#endif +} + +/*FIXME - android initialization is a mess right now*/ +#elif defined(GPAC_ANDROID) + +static Bool get_default_install_path(char *file_path, u32 path_type) +{ + if (path_type==GF_PATH_APP) strcpy(file_path, ""); + else if (path_type==GF_PATH_CFG) strcpy(file_path, ""); + else if (path_type==GF_PATH_GUI) strcpy(file_path, ""); + else if (path_type==GF_PATH_MODULES) strcpy(file_path, ""); + return 1; +} + + +#elif defined(__SYMBIAN__) + +#if defined(__SERIES60_3X__) +#define SYMBIAN_GPAC_CFG_DIR "\\private\\F01F9075" +#define SYMBIAN_GPAC_GUI_DIR "\\private\\F01F9075\\gui" +#define SYMBIAN_GPAC_MODULES_DIR "\\sys\\bin" +#else +#define SYMBIAN_GPAC_CFG_DIR "\\system\\apps\\Osmo4" +#define SYMBIAN_GPAC_GUI_DIR "\\system\\apps\\Osmo4\\gui" +#define SYMBIAN_GPAC_MODULES_DIR GPAC_CFG_DIR +#endif + +static Bool get_default_install_path(char *file_path, u32 path_type) +{ + if (path_type==GF_PATH_APP) strcpy(file_path, SYMBIAN_GPAC_MODULES_DIR); + else if (path_type==GF_PATH_CFG) strcpy(file_path, SYMBIAN_GPAC_CFG_DIR); + else if (path_type==GF_PATH_GUI) strcpy(file_path, SYMBIAN_GPAC_GUI_DIR); + else if (path_type==GF_PATH_MODULES) strcpy(file_path, SYMBIAN_GPAC_MODULES_DIR); + return 1; +} + +/*Linux, OSX, iOS*/ +#else + +static Bool get_default_install_path(char *file_path, u32 path_type) +{ + char app_path[GF_MAX_PATH]; + char *sep; + u32 size = GF_MAX_PATH; + + /*on OSX, Linux & co, user home is where we store the cfg file*/ + if (path_type==GF_PATH_CFG) { + char *user_home = getenv("HOME"); + if (!user_home) return 0; + strcpy(file_path, user_home); + if (file_path[strlen(file_path)-1] == '/') file_path[strlen(file_path)-1] = 0; + return 1; + } + + if (path_type==GF_PATH_APP) { +#if (defined(__DARWIN__) || defined(__APPLE__) ) + if (_NSGetExecutablePath(app_path, &size) ==0) { + realpath(app_path, file_path); + char *sep = strrchr(file_path, '/'); + if (sep) sep[0] = 0; + return 1; + } + +#elif defined(GPAC_CONFIG_LINUX) + size = readlink("/proc/self/exe", file_path, GF_MAX_PATH); + if (size>0) { + char *sep = strrchr(file_path, '/'); + if (sep) sep[0] = 0; + return 1; + } +#endif + return 0; + } + + + /*locate the app*/ + if (!get_default_install_path(app_path, GF_PATH_APP)) return 0; + + /*installed or symlink on system, user user home directory*/ + if (!strnicmp(app_path, "/usr/", 5) || !strnicmp(app_path, "/opt/", 5)) { + if (path_type==GF_PATH_GUI) { + /*look in possible install dirs ...*/ + if (check_file_exists("gui.bt", "/usr/share/gpac/gui", file_path)) return 1; + if (check_file_exists("gui.bt", "/usr/local/share/gpac/gui", file_path)) return 1; + if (check_file_exists("gui.bt", "/opt/share/gpac/gui", file_path)) return 1; + if (check_file_exists("gui.bt", "/opt/local/share/gpac/gui", file_path)) return 1; + } else if (path_type==GF_PATH_MODULES) { + /*look in possible install dirs ...*/ + if (check_file_exists(TEST_MODULE, "/usr/lib/gpac", file_path)) return 1; + if (check_file_exists(TEST_MODULE, "/usr/local/lib/gpac", file_path)) return 1; + if (check_file_exists(TEST_MODULE, "/opt/lib/gpac", file_path)) return 1; + if (check_file_exists(TEST_MODULE, "/opt/local/lib/gpac", file_path)) return 1; + } + } + + if (path_type==GF_PATH_GUI) { + if (get_default_install_path(app_path, GF_PATH_CFG)) { + /*GUI not found, look in ~/.gpac/gui/ */ + strcat(app_path, "/.gpac/gui"); + if (check_file_exists("gui.bt", app_path, file_path)) return 1; + } + + /*GUI not found, look in gpac distribution if any */ + if (get_default_install_path(app_path, GF_PATH_APP)) { + char *sep = strstr(app_path, "/bin/gcc"); + if (sep) { + sep[0] = 0; + strcat(app_path, "/gui"); + if (check_file_exists("gui.bt", app_path, file_path)) return 1; + } + } + /*GUI not found, look in .app for OSX case*/ + } + + if (path_type==GF_PATH_MODULES) { + /*look in gpac compilation tree (modules are output in the same folder as apps) */ + if (get_default_install_path(app_path, GF_PATH_APP)) { + if (check_file_exists(TEST_MODULE, app_path, file_path)) return 1; + /*on OSX check modules subdirectory */ + strcat(app_path, "/modules"); + if (check_file_exists(TEST_MODULE, app_path, file_path)) return 1; + } + /*modules not found, look in ~/.gpac/modules/ */ + if (get_default_install_path(app_path, GF_PATH_CFG)) { + strcpy(app_path, file_path); + strcat(app_path, "/.gpac/modules"); + if (check_file_exists(TEST_MODULE, app_path, file_path)) return 1; + } + /*modules not found, failure*/ + return 0; + } + + /*OSX way vs iPhone*/ + sep = strstr(app_path, ".app/"); + if (sep) sep[4] = 0; + + /*we are looking for .app install path, or GUI */ + if (path_type==GF_PATH_GUI) { +#ifndef GPAC_IPHONE + strcat(app_path, "/Contents/MacOS/gui"); + if (check_file_exists("gui.bt", app_path, file_path)) return 1; +#else /*iOS: for now, everything is set flat within the package*/ + /*iOS app is distributed with embedded GUI*/ + get_default_install_path(app_path, GF_PATH_APP); + strcat(app_path, "/gui"); + if (check_file_exists("gui_old.bt", app_path, file_path)) return 1; +#endif + } + else { // (path_type==GF_PATH_MODULES) + strcat(app_path, "/Contents/MacOS/modules"); + if (check_file_exists(TEST_MODULE, app_path, file_path)) return 1; + } + /*not found ...*/ + return 0; +} + +#endif + + +static GF_Config *create_default_config(char *file_path) +{ + FILE *f; + GF_Config *cfg; + char *cache_dir; + char szPath[GF_MAX_PATH]; + char gui_path[GF_MAX_PATH]; + + if (! get_default_install_path(file_path, GF_PATH_CFG)) { + gf_delete_file(szPath); + return NULL; + } + /*Create the config file*/ + sprintf(szPath, "%s%c%s", file_path, GF_PATH_SEPARATOR, CFG_FILE_NAME); + f = gf_f64_open(szPath, "wt"); + if (!f) return NULL; + fclose(f); + + if (! get_default_install_path(szPath, GF_PATH_MODULES)) { + gf_delete_file(szPath); + fprintf(stdout, "default modules not found\n"); + return NULL; + } + + cfg = gf_cfg_new(file_path, CFG_FILE_NAME); + if (!cfg) return NULL; + + gf_cfg_set_key(cfg, "General", "ModulesDirectory", szPath); + + /*get default temporary directoy */ + cache_dir = gf_get_default_cache_directory(); + if (cache_dir) { + gf_cfg_set_key(cfg, "General", "CacheDirectory", cache_dir); + gf_free(cache_dir); + } + + gf_cfg_set_key(cfg, "Compositor", "Raster2D", "GPAC 2D Raster"); + gf_cfg_set_key(cfg, "Audio", "ForceConfig", "yes"); + gf_cfg_set_key(cfg, "Audio", "NumBuffers", "2"); + gf_cfg_set_key(cfg, "Audio", "TotalDuration", "120"); + gf_cfg_set_key(cfg, "Audio", "DisableNotification", "no"); + + /*Setup font engine to FreeType by default, and locate TrueType font directory on the system*/ + gf_cfg_set_key(cfg, "FontEngine", "FontReader", "ft_font"); + gf_cfg_set_key(cfg, "FontEngine", "RescanFonts", "yes"); + + +#if defined(_WIN32_WCE) + /*FIXME - is this true on all WinCE systems??*/ + strcpy(szPath, "\\Windows"); +#elif defined(WIN32) + GetWindowsDirectory((char*)szPath, MAX_PATH); + if (szPath[strlen((char*)szPath)-1] != '\\') strcat((char*)szPath, "\\"); + strcat((char *)szPath, "Fonts"); +#elif defined(__APPLE__) + +#ifdef GPAC_IPHONE + strcpy(szPath, "/System/Library/Fonts/Cache"); +#else + strcpy(szPath, "/Library/Fonts"); +#endif + +#else + strcpy(szPath, "/usr/share/fonts/truetype/"); +#endif + gf_cfg_set_key(cfg, "FontEngine", "FontDirectory", szPath); + + gf_cfg_set_key(cfg, "Downloader", "CleanCache", "yes"); + gf_cfg_set_key(cfg, "Compositor", "AntiAlias", "All"); + gf_cfg_set_key(cfg, "Compositor", "FrameRate", "30"); + /*use power-of-2 emulation in OpenGL if no rectangular texture extension*/ + gf_cfg_set_key(cfg, "Compositor", "EmulatePOW2", "yes"); + gf_cfg_set_key(cfg, "Compositor", "ScalableZoom", "yes"); + +#if defined(_WIN32_WCE) + gf_cfg_set_key(cfg, "Video", "DriverName", "GAPI Video Output"); +#elif defined(WIN32) + gf_cfg_set_key(cfg, "Video", "DriverName", "DirectX Video Output"); +#elif defined(__DARWIN__) || defined(__APPLE__) + gf_cfg_set_key(cfg, "Video", "DriverName", "SDL Video Output"); +#else + gf_cfg_set_key(cfg, "Video", "DriverName", "X11 Video Output"); + gf_cfg_set_key(cfg, "Audio", "DriverName", "SDL Audio Output"); +#endif + + gf_cfg_set_key(cfg, "Video", "SwitchResolution", "no"); + gf_cfg_set_key(cfg, "Video", "HardwareMemory", "Auto"); + gf_cfg_set_key(cfg, "Network", "AutoReconfigUDP", "yes"); + gf_cfg_set_key(cfg, "Network", "UDPTimeout", "10000"); + gf_cfg_set_key(cfg, "Network", "BufferLength", "3000"); + + + /*locate GUI*/ + if ( get_default_install_path(szPath, GF_PATH_GUI) ) { + sprintf(gui_path, "%s%cgui.bt", szPath, GF_PATH_SEPARATOR); + f = fopen(gui_path, "rt"); + if (f) { + fclose(f); + gf_cfg_set_key(cfg, "General", "StartupFile", gui_path); + } + } + + /*store and reload*/ + gf_cfg_del(cfg); + return gf_cfg_new(file_path, CFG_FILE_NAME); +} + +/*check if modules directory has changed in the config file +this is mainly intended for OSX where we can have an install in /usr/... and an install in /Applications/Osmo4.app +*/ +static void check_modules_dir(GF_Config *cfg) +{ + char path[GF_MAX_PATH]; + const char *opt; + + if ( get_default_install_path(path, GF_PATH_MODULES) ) { +#if defined(__DARWIN__) || defined(__APPLE__) + opt = gf_cfg_get_key(cfg, "General", "ModulesDirectory"); + if (!opt || strcmp(opt, path)) gf_cfg_set_key(cfg, "General", "ModulesDirectory", path); +#endif + } + + /*if startup file was disabled, do not attempt to correct it*/ + if (gf_cfg_get_key(cfg, "General", "StartupFile")==NULL) return; + + if ( get_default_install_path(path, GF_PATH_GUI) ) { + opt = gf_cfg_get_key(cfg, "General", "StartupFile"); + if (strstr(opt, "gui.bt") && strcmp(opt, path)) { +#if defined(_WIN32_WCE) || defined(WIN32) + strcat(path, "\\gui.bt"); +#else + strcat(path, "/gui.bt"); +#endif + gf_cfg_set_key(cfg, "General", "StartupFile", path); + } + } +} + +GF_Config *gf_cfg_init(const char *file, Bool *new_cfg) +{ + GF_Config *cfg; + char szPath[GF_MAX_PATH]; + + if (new_cfg) *new_cfg = 0; + + if (file) { + cfg = gf_cfg_new(NULL, file); + if (cfg) { + check_modules_dir(cfg); + return cfg; + } + } + + if (!get_default_install_path(szPath, GF_PATH_CFG)) { + fprintf(stderr, "Fatal error: Cannot create a configuration file in application or user home directory - no write access\n"); + return NULL; + } + cfg = gf_cfg_new(szPath, CFG_FILE_NAME); + if (!cfg) { + fprintf(stdout, "GPAC config file %s not found in %s - creating new file\n", CFG_FILE_NAME, szPath); + cfg = create_default_config(szPath); + } + + if (!cfg) { + fprintf(stdout, "cannot create config file %s in %s directory\n", CFG_FILE_NAME, szPath); + return NULL; + } + + fprintf(stdout, "Using config file in %s directory\n", szPath); + + check_modules_dir(cfg); + + if (new_cfg) *new_cfg = 1; + return cfg; +} + diff --git a/src/utils/os_divers.c b/src/utils/os_divers.c index 3db684e..87ce36c 100644 --- a/src/utils/os_divers.c +++ b/src/utils/os_divers.c @@ -193,7 +193,7 @@ GF_Err gf_delete_file(const char *fileName) { #if defined(_WIN32_WCE) TCHAR swzName[MAX_PATH]; - CE_CharToWide(fileName, swzName); + CE_CharToWide((char*)fileName, swzName); return (DeleteFile(swzName)==0) ? GF_IO_ERR : GF_OK; #elif defined(WIN32) /* success if != 0 */ @@ -209,8 +209,8 @@ void gf_move_file(const char *fileName, const char *newFileName) #if defined(_WIN32_WCE) TCHAR swzName[MAX_PATH]; TCHAR swzNewName[MAX_PATH]; - CE_CharToWide(fileName, swzName); - CE_CharToWide(newFileName, swzNewName); + CE_CharToWide((char*)fileName, swzName); + CE_CharToWide((char*)newFileName, swzNewName); MoveFile(swzName, swzNewName); #elif defined(WIN32) MoveFile(fileName, newFileName); @@ -856,6 +856,8 @@ sh4_change_fpscr(int off, int on) void gf_mem_enable_tracker(); #endif +static u64 memory_at_gpac_startup = 0; + void gf_sys_init(Bool enable_memory_tracker) { if (!sys_init) { @@ -937,6 +939,14 @@ void gf_sys_init(Bool enable_memory_tracker) #endif } sys_init += 1; + + + /*init RTI stats*/ + if (!memory_at_gpac_startup) { + GF_SystemRTInfo rti; + gf_sys_get_rti(500, &rti, GF_RTI_SYSTEM_MEMORY_ONLY); + memory_at_gpac_startup = rti.physical_memory_avail; + } } void gf_sys_close() @@ -956,6 +966,10 @@ void gf_sys_close() if (psapi_hinst) FreeLibrary(psapi_hinst); psapi_hinst = NULL; #endif + +#ifdef GPAC_MEMORY_TRACKING + gf_memory_print(); +#endif } } @@ -965,10 +979,9 @@ extern size_t gpac_nb_alloc_blocs; #endif /*CPU and Memory Usage*/ - #ifdef WIN32 -Bool gf_sys_get_rti(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) +Bool gf_sys_get_rti_os(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) { #if defined(_WIN32_WCE) THREADENTRY32 tentry; @@ -1229,11 +1242,15 @@ Bool gf_sys_get_rti(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) #include #include #include +#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1060 +#include +#else #include +#endif static u64 total_physical_memory = 0; -Bool gf_sys_get_rti(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) +Bool gf_sys_get_rti_os(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) { size_t length; u32 entry_time, i, percent; @@ -1340,7 +1357,7 @@ Bool gf_sys_get_rti(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) //linux #else -Bool gf_sys_get_rti(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) +Bool gf_sys_get_rti_os(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) { u32 entry_time; u64 process_u_k_time; @@ -1500,6 +1517,18 @@ Bool gf_sys_get_rti(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) #endif + +Bool gf_sys_get_rti(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) +{ + Bool res = gf_sys_get_rti_os(refresh_time_ms, rti, flags); + if (res) { + if (!rti->process_memory) rti->process_memory = memory_at_gpac_startup - rti->physical_memory_avail; + if (!rti->gpac_memory) rti->gpac_memory = memory_at_gpac_startup - rti->physical_memory_avail; + } + return res; +} + + char * gf_get_default_cache_directory(){ #ifdef _WIN32_WCE return gf_strdup( "\\windows\\temp" ); @@ -1637,22 +1666,45 @@ exit: close(fd); return NULL; } - #else /* WIN32 */ -#pragma message("gf_global_resource_lock() not implemented") struct _GF_GlobalLock_opaque { char * resourceName; + HANDLE hMutex; /*a named mutex is a system-mode object on windows*/ }; - #endif GF_GlobalLock * gf_global_resource_lock(const char * resourceName){ #ifdef WIN32 - GF_GlobalLock * lock = gf_malloc(sizeof(GF_GlobalLock)); - lock->resourceName = gf_strdup( resourceName ); - /* TODO : implement this properly for Windows... */ - return lock; +#ifdef _WIN32_WCE + unsigned short sWResourceName[MAX_PATH]; +#endif + GF_GlobalLock *lock = gf_malloc(sizeof(GF_GlobalLock)); + lock->resourceName = gf_strdup(resourceName); + + /*first ensure mutex is created*/ +#ifdef _WIN32_WCE + CE_CharToWide((char *)resourceName, sWResourceName); + lock->hMutex = CreateMutex(NULL, TRUE, sWResourceName); +#else + lock->hMutex = CreateMutex(NULL, TRUE, resourceName); +#endif + if (!lock->hMutex) { + DWORD lastErr = GetLastError(); + if (lastErr != ERROR_ALREADY_EXISTS) + return NULL; + } + + /*then lock it*/ + switch (WaitForSingleObject(lock->hMutex, INFINITE)) { + case WAIT_ABANDONED: + case WAIT_TIMEOUT: + assert(0); /*serious error: someone has modified the object elsewhere*/ + gf_global_resource_unlock(lock); + return NULL; + } + + return lock; #else /* WIN32 */ return gf_create_PID_file(resourceName); #endif /* WIN32 */ @@ -1674,9 +1726,17 @@ GF_Err gf_global_resource_unlock(GF_GlobalLock * lock){ gf_free(lock->pidFile); lock->pidFile = NULL; lock->fd = -1; -#endif /* not defined WIN32 */ - if (lock->resourceName) - gf_free(lock->resourceName); +#else /* WIN32 */ + { + /*MSDN: "The mutex object is destroyed when its last handle has been closed."*/ + BOOL ret = ReleaseMutex(lock->hMutex); + assert(ret); + ret = CloseHandle(lock->hMutex); + assert(ret); + } +#endif + if (lock->resourceName) + gf_free(lock->resourceName); lock->resourceName = NULL; gf_free(lock); return GF_OK; diff --git a/src/utils/os_net.c b/src/utils/os_net.c index 08da742..71f2546 100644 --- a/src/utils/os_net.c +++ b/src/utils/os_net.c @@ -615,7 +615,7 @@ GF_Err gf_sk_bind(GF_Socket *sock, const char *local_ip, u16 port, const char *p s32 optval; if (!sock || sock->socket) return GF_BAD_PARAM; - + #ifndef WIN32 if(!local_ip){ if(!peer_name || !strcmp(peer_name,"localhost")){ @@ -631,7 +631,10 @@ GF_Err gf_sk_bind(GF_Socket *sock, const char *local_ip, u16 port, const char *p /*probe way to peer: is it V4 or V6? */ if (peer_name && peer_port) { res = gf_sk_get_ipv6_addr(peer_name, peer_port, af, AI_PASSIVE, type); - if (!res) return GF_IP_CONNECTION_FAILURE; + if (!res) { + GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[Socket] Cannot get IPV6 host name for %s:%d\n", peer_name, peer_port)); + return GF_IP_ADDRESS_NOT_FOUND; + } #ifdef WIN32 /*win32 has troubles redirecting IPV4 datagrams to IPV6 sockets, so override local family type to avoid IPV4(S)->IPV6(C) UDP*/ @@ -657,7 +660,10 @@ GF_Err gf_sk_bind(GF_Socket *sock, const char *local_ip, u16 port, const char *p res = gf_sk_get_ipv6_addr(NULL, port, af, AI_PASSIVE, type); local_ip = NULL; } - if (!res) return GF_IP_CONNECTION_FAILURE; + if (!res) { + GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[Socket] Cannot get IPV6 host name for %s:%d\n", local_ip, port)); + return GF_IP_ADDRESS_NOT_FOUND; + } } /*for all interfaces*/ @@ -700,6 +706,7 @@ GF_Err gf_sk_bind(GF_Socket *sock, const char *local_ip, u16 port, const char *p return GF_OK; } freeaddrinfo(res); + GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[Socket] Cannot bind to host %s port %d\n", local_ip, port)); return GF_IP_CONNECTION_FAILURE; #else diff --git a/src/utils/os_thread.c b/src/utils/os_thread.c index bf14b32..a01a114 100644 --- a/src/utils/os_thread.c +++ b/src/utils/os_thread.c @@ -114,7 +114,7 @@ GF_Thread *gf_th_new(const char *name) tmp->log_name = gf_strdup(name); } else { char szN[20]; - sprintf(szN, "0x%p", (void*)tmp); + sprintf(szN, "%p", (void*)tmp); tmp->log_name = gf_strdup(szN); } log_add_thread(tmp); @@ -332,7 +332,7 @@ u32 gf_th_id() #ifdef WIN32 return ((u32) GetCurrentThreadId()); #else - return ((u32) pthread_self()); + return ((u32) (PTR_TO_U_CAST(pthread_self()))); #endif } @@ -381,7 +381,7 @@ GF_Mutex *gf_mx_new(const char *name) tmp->log_name = gf_strdup(name); } else { char szN[20]; - sprintf(szN, "0x%p", (void*)tmp); + sprintf(szN, "%p", (void*)tmp); tmp->log_name = gf_strdup(szN); } assert( tmp->log_name); @@ -486,14 +486,20 @@ Bool gf_mx_try_lock(GF_Mutex *mx) } #ifdef WIN32 - /*wait for 1 ms (I can't figure out from MS doc if 0 timeout only "tests the state" or also lock the mutex ... */ - switch (WaitForSingleObject(mx->hMutex, 1)) { + /*is the object signaled?*/ + switch (WaitForSingleObject(mx->hMutex, 0)) { + case WAIT_OBJECT_0: + break; case WAIT_ABANDONED: case WAIT_TIMEOUT: GF_LOG(GF_LOG_DEBUG, GF_LOG_MUTEX, ("[Mutex %s] At %d Couldn't be locked by thread %s (grabbed by thread %s)\n", mx->log_name, gf_sys_clock(), log_th_name(caller), log_th_name(mx->Holder) )); return 0; + case WAIT_FAILED: + GF_LOG(GF_LOG_ERROR, GF_LOG_MUTEX, ("[Mutex %s] At %d WaitForSingleObject failed\n", mx->log_name, gf_sys_clock())); + return 0; default: - break; + assert(0); + return 0; } #else if (pthread_mutex_trylock(&mx->hMutex) != 0 ) { @@ -540,7 +546,7 @@ GF_Semaphore *gf_sema_new(u32 MaxCount, u32 InitCount) */ { char semaName[40]; - sprintf(semaName,"GPAC_SEM%d", (u32) tmp); + sprintf(semaName,"GPAC_SEM%ld", (unsigned long) tmp); tmp->SemName = gf_strdup(semaName); } tmp->hSemaphore = sem_open(tmp->SemName, O_CREAT, S_IRUSR|S_IWUSR, InitCount); diff --git a/src/utils/xml_parser.c b/src/utils/xml_parser.c index 603945c..75c06c8 100644 --- a/src/utils/xml_parser.c +++ b/src/utils/xml_parser.c @@ -64,7 +64,7 @@ static char *xml_translate_xml_string(char *str) if (szChar[2]=='x') sscanf(szChar, "&#x%x;", &val); else - sscanf(szChar, "&#%ud;", &val); + sscanf(szChar, "&#%u;", &val); wchar[0] = val; srcp = wchar; j += gf_utf8_wcstombs(&value[j], 20, &srcp);