|
From: <ny...@us...> - 2007-09-25 14:27:03
|
Revision: 416
http://pmplib.svn.sourceforge.net/pmplib/?rev=416&view=rev
Author: nyaochi
Date: 2007-09-25 07:27:01 -0700 (Tue, 25 Sep 2007)
Log Message:
-----------
- Sync with MPEG4ip Version 1.6. libgmi now requires
libmp4v2 bundled with version 1.6.
- Retrieval of albumartist values.
Modified Paths:
--------------
trunk/pmplib/lib/gmi/contrib/mp4v2/mp4.h
trunk/pmplib/lib/gmi/contrib/mp4v2/mpeg4ip.h
trunk/pmplib/lib/gmi/contrib/mp4v2/mpeg4ip_version.h
trunk/pmplib/lib/gmi/contrib/mp4v2/mpeg4ip_win32.h
trunk/pmplib/lib/gmi/gmi.vcproj
trunk/pmplib/lib/gmi/gmi_mp4v2.c
Added Paths:
-----------
trunk/pmplib/lib/gmi/contrib/mp4v2/win32/libmp4v2.lib
trunk/pmplib/lib/gmi/contrib/mp4v2/win32/libmp4v2d.lib
Removed Paths:
-------------
trunk/pmplib/lib/gmi/contrib/mp4v2/win32/libmp4v260.lib
trunk/pmplib/lib/gmi/contrib/mp4v2/win32/libmp4v260d.lib
Modified: trunk/pmplib/lib/gmi/contrib/mp4v2/mp4.h
===================================================================
--- trunk/pmplib/lib/gmi/contrib/mp4v2/mp4.h 2007-09-24 03:34:31 UTC (rev 415)
+++ trunk/pmplib/lib/gmi/contrib/mp4v2/mp4.h 2007-09-25 14:27:01 UTC (rev 416)
@@ -33,18 +33,19 @@
/* include system and project specific headers */
#include "mpeg4ip.h"
-
#include <math.h> /* to define float HUGE_VAL and/or NAN */
#ifndef NAN
#define NAN HUGE_VAL
#endif
+#ifndef DEFAULT
#ifdef __cplusplus
/* exploit C++ ability of default values for function parameters */
#define DEFAULT(x) =x
#else
#define DEFAULT(x)
#endif
+#endif
/* MP4 API types */
typedef void* MP4FileHandle;
@@ -54,6 +55,26 @@
typedef u_int64_t MP4Duration;
typedef u_int32_t MP4EditId;
+typedef u_int64_t (*VIRTUALIO_GETFILELENGTH)(void *user); // return file length in bytes
+typedef int (*VIRTUALIO_SETPOSITION)(void *user, u_int64_t position); // return 0 on success
+typedef int (*VIRTUALIO_GETPOSITION)(void *user, u_int64_t *position); // fill position, return 0 on success
+typedef size_t (*VIRTUALIO_READ)(void *user, void *buffer, size_t size); // return number of bytes actually read
+typedef size_t (*VIRTUALIO_WRITE)(void *user, void *buffer, size_t size); // return number of bytes actually written
+typedef int (*VIRTUALIO_ENDOFFILE)(void *user); // return 1 if file hit EOF
+typedef int (*VIRTUALIO_CLOSE)(void *user); // return 0 on success
+
+typedef struct Virtual_IO
+{
+ VIRTUALIO_GETFILELENGTH GetFileLength;
+ VIRTUALIO_SETPOSITION SetPosition;
+ VIRTUALIO_GETPOSITION GetPosition;
+ VIRTUALIO_READ Read;
+ VIRTUALIO_WRITE Write;
+ VIRTUALIO_ENDOFFILE EndOfFile;
+ VIRTUALIO_CLOSE Close;
+} Virtual_IO_t;
+
+
/* Invalid values for API types */
#define MP4_INVALID_FILE_HANDLE ((MP4FileHandle)NULL)
#define MP4_INVALID_TRACK_ID ((MP4TrackId)0)
@@ -100,6 +121,7 @@
#define MP4_VIDEO_TRACK_TYPE "vide"
#define MP4_HINT_TRACK_TYPE "hint"
#define MP4_CNTL_TRACK_TYPE "cntl"
+#define MP4_TEXT_TRACK_TYPE "text"
/*
* This second set of track types should be created
* via MP4AddSystemsTrack(type)
@@ -169,6 +191,11 @@
#define MP4_MPEG4_WAVETABLE_AUDIO_TYPE 14
#define MP4_MPEG4_MIDI_AUDIO_TYPE 15
#define MP4_MPEG4_ALGORITHMIC_FX_AUDIO_TYPE 16
+#define MP4_MPEG4_ALS_AUDIO_TYPE 31
+#define MP4_MPEG4_LAYER1_AUDIO_TYPE 32
+#define MP4_MPEG4_LAYER2_AUDIO_TYPE 33
+#define MP4_MPEG4_LAYER3_AUDIO_TYPE 34
+#define MP4_MPEG4_SLS_AUDIO_TYPE 35
/* MP4 Audio type utilities following common usage */
#define MP4_IS_MP3_AUDIO_TYPE(type) \
@@ -313,7 +340,13 @@
const char* fileName,
u_int32_t verbosity DEFAULT(0));
-bool MP4Close(
+// benski>
+MP4FileHandle MP4ReadEx(const char* fileName,
+ void *user,
+ Virtual_IO_t *virtual_IO,
+ u_int32_t verbosity DEFAULT(0));
+
+void MP4Close(
MP4FileHandle hFile);
bool MP4Optimize(
@@ -340,7 +373,7 @@
u_int32_t MP4GetVerbosity(MP4FileHandle hFile);
-bool MP4SetVerbosity(MP4FileHandle hFile, u_int32_t verbosity);
+void MP4SetVerbosity(MP4FileHandle hFile, u_int32_t verbosity);
MP4Duration MP4GetDuration(MP4FileHandle hFile);
@@ -359,11 +392,11 @@
u_int8_t MP4GetVideoProfileLevel(MP4FileHandle hFile,
MP4TrackId trackId DEFAULT(MP4_INVALID_TRACK_ID));
-bool MP4SetVideoProfileLevel(MP4FileHandle hFile, u_int8_t value);
+void MP4SetVideoProfileLevel(MP4FileHandle hFile, u_int8_t value);
u_int8_t MP4GetAudioProfileLevel(MP4FileHandle hFile);
-bool MP4SetAudioProfileLevel(MP4FileHandle hFile, u_int8_t value);
+void MP4SetAudioProfileLevel(MP4FileHandle hFile, u_int8_t value);
u_int8_t MP4GetGraphicsProfileLevel(MP4FileHandle hFile);
@@ -440,9 +473,12 @@
u_int8_t key_ind_len;
u_int8_t iv_len;
u_int8_t selective_enc;
- char *kms_uri;
+ const char *kms_uri;
} mp4v2_ismacrypParams;
+// API to initialize ismacryp properties to sensible defaults
+// if input param is null then mallocs a params struct
+mp4v2_ismacrypParams *MP4DefaultISMACrypParams(mp4v2_ismacrypParams *ptr);
MP4TrackId MP4AddEncAudioTrack(
MP4FileHandle hFile,
@@ -450,6 +486,7 @@
MP4Duration sampleDuration,
mp4v2_ismacrypParams *icPp,
u_int8_t audioType DEFAULT(MP4_MPEG4_AUDIO_TYPE));
+
MP4TrackId MP4AddAmrAudioTrack(
MP4FileHandle hFile,
u_int32_t timeScale,
@@ -473,8 +510,11 @@
MP4TrackId MP4AddHrefTrack(MP4FileHandle hFile,
uint32_t timeScale,
- MP4Duration sampleDuration);
+ MP4Duration sampleDuration,
+ const char *base_url DEFAULT(NULL));
+const char *MP4GetHrefTrackBaseUrl(MP4FileHandle hFile,
+ MP4TrackId trackId);
MP4TrackId MP4AddVideoTrack(
MP4FileHandle hFile,
u_int32_t timeScale,
@@ -490,7 +530,8 @@
u_int16_t width,
u_int16_t height,
mp4v2_ismacrypParams *icPp,
- u_int8_t videoType DEFAULT(MP4_MPEG4_VIDEO_TYPE));
+ u_int8_t videoType DEFAULT(MP4_MPEG4_VIDEO_TYPE),
+ const char *oFormat DEFAULT(NULL));
MP4TrackId MP4AddH264VideoTrack(
MP4FileHandle hFile,
@@ -502,11 +543,22 @@
uint8_t profile_compat,
uint8_t AVCLevelIndication,
uint8_t sampleLenFieldSizeMinusOne);
-bool MP4AddH264SequenceParameterSet(MP4FileHandle hFile,
+
+MP4TrackId MP4AddEncH264VideoTrack(
+ MP4FileHandle dstFile,
+ u_int32_t timeScale,
+ MP4Duration sampleDuration,
+ u_int16_t width,
+ u_int16_t height,
+ MP4FileHandle srcFile,
+ MP4TrackId srcTrackId,
+ mp4v2_ismacrypParams *icPp);
+
+void MP4AddH264SequenceParameterSet(MP4FileHandle hFile,
MP4TrackId trackId,
const uint8_t *pSequence,
uint16_t sequenceLen);
-bool MP4AddH264PictureParameterSet(MP4FileHandle hFile,
+void MP4AddH264PictureParameterSet(MP4FileHandle hFile,
MP4TrackId trackId,
const uint8_t *pPict,
uint16_t pictLen);
@@ -541,6 +593,14 @@
MP4FileHandle hFile,
MP4TrackId refTrackId);
+MP4TrackId MP4AddTextTrack(
+ MP4FileHandle hFile,
+ MP4TrackId refTrackId);
+
+MP4TrackId MP4AddChapterTextTrack(
+ MP4FileHandle hFile,
+ MP4TrackId refTrackId);
+
MP4TrackId MP4CloneTrack(
MP4FileHandle srcFile,
MP4TrackId srcTrackId,
@@ -573,7 +633,7 @@
bool applyEdits DEFAULT(false),
MP4TrackId dstHintTrackReferenceTrack DEFAULT(MP4_INVALID_TRACK_ID));
-bool MP4DeleteTrack(
+void MP4DeleteTrack(
MP4FileHandle hFile,
MP4TrackId trackId);
@@ -606,6 +666,12 @@
const char *MP4GetTrackMediaDataName(MP4FileHandle hFile,
MP4TrackId trackId);
+
+// MP4GetTrackMediaDataOriginalFormat is to be used to get the original
+// MediaDataName if a track has been encrypted.
+bool MP4GetTrackMediaDataOriginalFormat(MP4FileHandle hFile,
+ MP4TrackId trackId, char *originalFormat, u_int32_t buflen);
+
MP4Duration MP4GetTrackDuration(
MP4FileHandle hFile,
MP4TrackId trackId);
@@ -614,7 +680,7 @@
MP4FileHandle hFile,
MP4TrackId trackId);
-bool MP4SetTrackTimeScale(
+void MP4SetTrackTimeScale(
MP4FileHandle hFile,
MP4TrackId trackId,
u_int32_t value);
@@ -658,7 +724,7 @@
MP4TrackId trackId,
uint8_t *pProfile,
uint8_t *pLevel);
-bool MP4GetTrackH264SeqPictHeaders(MP4FileHandle hFile,
+void MP4GetTrackH264SeqPictHeaders(MP4FileHandle hFile,
MP4TrackId trackId,
uint8_t ***pSeqHeaders,
uint32_t **pSeqHeaderSize,
@@ -1100,8 +1166,9 @@
/* iTunes metadata handling */
bool MP4MetadataDelete(MP4FileHandle hFile);
bool MP4GetMetadataByIndex(MP4FileHandle hFile, u_int32_t index,
- const char** ppName,
- u_int8_t** ppValue, u_int32_t* pValueSize);
+ char** ppName, // need to free memory
+ u_int8_t** ppValue, // need to free
+ u_int32_t* pValueSize);
bool MP4SetMetadataName(MP4FileHandle hFile, const char* value);
bool MP4GetMetadataName(MP4FileHandle hFile, char** value);
bool MP4DeleteMetadataName(MP4FileHandle hFile);
@@ -1145,19 +1212,27 @@
bool MP4SetMetadataCompilation(MP4FileHandle hFile, u_int8_t cpl);
bool MP4GetMetadataCompilation(MP4FileHandle hFile, u_int8_t* cpl);
bool MP4DeleteMetadataCompilation(MP4FileHandle hFile);
+bool MP4SetMetadataPartOfGaplessAlbum(MP4FileHandle hFile, uint8_t pgap);
+bool MP4GetMetadataPartOfGaplessAlbum(MP4FileHandle hFile, uint8_t *pgap);
+bool MP4DeleteMetadataPartOfGaplessAlbum(MP4FileHandle hFile);
bool MP4SetMetadataCoverArt(MP4FileHandle hFile,
u_int8_t *coverArt, u_int32_t size);
bool MP4GetMetadataCoverArt(MP4FileHandle hFile,
- u_int8_t **coverArt, u_int32_t* size);
+ u_int8_t **coverArt, u_int32_t* size,
+ uint32_t index DEFAULT(0));
u_int32_t MP4GetMetadataCoverArtCount(MP4FileHandle hFile);
bool MP4DeleteMetadataCoverArt(MP4FileHandle hFile);
-bool MP4SetMetadataFreeForm(MP4FileHandle hFile, char *name,
- u_int8_t* pValue, u_int32_t valueSize);
-bool MP4GetMetadataFreeForm(MP4FileHandle hFile, char *name,
- u_int8_t** pValue, u_int32_t* valueSize);
-bool MP4DeleteMetadataFreeForm(MP4FileHandle hFile, char *name);
-
+bool MP4SetMetadataAlbumArtist(MP4FileHandle hFile, const char* value);
+bool MP4GetMetadataAlbumArtist(MP4FileHandle hFile, char** value);
+bool MP4DeleteMetadataAlbumArtist(MP4FileHandle hFile);
+
+bool MP4SetMetadataFreeForm(MP4FileHandle hFile, const char *name,
+ const u_int8_t* pValue, u_int32_t valueSize, const char *owner DEFAULT(NULL));
+bool MP4GetMetadataFreeForm(MP4FileHandle hFile, const char *name,
+ u_int8_t** pValue, u_int32_t* valueSize, const char *owner DEFAULT(NULL));
+bool MP4DeleteMetadataFreeForm(MP4FileHandle hFile, const char *name, const char *owner DEFAULT(NULL));
+
/* time conversion utilties */
/* predefined values for timeScale parameter below */
@@ -1211,7 +1286,7 @@
uint8_t *Base64ToBinary(const char *pData,
uint32_t decodeSize,
uint32_t *pDataSize);
-
+void MP4Free(void *p);
#ifdef __cplusplus
}
#endif
Modified: trunk/pmplib/lib/gmi/contrib/mp4v2/mpeg4ip.h
===================================================================
--- trunk/pmplib/lib/gmi/contrib/mp4v2/mpeg4ip.h 2007-09-24 03:34:31 UTC (rev 415)
+++ trunk/pmplib/lib/gmi/contrib/mp4v2/mpeg4ip.h 2007-09-25 14:27:01 UTC (rev 416)
@@ -331,5 +331,12 @@
AUDIO_FMT_HW_AC3,
} audio_format_t;
+#ifndef HAVE_STRUCT_IOVEC
+struct iovec {
+ void *iov_base;
+ unsigned int iov_len;
+};
+#endif
+
#endif /* __MPEG4IP_INCLUDED__ */
Modified: trunk/pmplib/lib/gmi/contrib/mp4v2/mpeg4ip_version.h
===================================================================
--- trunk/pmplib/lib/gmi/contrib/mp4v2/mpeg4ip_version.h 2007-09-24 03:34:31 UTC (rev 415)
+++ trunk/pmplib/lib/gmi/contrib/mp4v2/mpeg4ip_version.h 2007-09-25 14:27:01 UTC (rev 416)
@@ -1,6 +1,6 @@
#define MPEG4IP_PACKAGE "mpeg4ip"
-#define MPEG4IP_VERSION "1.5.0.1"
+#define MPEG4IP_VERSION "1.6"
#define MPEG4IP_MAJOR_VERSION 0x1
-#define MPEG4IP_MINOR_VERSION 0x5
-#define MPEG4IP_CVS_VERSION 0x01
+#define MPEG4IP_MINOR_VERSION 0x6
+#define MPEG4IP_CVS_VERSION 0x
#define MPEG4IP_HEX_VERSION ((MPEG4IP_MAJOR_VERSION << 16) | (MPEG4IP_MINOR_VERSION << 8) | MPEG4IP_CVS_VERSION)
Modified: trunk/pmplib/lib/gmi/contrib/mp4v2/mpeg4ip_win32.h
===================================================================
--- trunk/pmplib/lib/gmi/contrib/mp4v2/mpeg4ip_win32.h 2007-09-24 03:34:31 UTC (rev 415)
+++ trunk/pmplib/lib/gmi/contrib/mp4v2/mpeg4ip_win32.h 2007-09-25 14:27:01 UTC (rev 416)
@@ -24,9 +24,17 @@
#define HAVE_IN_PORT_T
#define HAVE_SOCKLEN_T
#define NEED_SDL_VIDEO_IN_MAIN_THREAD
+#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
+#endif
#define _WINSOCKAPI_
#define _INTEGRAL_MAX_BITS 64
+#ifndef __GNUC__
+#define _CRT_SECURE_NO_DEPRECATE 1
+#ifndef _WIN32
+#define _WIN32
+#endif
+#endif
#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
@@ -35,6 +43,9 @@
#include <time.h>
#include <limits.h>
+#ifndef inline
+#define inline __inline
+#endif
typedef unsigned __int64 uint64_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int16 uint16_t;
@@ -43,22 +54,39 @@
typedef unsigned __int32 u_int32_t;
typedef unsigned __int16 u_int16_t;
typedef unsigned __int8 u_int8_t;
-typedef __int64 int64_t;
-typedef __int32 int32_t;
-typedef __int16 int16_t;
-typedef __int8 int8_t;
+typedef signed __int64 int64_t;
+typedef signed __int32 int32_t;
+typedef signed __int16 int16_t;
+typedef signed __int8 int8_t;
typedef unsigned short in_port_t;
typedef int socklen_t;
typedef int ssize_t;
typedef unsigned int uint;
-#define snprintf _snprintf
+static inline int snprintf(char *buffer, size_t count,
+ const char *format, ...) {
+ va_list ap;
+ int ret;
+ va_start(ap, format);
+ ret = vsnprintf_s(buffer, count, _TRUNCATE, format, ap);
+ va_end(ap);
+ if (ret == -1) {
+ if (errno == EINVAL) return -1;
+ return (int)count;
+ }
+ return ret;
+}
#define strncasecmp _strnicmp
#define strcasecmp _stricmp
+#define localtime_r(a,b) localtime_s(b,a)
+#define printf printf_s
+#define fprintf fprintf_s
#include <io.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
+#ifndef __GNUC__
+#define read _read
#define write _write
#define lseek _lseek
#define close _close
@@ -67,6 +95,9 @@
#define vsnprintf _vsnprintf
#define stat _stati64
#define fstat _fstati64
+#define fileno _fileno
+#define strdup _strdup
+#endif
#define F_OK 0
#define OPEN_RDWR (_O_RDWR | _O_BINARY)
#define OPEN_CREAT (_O_CREAT | _O_BINARY)
@@ -84,8 +115,11 @@
}
#endif
+#ifndef PATH_MAX
#define PATH_MAX MAX_PATH
+#endif
#define MAX_UINT64 -1
+
#define D64F "I64d"
#define U64F "I64u"
#define X64F "I64x"
@@ -102,7 +136,7 @@
#define LOG_INFO 6
#define LOG_DEBUG 7
-#if !__STDC__ && _INTEGRAL_MAX_BITS >= 64
+#if defined (__GNUC__) || (!__STDC__ && _INTEGRAL_MAX_BITS >= 64)
#define VAR_TO_FPOS(fpos, var) (fpos) = (var)
#define FPOS_TO_VAR(fpos, typed, var) (var) = (typed)(fpos)
#else
@@ -127,4 +161,18 @@
#define SIZEOF_BOOL 1
+#ifndef __GNUC__
+#ifndef _SS_PAD1SIZE
+struct sockaddr_storage {
+ unsigned short ss_family;
+ uint32_t ss_align;
+ char __ss_padding[128 - 2 * sizeof(uint32_t)];
+};
#endif
+#pragma warning(disable : 4244)
+#pragma warning(disable: 4996)
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+#define HAVE_INET_PTON 1
+#define HAVE_INET_NTOP 1
+#endif
+#endif
Added: trunk/pmplib/lib/gmi/contrib/mp4v2/win32/libmp4v2.lib
===================================================================
(Binary files differ)
Property changes on: trunk/pmplib/lib/gmi/contrib/mp4v2/win32/libmp4v2.lib
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Deleted: trunk/pmplib/lib/gmi/contrib/mp4v2/win32/libmp4v260.lib
===================================================================
(Binary files differ)
Deleted: trunk/pmplib/lib/gmi/contrib/mp4v2/win32/libmp4v260d.lib
===================================================================
(Binary files differ)
Added: trunk/pmplib/lib/gmi/contrib/mp4v2/win32/libmp4v2d.lib
===================================================================
(Binary files differ)
Property changes on: trunk/pmplib/lib/gmi/contrib/mp4v2/win32/libmp4v2d.lib
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: trunk/pmplib/lib/gmi/gmi.vcproj
===================================================================
--- trunk/pmplib/lib/gmi/gmi.vcproj 2007-09-24 03:34:31 UTC (rev 415)
+++ trunk/pmplib/lib/gmi/gmi.vcproj 2007-09-25 14:27:01 UTC (rev 416)
@@ -62,7 +62,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies=".\contrib\id3tag\win32\libid3tagd.lib .\contrib\id3tag\win32\zlibd.lib .\contrib\ogg\win32\ogg_static_d.lib .\contrib\vorbis\win32\vorbis_static_d.lib .\contrib\vorbis\win32\vorbisfile_static_d.lib .\contrib\mp4v2\win32\libmp4v260d.lib"
+ AdditionalDependencies=".\contrib\id3tag\win32\libid3tagd.lib .\contrib\id3tag\win32\zlibd.lib .\contrib\ogg\win32\ogg_static_d.lib .\contrib\vorbis\win32\vorbis_static_d.lib .\contrib\vorbis\win32\vorbisfile_static_d.lib .\contrib\mp4v2\win32\libmp4v2d.lib"
OutputFile="$(OutDir)/gmi.dll"
LinkIncremental="2"
GenerateDebugInformation="true"
@@ -140,7 +140,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies=".\contrib\id3tag\win32\libid3tag.lib .\contrib\id3tag\win32\zlib.lib .\contrib\ogg\win32\ogg_static.lib .\contrib\vorbis\win32\vorbis_static.lib .\contrib\vorbis\win32\vorbisfile_static.lib .\contrib\mp4v2\win32\libmp4v260.lib"
+ AdditionalDependencies=".\contrib\id3tag\win32\libid3tag.lib .\contrib\id3tag\win32\zlib.lib .\contrib\ogg\win32\ogg_static.lib .\contrib\vorbis\win32\vorbis_static.lib .\contrib\vorbis\win32\vorbisfile_static.lib .\contrib\mp4v2\win32\libmp4v2.lib"
OutputFile="$(OutDir)/gmi.dll"
LinkIncremental="1"
GenerateDebugInformation="true"
Modified: trunk/pmplib/lib/gmi/gmi_mp4v2.c
===================================================================
--- trunk/pmplib/lib/gmi/gmi_mp4v2.c 2007-09-24 03:34:31 UTC (rev 415)
+++ trunk/pmplib/lib/gmi/gmi_mp4v2.c 2007-09-25 14:27:01 UTC (rev 416)
@@ -105,6 +105,11 @@
info->artist = utf8dupucs2(value);
free(value);
}
+ if (MP4GetMetadataAlbumArtist(mp4file, &value) && value != NULL) {
+ ucs2free(info->album_artist);
+ info->album_artist = utf8dupucs2(value);
+ free(value);
+ }
if (MP4GetMetadataAlbum(mp4file, &value) && value != NULL) {
ucs2free(info->album);
info->album = utf8dupucs2(value);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|