[Helix-client-dev] CR: Extended support for iTunes meta-info in datatype projects
Petar Basic <[email protected]> Mon, 19 Oct 2009 18:33:50 +0200
| Newsgroups | gmane.comp.multimedia.helix.devel |
|---|---|
| Message-ID | <[email protected]> |
Modified by: pbasic at real.com
Date: 2009/10/19
Project: GMP MetaEditor (meta3gp.exe)
Synopsis:
Extended support for iTunes meta-info in datatype projects
Overview:
GMP MetaEditor tool must support both 3GPP and iTunes meta-info
flavors in MP4-based files. iTunes metadata boxes were only partially
supported in MP4 file-writer and so far unsupported in MP4
file-format. This CR adds support for standard iTunes tags minus the
Cover Art ('covr') tag which will be addressed separately.
The following iTunes tags are now supported:
Album Name (@alb)
Artist(@ART)
User Comment(@cmt)
Copyright (cprt)
Release Date (@day)
Pre-defined Genre (gnre)
User Genre (@gen)
Song Name (@nam)
Track Sub-Title (@st3)
Encoding Tool (@too)
Composer (@wrt)
Album Artist (aART)
Disc Compilation (cpil)
Disc Number (disk)
Grouping (@grp)
Lyrics (@lyr)
Content Rating (rtng)
Beats Per Minute (tmpo)
Track Number (@trkn)
File-writer takes into account common expectations of other software
packages and outputs atoms accordingly. For this reason, the length
of values in string atoms except @lyr is currently limited to 255
characters. UTF8 and UTF16BE output is fully supported except for
@lyr which must be in UTF8 format. Only year portion of @day atom is
read/written as the full date seems unimportant to most other software
(e.g. iTunes9 also allows input of the year part only).
Details:
1.) Fixed a bug in EncStrUtils::ConvertUTF8ToUTF16.
2.) Updated project dependencies in helix.bif.
3.) Added iTunes meta-flavor definition to ihxmetaeditor.h.
4.) Updated meta-info key defines in metainfokeys.h. The keys have
been split in several non-overlapping sets. Currently defined are
Generic set, iTunes specific set, 3GPP specific set. Key sets can be
combined where needed. Some aliases in specific sets have been
defined which reference keys in the generic set.
5.) Moved MetaInfo3GP utilities from meta3gp project into
common/util/metautil.cpp module. Renamed utility class to MetaInfo.
This class simplifies processing of meta-info properties in
file-headers, stream-headers, etc. It can also be used as a simpler
temporary C++-style container for meta-info values; export/import
to/from Helix IHXValues container is supported.
6.) Updated code in dtdriver/common/decoder, dtdriver/common/engine,
datatype/tools/metaeditor to use MetaInfo class utilities. All
available meta-info is now always transferred between headers in
FFDriver components.
7.) Metaeditor's source handler now transfers all available meta-info
properties between headers and leaves meta-info set/flavor filtering
to IHXMetaDataProcessor.
8.) Updated and refactored command line processing in meta3gp
executable project according to GMP MetaEditor specs. Both flavors of
meta-data (3GPP, iTunes) can be injected into the same media-file by
specifying the -metastyle switch multiple times.
9.) Merged MP4 atom handling improvements from 310Atlas:
A.) MP4 fileformat's atomizer had to be extended to handle
non-standard size (versioned) container atoms. Until now it was
assumed that each container has 8 byte header - e.g. 'meta' atom uses
12 bytes.
B.) MP4 fileformat has been extended with 'meta' and 'ID32'
definitions. ID32 Tags found at track level are handled by TrackInfo
manager and are inserted into the stream header of the corresponding
stream.
C.) Removed dead code (TypedChildIterator) in MP4 fileformat.
D.) MP4 filewriter has been extended with 'meta' and 'ID32'
definitions. Stream mixer outputs the ID3v2 tag to the following atom
path: /file/moov/meta/ID32.
E.) MP4 filewriter writes out the ID32 meta data as part of the moov
or trak meta box depending on the location (file or stream header) of
the ID32 blob.
10.) MP4 filewriter has been updated to respect MetaDataFlavor
configuration option and can therefore update both flavors of
meta-data into the same media-file. Added/extended iTunes atom
definitions and atom tree builder methods.
11.) MP4 fileformat has been updated to read iTunes meta tags.
Added/extended iTunes atom definitions and atom tree builder methods.
CreateQTAtom method now takes additional parameter specifying the
current tree root - this was needed because there is some overlap
among flavor atom names (3GPP gnre/iTunes gnre, 3GPP cprt/iTunes cprt,
3GPP rtng/iTunes rntg). The tree builder needs current root type to
decide the context of creation and to create an atom of the correct
class (iTunes or 3GPP). Since both flavors of metadata can now be
encountered inside a single media-file, some extraction method
prioritization has been implemented based on MajorBrand value. By
default, 3GPP info will overwrite iTunes info. In case of M4A brand,
iTunes info will overwrite 3GPP info. The reader is not subject to
artificial 255 characters limitation in iTunes strings; it also
tolerates various deviations from the iTMF spec where it is safe and
possible to do so.
Testing:
Verified that meta-info injected by GMP MetaEditor can be read with
other software (iTunes 9, AtomicParsley 0.9, CT metadata extractor
1.3). Verified that meta-info injected by other software can be read
with GMP MetaEditor.
Files Modified:
common/include/ihxmetaeditor.h
common/util/encstr.cpp
datatype/include/metainfokeys.h
datatype/common/util/metautil.cpp
datatype/common/util/pub/metautil.h
datatype/common/util/Umakefil
datatype/tools/dtdriver/common/Umakefil
datatype/tools/dtdriver/decoder/audio/Umakefil
datatype/tools/dtdriver/decoder/audio/adecoder.cpp
datatype/tools/dtdriver/decoder/video/Umakefil
datatype/tools/dtdriver/decoder/video/vdecoder.cpp
datatype/tools/dtdriver/decoder/video/vdepacker.cpp
datatype/tools/dtdriver/engine/pub/ffdriver.h
datatype/tools/dtdriver/engine/ffdriver.cpp
datatype/tools/dtdriver/engine/Umakefil
datatype/tools/dtdriver/apps/meta3gp/main.cpp
datatype/tools/dtdriver/apps/meta3gp/Umakefil_meta3gp
datatype/tools/metaeditor/srchandler.cpp
datatype/tools/metaeditor/srchandler.h
datatype/tools/metaeditor/Umakefil
datatype/mp4/fileformat/atomizer.cpp
datatype/mp4/fileformat/pub/atomizer.h
datatype/mp4/fileformat/qtatoms.cpp
datatype/mp4/fileformat/pub/qtatoms.h
datatype/mp4/fileformat/qtatmmgs.cpp
datatype/mp4/fileformat/pub/qtatmmgs.h
datatype/mp4/fileformat/qtffplin.cpp
datatype/mp4/fileformat/pub/qtffplin.h
datatype/mp4/fileformat/pub/qtbatom.h
datatype/mp4/fileformat/dllumakefil
datatype/mp4/fileformat/libumakefil
datatype/mp4/filewriter/3gpmeta.h
datatype/mp4/filewriter/3gpmeta.cpp
datatype/mp4/filewriter/mp4sm.h
datatype/mp4/filewriter/mp4sm.cpp
datatype/mp4/filewriter/m4amdatoms.h
datatype/mp4/filewriter/mp4atoms.h
Files Removed:
datatype/tools/metaeditor/metautil3gp.cpp
datatype/tools/metaeditor/pub/metautil3gp.h
datatype/tools/metaeditor/Umakefile_3gp_lib
datatype/tools/metaeditor/Umakefile_dll
Platforms and Profiles Affected:
All
Image Size and Heap Use impact:
Small increase
Platforms and Profiles Build Verified:
system id: win32-i386-vc7
profile: helix-client-all-defines
Platforms and Profiles Functionality Verified:
x86 Windows XP SP2
Branch:
HEAD
Copyright assignment:
I am a RealNetworks employee or contractor.
_______________________________________________
Helix-client-dev mailing list
[email protected]
http://lists.helixcommunity.org/mailman/listinfo/helix-client-dev
common_include.diff
(text/x-patch, 2.5 KB)
Index: ihxmetaeditor.h
===================================================================
RCS file: /cvsroot/common/include/ihxmetaeditor.h,v
retrieving revision 1.1
diff -d -H -w -U30 -r1.1 ihxmetaeditor.h
--- ihxmetaeditor.h 5 Nov 2007 21:32:45 -0000 1.1
+++ ihxmetaeditor.h 19 Oct 2009 12:39:01 -0000
@@ -58,62 +58,63 @@
#include "hxcomptr.h"
#include "hxsrcin.h"
/****************************************************************************
*
* Additional options (datatype-driver-chain):
*
* METADATAFLAVOR_OPTION_NAME - ULONG32, value must be one of METADATA_FLAVOR
* constants. Notifies components about the flavor of meta-data they are
* about to process.
*
* BLASTMETADATA_OPTION_NAME - ULONG32, if !=0, the meta-data incoming
* from the source will be erased before any new meta-data is added.
* Otherwise, new and existing meta-data will be merged.
*
*/
#define METADATAFLAVOR_OPTION_NAME "MetaDataFlavor"
#define BLASTMETADATA_OPTION_NAME "BlastMetaData"
/****************************************************************************
*
* Meta-data flavors:
* Used by meta-data source-handler and meta-data processors to
* extract/inject correct set of properties from/to file-header.
*
*/
typedef enum
{
- METADATA_FLAVOR_UNKNOWN = 0,
- METADATA_FLAVOR_3GP
+ METADATA_FLAVOR_3GPP = 0x00000010,
+ METADATA_FLAVOR_ITUNES = 0x00000100,
+ METADATA_FLAVOR_ALL = METADATA_FLAVOR_3GPP | METADATA_FLAVOR_ITUNES
} METADATA_FLAVOR;
/****************************************************************************
*
* Interface:
* IHXMetaDataProcessor
*
* Purpose:
* Used by IHXMetaDataSourceHandler to process meta-data. Clients
* can implement this interface if there is a need for special processing.
* Meta-data editor provides default processor implementation.
*
* IID_IHXMetaDataProcessor
* {241640A0-E73C-46a3-AA62-6C130BE884D6}
*
*/
DEFINE_GUID(IID_IHXMetaDataProcessor,
0x241640a0, 0xe73c, 0x46a3, 0xaa, 0x62, 0x6c, 0x13, 0x0b, 0xe8, 0x84, 0xd6);
#undef INTERFACE
#define INTERFACE IHXMetaDataProcessor
DECLARE_INTERFACE_(IHXMetaDataProcessor, IUnknown)
{
/****************************************************************************
* Method:
* IHXMetaDataProcessor::InitMetaDataProcessor()
* Purpose:
* Called to initialize MetaDataProcessor. May be called multiple times
common_util.diff
(text/x-patch, 2.2 KB)
Index: encstr.cpp
===================================================================
RCS file: /cvsroot/common/util/encstr.cpp,v
retrieving revision 1.5
diff -d -H -w -U30 -r1.5 encstr.cpp
--- encstr.cpp 29 Feb 2008 13:40:22 -0000 1.5
+++ encstr.cpp 19 Oct 2009 12:40:41 -0000
@@ -579,61 +579,62 @@
break;
}
memcpy(pszCopy + 2, psz, len);
}
}
return pszCopy;
}
char* EncStrUtils::ConvertUTF8ToUTF16(const char* psz, HXBOOL bBigEndian, HXBOOL bPrependBOM, UINT32 allocFlags)
{
if(!psz)
{
return 0;
}
UINT32 numConsumed = 0;
UINT32 numOutputed = 0;
if(::ConvertUTF8StringToUTF16String((const UINT8*)psz, MAX_UINT32, numConsumed,
0, 0, numOutputed, bBigEndian) < 0)
{
return 0; //conversion error
}
if(numOutputed)
{
if(bPrependBOM)
{
numOutputed += 1;
}
char* pszOut = EncStrUtils::Allocate(numOutputed * 2, allocFlags);
if(pszOut && ::ConvertUTF8StringToUTF16String((const UINT8*)psz, MAX_UINT32, numConsumed,
(UINT16*)(bPrependBOM ? pszOut + 2 : pszOut),
- numOutputed - 1, numOutputed, bBigEndian) < 0)
+ (bPrependBOM ? numOutputed - 1 : numOutputed),
+ numOutputed, bBigEndian) < 0)
{
EncStrUtils::Deallocate(pszOut, allocFlags);
return 0; //conversion error
}
if(bPrependBOM)
{
EncStrUtils::WriteUTF16BOM(pszOut, bBigEndian);
}
return pszOut;
}
return 0;
}
char* EncStrUtils::ConvertUTF16ToUTF8(const char* psz, HX_TEXT_ENCODING_TYPE enc, UINT32 allocFlags)
{
if(!psz)
{
return 0;
}
// check encoding
HXBOOL bBigEndian = TRUE;
switch(enc)
{
case HX_TEXT_ENCODING_TYPE_UTF16:
case HX_TEXT_ENCODING_TYPE_UTF16BE:
break;
case HX_TEXT_ENCODING_TYPE_UTF16LE:
bBigEndian = FALSE;
break;
datatype_common_util.diff
(text/x-patch, 65.9 KB)
Index: Umakefil
===================================================================
RCS file: /cvsroot/datatype/common/util/Umakefil,v
retrieving revision 1.14
diff -d -H -w -U30 -r1.14 Umakefil
--- Umakefil 14 Nov 2008 21:46:28 -0000 1.14
+++ Umakefil 19 Oct 2009 12:45:27 -0000
@@ -30,51 +30,52 @@
# use your version of this file under the terms of any one of the
# RPSL, the RCSL or the GPL.
#
# This file is part of the Helix DNA Technology. RealNetworks is the
# developer of the Original Code and owns the copyrights in the
# portions it created.
#
# This file, and the files included with this file, is distributed
# and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
# KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
# ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
# ENJOYMENT OR NON-INFRINGEMENT.
#
# Technology Compatibility Kit Test Suite(s) Location:
# http://www.helixcommunity.org/content/tck
#
# Contributor(s):
#
# ***** END LICENSE BLOCK *****
#
UmakefileVersion(2,1)
project.AddModuleIncludes( "common/include",
"common/system/pub",
"common/dbgtool/pub",
"common/util/pub",
"common/container/pub",
"common/runtime/pub",
- "common/log/logutil/pub")
+ "common/log/logutil/pub",
+ "datatype/include")
project.AddSources("bitstream.cpp",
"bitpack.cpp",
"riff.cpp",
"deintl.cpp",
"invtelec.cpp",
"resize.cpp",
"pyldparse.cpp",
"pxtransp.cpp",
"metautil.cpp",
"sspayld.cpp",
"getreqhdr.cpp",
"adjtime.cpp")
if "HELIX_FEATURE_STATS" in project.defines:
project.AddSources('rendstats.cpp')
LibraryTarget('dtutillib')
DependTarget()
Index: metautil.cpp
===================================================================
RCS file: /cvsroot/datatype/common/util/metautil.cpp,v
retrieving revision 1.7
diff -d -H -w -U30 -r1.7 metautil.cpp
--- metautil.cpp 6 Jul 2007 22:00:23 -0000 1.7
+++ metautil.cpp 19 Oct 2009 12:45:29 -0000
@@ -26,60 +26,65 @@
* or RCSL, indicate your decision by deleting the provisions above
* and replace them with the notice and other provisions required by
* the GPL. 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
* RPSL, the RCSL or the GPL.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the
* portions it created.
*
* This file, and the files included with this file, is distributed
* and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
* ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "hlxclib/string.h"
#include "hxtypes.h"
#include "hxcom.h"
#include "ihxpckts.h"
#include "hxfiles.h"
#include "hxccf.h"
+#include "iso639.h"
+#include "proptools.h"
+
+#include "metautil.h"
+
HX_RESULT CheckMetaInfoRequest(IHXRequest* pRequest,
IHXCommonClassFactory* pFactory,
REF(HXBOOL) rbAcceptMetaInfoPresent,
REF(HXBOOL) rbAllMetaInfoRequested,
REF(IHXValues*) rpRequestedMetaInfo)
{
HX_RESULT retVal = HXR_FAIL;
if (pRequest && pFactory)
{
IHXValues* pReqHdrs = NULL;
retVal = pRequest->GetRequestHeaders(pReqHdrs);
if (SUCCEEDED(retVal) && pReqHdrs)
{
IHXBuffer* pBuffer = NULL;
pReqHdrs->GetPropertyCString("AcceptMetaInfo", pBuffer);
if (pBuffer)
{
// "AcceptMetaInfo" is present
rbAcceptMetaInfoPresent = TRUE;
// Get the string to examine
const char* pszStr = (const char*) pBuffer->GetBuffer();
// Check if it's "*"
if (!strcmp(pszStr, "*"))
{
// All meta info is requested
rbAllMetaInfoRequested = TRUE;
rpRequestedMetaInfo = NULL;
}
@@ -119,30 +124,1321 @@
}
else
{
// AcceptMetaInfo was present, but there
// weren't any valid strings in it, so we fail
retVal = HXR_FAIL;
}
// Release the values
HX_RELEASE(pInfo);
}
}
else
{
// "AcceptMetaInfo" is not present in
// the request headers
rbAcceptMetaInfoPresent = FALSE;
}
HX_RELEASE(pBuffer);
}
else
{
// No request headers
rbAcceptMetaInfoPresent = FALSE;
}
HX_RELEASE(pReqHdrs);
}
return retVal;
}
+const char* const g_ID3_genres[] = {
+ "Blues", //0
+ "Classic Rock",
+ "Country",
+ "Dance",
+ "Disco",
+ "Funk", //5
+ "Grunge",
+ "Hip-Hop",
+ "Jazz",
+ "Metal",
+ "New Age", //10
+ "Oldies",
+ "Other",
+ "Pop",
+ "R&B",
+ "Rap", //15
+ "Reggae",
+ "Rock",
+ "Techno",
+ "Industrial",
+ "Alternative", //20
+ "Ska",
+ "Death Metal",
+ "Pranks",
+ "Soundtrack",
+ "Euro-Techno", //25
+ "Ambient",
+ "Trip-Hop",
+ "Vocal",
+ "Jazz+Funk",
+ "Fusion", //30
+ "Trance",
+ "Classical",
+ "Instrumental",
+ "Acid",
+ "House", //35
+ "Game",
+ "Sound Clip",
+ "Gospel",
+ "Noise",
+ "AlternRock", //40
+ "Bass",
+ "Soul",
+ "Punk",
+ "Space",
+ "Meditative", //45
+ "Instrumental Pop",
+ "Instrumental Rock",
+ "Ethnic",
+ "Gothic",
+ "Darkwave", //50
+ "Techno-Industrial",
+ "Electronic",
+ "Pop-Folk",
+ "Eurodance",
+ "Dream", //55
+ "Southern Rock",
+ "Comedy",
+ "Cult",
+ "Gangsta",
+ "Top 40", //60
+ "Christian Rap",
+ "Pop/Funk",
+ "Jungle",
+ "Native American",
+ "Cabaret", //65
+ "New Wave",
+ "Psychadelic",
+ "Rave",
+ "Showtunes",
+ "Trailer", //70
+ "Lo-Fi",
+ "Tribal",
+ "Acid Punk",
+ "Acid Jazz",
+ "Polka", //75
+ "Retro",
+ "Musical",
+ "Rock & Roll",
+ "Hard Rock",
+
+ // Winamp extensions
+ "Folk", //80
+ "Folk-Rock",
+ "National Folk",
+ "Swing",
+ "Fast Fusion",
+ "Bebob", //85
+ "Latin",
+ "Revival",
+ "Celtic",
+ "Bluegrass",
+ "Avantgarde", //90
+ "Gothic Rock",
+ "Progressive Rock",
+ "Psychedelic Rock",
+ "Symphonic Rock",
+ "Slow Rock", //95
+ "Big Band",
+ "Chorus",
+ "Easy Listening",
+ "Acoustic",
+ "Humour", //100
+ "Speech",
+ "Chanson",
+ "Opera",
+ "Chamber Music",
+ "Sonata", //105
+ "Symphony",
+ "Booty Bass",
+ "Primus",
+ "Porn Groove",
+ "Satire", //110
+ "Slow Jam",
+ "Club",
+ "Tango",
+ "Samba",
+ "Folklore", //115
+ "Ballad",
+ "Power Ballad",
+ "Rhythmic Soul",
+ "Freestyle",
+ "Duet", //120
+ "Punk Rock",
+ "Drum Solo",
+ "Acapella",
+ "Euro-House",
+ "Dance Hall" //125
+};
+
+const UINT32 g_ID3_genre_count = sizeof(g_ID3_genres) / sizeof(const char*);
+
+HXBOOL ID3Tools::GenreOrdinalFromName(const char* szGenreName, UINT8& outOrdinal, HXBOOL bCaseSensitiveSearch)
+{
+ int(*pfnStrCmp)(const char*, const char*) = bCaseSensitiveSearch ? strcmp : strcmpi;
+
+ for(UINT8 iOrd = 0; iOrd < g_ID3_genre_count; iOrd++)
+ {
+ if(!pfnStrCmp(g_ID3_genres[iOrd], szGenreName))
+ {
+ outOrdinal = iOrd;
+ return TRUE;
+ }
+ }
+
+ // not found
+ return FALSE;
+}
+
+const char* ID3Tools::GenreNameFromOrdinal(UINT8 uGenreOrdinal)
+{
+ return (uGenreOrdinal < g_ID3_genre_count) ? g_ID3_genres[uGenreOrdinal] : 0;
+}
+
+ULONG32 ID3Tools::ParseGenreNameList(CHXPtrArray& genreOrdinals, const char* szGenreNames,
+ HXBOOL bCaseSensitiveSearch, char separator, HXBOOL bTrimWhitespace)
+{
+ if(!szGenreNames)
+ {
+ return 0;
+ }
+
+ ULONG32 genreCount = 0;
+ CHXString sVal = szGenreNames;
+
+ while(!sVal.IsEmpty())
+ {
+ INT32 pos = sVal.Find(',');
+
+ CHXString sEntry = (pos < 0) ? sVal : ((pos == 0) ? CHXString() : sVal.Left(pos));
+ if(bTrimWhitespace)
+ {
+ sEntry.TrimLeft();
+ sEntry.TrimRight();
+ }
+
+ if(!sEntry.IsEmpty())
+ {
+ UINT8 uGenreOrdinal = 0;
+ if(GenreOrdinalFromName((const char*)sEntry, uGenreOrdinal, bCaseSensitiveSearch))
+ {
+ genreCount++;
+ genreOrdinals.Add((void*)ULONG32(uGenreOrdinal));
+ }
+ }
+
+ // next entry
+ sVal = (pos >= 0) ? sVal.Right(sVal.GetLength() - pos - 1) : CHXString();
+ }
+
+ return genreCount;
+}
+
+void ID3Tools::MakeGenreNameList(CHXString& outGenreNames, const CHXPtrArray& genreOrdinals, const char* szSeparator)
+{
+ if(!szSeparator || !szSeparator[0])
+ {
+ szSeparator = ",";
+ }
+
+ for(ULONG32 i = 0; i < genreOrdinals.GetSize(); i++)
+ {
+ UINT8 uGenreOrdinal = (UINT8)(ULONG32)genreOrdinals.GetAt(i);
+
+ const char* szID3GenreName = GenreNameFromOrdinal(uGenreOrdinal);
+ if(szID3GenreName && szID3GenreName[0])
+ {
+ if(!outGenreNames.IsEmpty())
+ {
+ outGenreNames += szSeparator;
+ }
+ outGenreNames += szID3GenreName;
+ }
+ }
+}
+
+HX_RESULT MetaInfo::RemoveKeywordProperties(IHXValues* pValues)
+{
+ HX_RESULT retVal = HXR_OK;
+
+ ULONG32 ulKeywordCount = 0;
+ if(PropTools::CopyPropertyULONG32(ulKeywordCount, pValues, _3GPP_META_INFO_KEYWORD_COUNT_KEY))
+ {
+ PropTools::RemovePropertyULONG32(retVal, pValues, _3GPP_META_INFO_KEYWORD_COUNT_KEY);
+
+ for(ULONG32 i = 0; i < ulKeywordCount; i++)
+ {
+ char key[128];
+ sprintf(key, _3GPP_META_INFO_KEYWORD_KEY, int(i));
+ PropTools::RemovePropertyBuffer(retVal, pValues, key);
+ }
+ }
+ return retVal;
+}
+
+HX_RESULT MetaInfo::CopyKeywordProperties(IHXValues* dst, IHXValues* src, HXBOOL bBlast)
+{
+ HX_RESULT retVal = HXR_OK;
+
+ ULONG32 ulKeywordCount = 0;
+ if(PropTools::CopyPropertyULONG32(ulKeywordCount, src, _3GPP_META_INFO_KEYWORD_COUNT_KEY))
+ {
+ retVal = RemoveKeywordProperties(dst);
+
+ PropTools::CopyPropertyULONG32(retVal, dst, src, _3GPP_META_INFO_KEYWORD_COUNT_KEY, TRUE);
+ for(ULONG32 i = 0; i < ulKeywordCount; i++)
+ {
+ if(SUCCEEDED(retVal))
+ {
+ char key[128];
+ sprintf(key, _3GPP_META_INFO_KEYWORD_KEY, int(i));
+ PropTools::CopyPropertyBuffer(retVal, dst, src, key, TRUE);
+ }
+ }
+ }
+ else if(bBlast)
+ {
+ retVal = RemoveKeywordProperties(dst);
+ }
+ return retVal;
+}
+
+HX_RESULT MetaInfo::RemoveAllProperties(IHXValues* pValues, ULONG32 metaInfoSetFlags)
+{
+ HX_RESULT retVal = HXR_OK;
+
+ // Generic
+ if(metaInfoSetFlags & METAINFO_SET_GENERIC)
+ {
+ PropTools::RemovePropertyBuffer(retVal, pValues, _GENERIC_META_INFO_TITLE_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _GENERIC_META_INFO_COMPOSER_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _GENERIC_META_INFO_COPYRIGHT_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _GENERIC_META_INFO_COMMENT_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _GENERIC_META_INFO_ARTIST_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _GENERIC_META_INFO_GENRE_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _GENERIC_META_INFO_ALBUM_KEY);
+
+ PropTools::RemovePropertyULONG32(retVal, pValues, _GENERIC_META_INFO_TRACK_NUMBER_KEY);
+ PropTools::RemovePropertyULONG32(retVal, pValues, _GENERIC_META_INFO_RECORDING_YEAR_KEY);
+ }
+
+ // iTunes
+ if(metaInfoSetFlags & METAINFO_SET_ITUNES_SPECIFIC)
+ {
+ PropTools::RemovePropertyBuffer(retVal, pValues, _ITUNES_META_INFO_TRACK_SUBTITLE_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _ITUNES_META_INFO_GENERATOR_TOOL_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _ITUNES_META_INFO_GROUPING_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _ITUNES_META_INFO_ALBUM_ARTIST_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _ITUNES_META_INFO_LYRICS_KEY);
+
+ PropTools::RemovePropertyULONG32(retVal, pValues, _ITUNES_META_INFO_BEATS_PER_MINUTE_KEY);
+ PropTools::RemovePropertyULONG32(retVal, pValues, _ITUNES_META_INFO_PART_OF_COMPILATION_KEY);
+ PropTools::RemovePropertyULONG32(retVal, pValues, _ITUNES_META_INFO_EXPLICIT_CONTENT_KEY);
+ PropTools::RemovePropertyULONG32(retVal, pValues, _ITUNES_META_INFO_TRACK_COUNT_KEY);
+ PropTools::RemovePropertyULONG32(retVal, pValues, _ITUNES_META_INFO_DISC_NUMBER_KEY);
+ PropTools::RemovePropertyULONG32(retVal, pValues, _ITUNES_META_INFO_DISC_COUNT_KEY);
+ }
+
+ // 3GPP
+ if(metaInfoSetFlags & METAINFO_SET_3GPP_SPECIFIC)
+ {
+ PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_GLOBAL_LANGUAGE_ENCODING_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_RATING_ENTITY_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_RATING_CRITERIA_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_RATING_INFO_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_CLASSIFICATION_ENTITY_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_CLASSIFICATION_INFO_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_LOCATION_NAME_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_LOCATION_ASTRONOMICAL_BODY_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_LOCATION_ADDITIONAL_NOTES_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_LOCATION_LONGITUDE_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_LOCATION_LATITUDE_KEY);
+ PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_LOCATION_ALTITUDE_KEY);
+
+ PropTools::RemovePropertyULONG32(retVal, pValues, _3GPP_META_INFO_CLASSIFICATION_TABLE_KEY);
+ PropTools::RemovePropertyULONG32(retVal, pValues, _3GPP_META_INFO_LOCATION_ROLE_KEY);
+
+ // keywords
+ if(SUCCEEDED(retVal))
+ {
+ retVal = RemoveKeywordProperties(pValues);
+ }
+ }
+
+ return retVal;
+}
+
+HX_RESULT MetaInfo::CopyAllProperties(IHXValues* dst, IHXValues* src, ULONG32 metaInfoSetFlags, HXBOOL bBlast)
+{
+ HX_RESULT retVal = HXR_OK;
+
+ // Generic
+ if(metaInfoSetFlags & METAINFO_SET_GENERIC)
+ {
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _GENERIC_META_INFO_TITLE_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _GENERIC_META_INFO_COMPOSER_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _GENERIC_META_INFO_COPYRIGHT_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _GENERIC_META_INFO_COMMENT_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _GENERIC_META_INFO_ARTIST_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _GENERIC_META_INFO_GENRE_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _GENERIC_META_INFO_ALBUM_KEY, bBlast);
+
+ PropTools::CopyPropertyULONG32(retVal, dst, src, _GENERIC_META_INFO_TRACK_NUMBER_KEY, bBlast);
+ PropTools::CopyPropertyULONG32(retVal, dst, src, _GENERIC_META_INFO_RECORDING_YEAR_KEY, bBlast);
+ }
+
+ // iTunes
+ if(metaInfoSetFlags & METAINFO_SET_ITUNES_SPECIFIC)
+ {
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _ITUNES_META_INFO_TRACK_SUBTITLE_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _ITUNES_META_INFO_GENERATOR_TOOL_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _ITUNES_META_INFO_GROUPING_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _ITUNES_META_INFO_ALBUM_ARTIST_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _ITUNES_META_INFO_LYRICS_KEY, bBlast);
+
+ PropTools::CopyPropertyULONG32(retVal, dst, src, _ITUNES_META_INFO_BEATS_PER_MINUTE_KEY, bBlast);
+ PropTools::CopyPropertyULONG32(retVal, dst, src, _ITUNES_META_INFO_PART_OF_COMPILATION_KEY, bBlast);
+ PropTools::CopyPropertyULONG32(retVal, dst, src, _ITUNES_META_INFO_EXPLICIT_CONTENT_KEY, bBlast);
+ PropTools::CopyPropertyULONG32(retVal, dst, src, _ITUNES_META_INFO_TRACK_COUNT_KEY, bBlast);
+ PropTools::CopyPropertyULONG32(retVal, dst, src, _ITUNES_META_INFO_DISC_NUMBER_KEY, bBlast);
+ PropTools::CopyPropertyULONG32(retVal, dst, src, _ITUNES_META_INFO_DISC_COUNT_KEY, bBlast);
+ }
+
+ // 3GPP
+ if(metaInfoSetFlags & METAINFO_SET_3GPP_SPECIFIC)
+ {
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_GLOBAL_LANGUAGE_ENCODING_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_RATING_ENTITY_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_RATING_CRITERIA_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_RATING_INFO_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_CLASSIFICATION_ENTITY_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_CLASSIFICATION_INFO_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_LOCATION_NAME_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_LOCATION_ASTRONOMICAL_BODY_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_LOCATION_ADDITIONAL_NOTES_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_LOCATION_LONGITUDE_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_LOCATION_LATITUDE_KEY, bBlast);
+ PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_LOCATION_ALTITUDE_KEY, bBlast);
+
+ PropTools::CopyPropertyULONG32(retVal, dst, src, _3GPP_META_INFO_CLASSIFICATION_TABLE_KEY, bBlast);
+ PropTools::CopyPropertyULONG32(retVal, dst, src, _3GPP_META_INFO_LOCATION_ROLE_KEY, bBlast);
+
+ // keywords
+ if(SUCCEEDED(retVal))
+ {
+ retVal = CopyKeywordProperties(dst, src, bBlast);
+ }
+ }
+
+ return retVal;
+}
+
+ULONG32 MetaInfo::GetSetsFromFlavors(ULONG32 metaFlavorFlags)
+{
+ ULONG32 metaInfoSets = 0;
+
+ if(metaFlavorFlags & METADATA_FLAVOR_3GPP)
+ {
+ metaInfoSets |= METAINFO_SET_3GPP_ALL;
+ }
+
+ if(metaFlavorFlags & METADATA_FLAVOR_ITUNES)
+ {
+ metaInfoSets |= METAINFO_SET_ITUNES_ALL;
+ }
+
+ return metaInfoSets;
+}
+
+CHXString MetaInfo::GetFlavorName(METADATA_FLAVOR flavor)
+{
+ switch(flavor)
+ {
+ case METADATA_FLAVOR_3GPP:
+ return "3GPP";
+
+ case METADATA_FLAVOR_ITUNES:
+ return "iTunes";
+ }
+ return "UNKNOWN";
+}
+
+CHXString MetaInfo::GetFlavorNames(ULONG32 metaFlavorFlags)
+{
+ const METADATA_FLAVOR allFlavors[] = { METADATA_FLAVOR_3GPP, METADATA_FLAVOR_ITUNES };
+
+ CHXString s;
+ for(int i = 0; i < (sizeof(allFlavors) / sizeof(METADATA_FLAVOR)); i++)
+ {
+ if(metaFlavorFlags & allFlavors[i])
+ {
+ if(!s.IsEmpty())
+ {
+ s += ", ";
+ }
+ s += GetFlavorName(allFlavors[i]);
+ }
+ }
+
+ return s;
+}
+
+ULONG32 MetaInfo::GetSetsWhichSupportItem(eStringMetaItem itemName)
+{
+ switch(itemName)
+ {
+ case StringMetaItem_Title:
+ case StringMetaItem_Artist:
+ case StringMetaItem_Album:
+ case StringMetaItem_Genre:
+ case StringMetaItem_Composer:
+ case StringMetaItem_Comment:
+ case StringMetaItem_Copyright:
+ return METAINFO_SET_GENERIC;
+
+ case StringMetaItem_TrackSubtitle:
+ case StringMetaItem_GeneratorTool:
+ case StringMetaItem_Grouping:
+ case StringMetaItem_AlbumArtist:
+ case StringMetaItem_Lyrics:
+ return METAINFO_SET_ITUNES_SPECIFIC;
+
+ case StringMetaItem_GlobalLanguageEncoding:
+ case StringMetaItem_RatingEntity:
+ case StringMetaItem_RatingCriteria:
+ case StringMetaItem_RatingInfo:
+ case StringMetaItem_ClassificationEntity:
+ case StringMetaItem_ClassificationInfo:
+ case StringMetaItem_LocationName:
+ case StringMetaItem_LocationAstronomicalBody:
+ case StringMetaItem_LocationAdditionalNotes:
+ case StringMetaItem_LocationLongitude:
+ case StringMetaItem_LocationLatitude:
+ case StringMetaItem_LocationAltitude:
+ case StringMetaItem_Keywords:
+ return METAINFO_SET_3GPP_SPECIFIC;
+ }
+ return 0;
+}
+
+ULONG32 MetaInfo::GetFlavorsWhichSupportItem(eStringMetaItem itemName)
+{
+ switch(itemName)
+ {
+ case StringMetaItem_Title:
+ case StringMetaItem_Artist:
+ case StringMetaItem_Album:
+ case StringMetaItem_Genre:
+ case StringMetaItem_Composer:
+ case StringMetaItem_Comment:
+ case StringMetaItem_Copyright:
+ return (METADATA_FLAVOR_3GPP | METADATA_FLAVOR_ITUNES);
+
+ case StringMetaItem_TrackSubtitle:
+ case StringMetaItem_GeneratorTool:
+ case StringMetaItem_Grouping:
+ case StringMetaItem_AlbumArtist:
+ case StringMetaItem_Lyrics:
+ return METADATA_FLAVOR_ITUNES;
+
+ case StringMetaItem_GlobalLanguageEncoding:
+ case StringMetaItem_RatingEntity:
+ case StringMetaItem_RatingCriteria:
+ case StringMetaItem_RatingInfo:
+ case StringMetaItem_ClassificationEntity:
+ case StringMetaItem_ClassificationInfo:
+ case StringMetaItem_LocationName:
+ case StringMetaItem_LocationAstronomicalBody:
+ case StringMetaItem_LocationAdditionalNotes:
+ case StringMetaItem_LocationLongitude:
+ case StringMetaItem_LocationLatitude:
+ case StringMetaItem_LocationAltitude:
+ case StringMetaItem_Keywords:
+ return METADATA_FLAVOR_3GPP;
+ }
+ return 0;
+}
+
+HXBOOL MetaInfo::IsItemValueValidForFlavors(eStringMetaItem itemName, const EncodedString& val, ULONG32 metaFlavorFlags)
+{
+ switch(itemName)
+ {
+ case StringMetaItem_Title:
+ case StringMetaItem_Artist:
+ case StringMetaItem_Album:
+ case StringMetaItem_Genre:
+ case StringMetaItem_Composer:
+ case StringMetaItem_Comment:
+ case StringMetaItem_Copyright:
+ case StringMetaItem_TrackSubtitle:
+ case StringMetaItem_GeneratorTool:
+ case StringMetaItem_Grouping:
+ case StringMetaItem_AlbumArtist:
+ // iTunes have 255 character limit for all string properties except Lyrics
+ return (metaFlavorFlags & METADATA_FLAVOR_ITUNES) ? (val.GetByteLength() <= 255) : TRUE;
+
+ case StringMetaItem_Keywords:
+ // 3GPP has 255 characters limit for Keywords
+ return (val.GetByteLength() <= 255);
+ }
+ return TRUE;
+}
+
+ULONG32 MetaInfo::GetSetsWhichSupportItem(eUlongMetaItem itemName)
+{
+ switch(itemName)
+ {
+ case UlongMetaItem_TrackNumber:
+ case UlongMetaItem_RecordingYear:
+ return METAINFO_SET_GENERIC;
+
+ case UlongMetaItem_BeatsPerMinute:
+ case UlongMetaItem_PartOfCompilation:
+ case UlongMetaItem_ExplicitContent:
+ case UlongMetaItem_TrackCount:
+ case UlongMetaItem_DiscNumber:
+ case UlongMetaItem_DiscCount:
+ return METAINFO_SET_ITUNES_SPECIFIC;
+
+ case UlongMetaItem_ClassificationTable:
+ case UlongMetaItem_LocationRole:
+ return METAINFO_SET_3GPP_SPECIFIC;
+ }
+ return 0;
+}
+
+ULONG32 MetaInfo::GetFlavorsWhichSupportItem(eUlongMetaItem itemName)
+{
+ switch(itemName)
+ {
+ case UlongMetaItem_TrackNumber:
+ case UlongMetaItem_RecordingYear:
+ return (METADATA_FLAVOR_3GPP | METADATA_FLAVOR_ITUNES);
+
+ case UlongMetaItem_BeatsPerMinute:
+ case UlongMetaItem_PartOfCompilation:
+ case UlongMetaItem_ExplicitContent:
+ case UlongMetaItem_TrackCount:
+ case UlongMetaItem_DiscNumber:
+ case UlongMetaItem_DiscCount:
+ return METADATA_FLAVOR_ITUNES;
+
+ case UlongMetaItem_ClassificationTable:
+ case UlongMetaItem_LocationRole:
+ return METADATA_FLAVOR_3GPP;
+ }
+ return 0;
+}
+
+HXBOOL MetaInfo::IsItemValueValidForFlavors(eUlongMetaItem itemName, ULONG32 val, ULONG32 metaFlavorFlags)
+{
+ switch(itemName)
+ {
+ case UlongMetaItem_TrackNumber:
+ {
+ HXBOOL bInRange = TRUE;
+ if(metaFlavorFlags & METADATA_FLAVOR_ITUNES)
+ {
+ bInRange = bInRange && IsInRange16(val);
+ }
+ if(metaFlavorFlags & METADATA_FLAVOR_3GPP)
+ {
+ bInRange = bInRange && IsInRange8(val);
+ }
+ return metaFlavorFlags ? bInRange : FALSE;
+ }
+
+ case UlongMetaItem_RecordingYear:
+ {
+ HXBOOL bInRange = TRUE;
+ if(metaFlavorFlags & METADATA_FLAVOR_ITUNES)
+ {
+ bInRange = bInRange && IsInRange(val, 0, 9999);
+ }
+ if(metaFlavorFlags & METADATA_FLAVOR_3GPP)
+ {
+ bInRange = bInRange && IsInRange16(val);
+ }
+ return metaFlavorFlags ? bInRange : FALSE;
+ }
+
+ case UlongMetaItem_PartOfCompilation:
+ case UlongMetaItem_ExplicitContent:
+ {
+ if(metaFlavorFlags & METADATA_FLAVOR_ITUNES)
+ {
+ return IsInRangeBoolean(val);
+ }
+ return FALSE;
+ }
+
+ case UlongMetaItem_TrackCount:
+ case UlongMetaItem_DiscNumber:
+ case UlongMetaItem_DiscCount:
+ {
+ if(metaFlavorFlags & METADATA_FLAVOR_ITUNES)
+ {
+ return IsInRange16(val);
+ }
+ return FALSE;
+ }
+
+ case UlongMetaItem_ClassificationTable:
+ {
+ if(metaFlavorFlags & METADATA_FLAVOR_3GPP)
+ {
+ return IsInRange16(val);
+ }
+ return FALSE;
+ }
+
+ case UlongMetaItem_LocationRole:
+ {
+ if(metaFlavorFlags & METADATA_FLAVOR_3GPP)
+ {
+ return IsInRange8(val);
+ }
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+MetaInfo::MetaInfo()
+{
+ Clear();
+}
+
+MetaInfo::~MetaInfo()
+{
+ ClearKeywords();
+}
+
+MetaInfo::MetaInfo(const MetaInfo& rhs)
+{
+ *this = rhs;
+}
+
+MetaInfo& MetaInfo::operator=(const MetaInfo& rhs)
+{
+ Clear();
+ UpdateItems(rhs);
+ return *this;
+}
+
+void MetaInfo::Dump(ULONG32 metaInfoSetFlags)
+{
+ // Generic
+ if(metaInfoSetFlags & METAINFO_SET_GENERIC)
+ {
+ Dump(_GENERIC_META_INFO_TITLE_KEY, m_stringItems[StringMetaItem_Title]);
+ Dump(_GENERIC_META_INFO_COMPOSER_KEY, m_stringItems[StringMetaItem_Composer]);
+ Dump(_GENERIC_META_INFO_COPYRIGHT_KEY, m_stringItems[StringMetaItem_Copyright]);
+ Dump(_GENERIC_META_INFO_COMMENT_KEY, m_stringItems[StringMetaItem_Comment]);
+ Dump(_GENERIC_META_INFO_ARTIST_KEY, m_stringItems[StringMetaItem_Artist]);
+ Dump(_GENERIC_META_INFO_GENRE_KEY, m_stringItems[StringMetaItem_Genre]);
+ Dump(_GENERIC_META_INFO_ALBUM_KEY, m_stringItems[StringMetaItem_Album]);
+
+ Dump(_GENERIC_META_INFO_TRACK_NUMBER_KEY, m_ulongItems[UlongMetaItem_TrackNumber],
+ m_ulongItemValidFlags[UlongMetaItem_TrackNumber]);
+ Dump(_GENERIC_META_INFO_RECORDING_YEAR_KEY, m_ulongItems[UlongMetaItem_RecordingYear],
+ m_ulongItemValidFlags[UlongMetaItem_RecordingYear]);
+ }
+
+ // iTunes
+ if(metaInfoSetFlags & METAINFO_SET_ITUNES_SPECIFIC)
+ {
+ Dump(_ITUNES_META_INFO_TRACK_SUBTITLE_KEY, m_stringItems[StringMetaItem_TrackSubtitle]);
+ Dump(_ITUNES_META_INFO_GENERATOR_TOOL_KEY, m_stringItems[StringMetaItem_GeneratorTool]);
+ Dump(_ITUNES_META_INFO_GROUPING_KEY, m_stringItems[StringMetaItem_Grouping]);
+ Dump(_ITUNES_META_INFO_ALBUM_ARTIST_KEY, m_stringItems[StringMetaItem_AlbumArtist]);
+ Dump(_ITUNES_META_INFO_LYRICS_KEY, m_stringItems[StringMetaItem_Lyrics]);
+ Dump(_ITUNES_META_INFO_BEATS_PER_MINUTE_KEY, m_ulongItems[UlongMetaItem_BeatsPerMinute],
+ m_ulongItemValidFlags[UlongMetaItem_BeatsPerMinute]);
+ Dump(_ITUNES_META_INFO_PART_OF_COMPILATION_KEY, m_ulongItems[UlongMetaItem_PartOfCompilation],
+ m_ulongItemValidFlags[UlongMetaItem_PartOfCompilation]);
+ Dump(_ITUNES_META_INFO_EXPLICIT_CONTENT_KEY, m_ulongItems[UlongMetaItem_ExplicitContent],
+ m_ulongItemValidFlags[UlongMetaItem_ExplicitContent]);
+ Dump(_ITUNES_META_INFO_TRACK_COUNT_KEY, m_ulongItems[UlongMetaItem_TrackCount],
+ m_ulongItemValidFlags[UlongMetaItem_TrackCount]);
+ Dump(_ITUNES_META_INFO_DISC_NUMBER_KEY, m_ulongItems[UlongMetaItem_DiscNumber],
+ m_ulongItemValidFlags[UlongMetaItem_DiscNumber]);
+ Dump(_ITUNES_META_INFO_DISC_COUNT_KEY, m_ulongItems[UlongMetaItem_DiscCount],
+ m_ulongItemValidFlags[UlongMetaItem_DiscCount]);
+ }
+
+ // 3GPP
+ if(metaInfoSetFlags & METAINFO_SET_3GPP_SPECIFIC)
+ {
+ Dump(_3GPP_META_INFO_GLOBAL_LANGUAGE_ENCODING_KEY, m_stringItems[StringMetaItem_GlobalLanguageEncoding]);
+ Dump(_3GPP_META_INFO_RATING_ENTITY_KEY, m_stringItems[StringMetaItem_RatingEntity]);
+ Dump(_3GPP_META_INFO_RATING_CRITERIA_KEY, m_stringItems[StringMetaItem_RatingCriteria]);
+ Dump(_3GPP_META_INFO_RATING_INFO_KEY, m_stringItems[StringMetaItem_RatingInfo]);
+ Dump(_3GPP_META_INFO_CLASSIFICATION_ENTITY_KEY, m_stringItems[StringMetaItem_ClassificationEntity]);
+ Dump(_3GPP_META_INFO_CLASSIFICATION_TABLE_KEY, m_ulongItems[UlongMetaItem_ClassificationTable],
+ m_ulongItemValidFlags[UlongMetaItem_ClassificationTable]);
+ Dump(_3GPP_META_INFO_CLASSIFICATION_INFO_KEY, m_stringItems[StringMetaItem_ClassificationInfo]);
+ Dump(_3GPP_META_INFO_LOCATION_NAME_KEY, m_stringItems[StringMetaItem_LocationName]);
+ Dump(_3GPP_META_INFO_LOCATION_ASTRONOMICAL_BODY_KEY, m_stringItems[StringMetaItem_LocationAstronomicalBody]);
+ Dump(_3GPP_META_INFO_LOCATION_ADDITIONAL_NOTES_KEY, m_stringItems[StringMetaItem_LocationAdditionalNotes]);
+ Dump(_3GPP_META_INFO_LOCATION_ROLE_KEY, m_ulongItems[UlongMetaItem_LocationRole],
+ m_ulongItemValidFlags[UlongMetaItem_LocationRole]);
+ Dump(_3GPP_META_INFO_LOCATION_LONGITUDE_KEY, m_stringItems[StringMetaItem_LocationLongitude]);
+ Dump(_3GPP_META_INFO_LOCATION_LATITUDE_KEY, m_stringItems[StringMetaItem_LocationLatitude]);
+ Dump(_3GPP_META_INFO_LOCATION_ALTITUDE_KEY, m_stringItems[StringMetaItem_LocationAltitude]);
+
+ for(ULONG32 i = 0; i < GetKeywordCount(); i++)
+ {
+ printf(_3GPP_META_INFO_KEYWORD_KEY": ", int(i));
+ EncodedString kwd;
+ GetKeyword(i, kwd);
+ kwd.Dump();
+ printf("\n");
+ }
+ }
+}
+
+void MetaInfo::Clear()
+{
+ for(int iStrItem = StringMetaItem_StringItemBegin; iStrItem < StringMetaItem_StringItemEnd; iStrItem++)
+ {
+ m_stringItems[iStrItem].Clear();
+ }
+
+ ClearKeywords();
+
+ for(int iUlongItem = UlongMetaItem_UlongItemBegin; iUlongItem < UlongMetaItem_UlongItemEnd; iUlongItem++)
+ {
+ m_ulongItems[iUlongItem] = 0;
+ m_ulongItemValidFlags[iUlongItem] = FALSE;
+ }
+}
+
+void MetaInfo::ClearItems(ULONG32 metaInfoSetFlags)
+{
+ for(int iStrItem = StringMetaItem_StringItemBegin; iStrItem < StringMetaItem_StringItemEnd; iStrItem++)
+ {
+ if(IsItemSupportedByAnySet((eStringMetaItem)iStrItem, metaInfoSetFlags))
+ {
+ m_stringItems[iStrItem].Clear();
+ }
+ }
+
+ if(IsItemSupportedByAnySet(StringMetaItem_Keywords, metaInfoSetFlags))
+ {
+ ClearKeywords();
+ }
+
+ for(int iUlongItem = UlongMetaItem_UlongItemBegin; iUlongItem < UlongMetaItem_UlongItemEnd; iUlongItem++)
+ {
+ if(IsItemSupportedByAnySet((eUlongMetaItem)iUlongItem, metaInfoSetFlags))
+ {
+ m_ulongItems[iUlongItem] = 0;
+ m_ulongItemValidFlags[iUlongItem] = FALSE;
+ }
+ }
+}
+
+void MetaInfo::UpdateItems(const MetaInfo& src, ULONG32 metaInfoSetFlags)
+{
+ for(int iStrItem = StringMetaItem_StringItemBegin; iStrItem < StringMetaItem_StringItemEnd; iStrItem++)
+ {
+ if(IsItemSupportedByAnySet((eStringMetaItem)iStrItem, metaInfoSetFlags))
+ {
+ Update(m_stringItems[iStrItem], src.m_stringItems[iStrItem]);
+ }
+ }
+
+ if(IsItemSupportedByAnySet(StringMetaItem_Keywords, metaInfoSetFlags))
+ {
+ for(ULONG32 i = 0; i < src.GetKeywordCount(); i++)
+ {
+ EncodedString sTmp;
+ src.GetKeyword(i, sTmp);
+ AddKeyword(sTmp);
+ }
+ }
+
+ for(int iUlongItem = UlongMetaItem_UlongItemBegin; iUlongItem < UlongMetaItem_UlongItemEnd; iUlongItem++)
+ {
+ if(IsItemSupportedByAnySet((eUlongMetaItem)iUlongItem, metaInfoSetFlags))
+ {
+ Update(m_ulongItems[iUlongItem], m_ulongItemValidFlags[iUlongItem],
+ src.m_ulongItems[iUlongItem], src.m_ulongItemValidFlags[iUlongItem]);
+ }
+ }
+}
+
+void MetaInfo::CopyToValues(IHXValues* pValues, HXBOOL bBlast, ULONG32 metaInfoSetFlags) const
+{
+ if(!pValues)
+ {
+ return;
+ }
+
+ // Generic
+ if(metaInfoSetFlags & METAINFO_SET_GENERIC)
+ {
+ CopyString(pValues, bBlast, _GENERIC_META_INFO_TITLE_KEY, StringMetaItem_Title);
+ CopyString(pValues, bBlast, _GENERIC_META_INFO_COMPOSER_KEY, StringMetaItem_Composer);
+ CopyString(pValues, bBlast, _GENERIC_META_INFO_COPYRIGHT_KEY, StringMetaItem_Copyright);
+ CopyString(pValues, bBlast, _GENERIC_META_INFO_COMMENT_KEY, StringMetaItem_Comment);
+ CopyString(pValues, bBlast, _GENERIC_META_INFO_ARTIST_KEY, StringMetaItem_Artist);
+ CopyString(pValues, bBlast, _GENERIC_META_INFO_GENRE_KEY, StringMetaItem_Genre);
+ CopyString(pValues, bBlast, _GENERIC_META_INFO_ALBUM_KEY, StringMetaItem_Album);
+
+ CopyULONG32(pValues, bBlast, _GENERIC_META_INFO_TRACK_NUMBER_KEY, UlongMetaItem_TrackNumber);
+ CopyULONG32(pValues, bBlast, _GENERIC_META_INFO_RECORDING_YEAR_KEY, UlongMetaItem_RecordingYear);
+ }
+
+ // iTunes
+ if(metaInfoSetFlags & METAINFO_SET_ITUNES_SPECIFIC)
+ {
+ CopyString(pValues, bBlast, _ITUNES_META_INFO_TRACK_SUBTITLE_KEY, StringMetaItem_TrackSubtitle);
+ CopyString(pValues, bBlast, _ITUNES_META_INFO_GENERATOR_TOOL_KEY, StringMetaItem_GeneratorTool);
+ CopyString(pValues, bBlast, _ITUNES_META_INFO_GROUPING_KEY, StringMetaItem_Grouping);
+ CopyString(pValues, bBlast, _ITUNES_META_INFO_ALBUM_ARTIST_KEY, StringMetaItem_AlbumArtist);
+ CopyString(pValues, bBlast, _ITUNES_META_INFO_LYRICS_KEY, StringMetaItem_Lyrics);
+
+ CopyULONG32(pValues, bBlast, _ITUNES_META_INFO_BEATS_PER_MINUTE_KEY, UlongMetaItem_BeatsPerMinute);
+ CopyULONG32(pValues, bBlast, _ITUNES_META_INFO_PART_OF_COMPILATION_KEY, UlongMetaItem_PartOfCompilation);
+ CopyULONG32(pValues, bBlast, _ITUNES_META_INFO_EXPLICIT_CONTENT_KEY, UlongMetaItem_ExplicitContent);
+ CopyULONG32(pValues, bBlast, _ITUNES_META_INFO_TRACK_COUNT_KEY, UlongMetaItem_TrackCount);
+ CopyULONG32(pValues, bBlast, _ITUNES_META_INFO_DISC_NUMBER_KEY, UlongMetaItem_DiscNumber);
+ CopyULONG32(pValues, bBlast, _ITUNES_META_INFO_DISC_COUNT_KEY, UlongMetaItem_DiscCount);
+ }
+
+ // 3GPP
+ if(metaInfoSetFlags & METAINFO_SET_3GPP_SPECIFIC)
+ {
+ CopyString(pValues, bBlast, _3GPP_META_INFO_GLOBAL_LANGUAGE_ENCODING_KEY, StringMetaItem_GlobalLanguageEncoding);
+ CopyString(pValues, bBlast, _3GPP_META_INFO_RATING_ENTITY_KEY, StringMetaItem_RatingEntity);
+ CopyString(pValues, bBlast, _3GPP_META_INFO_RATING_CRITERIA_KEY, StringMetaItem_RatingCriteria);
+ CopyString(pValues, bBlast, _3GPP_META_INFO_RATING_INFO_KEY, StringMetaItem_RatingInfo);
+ CopyString(pValues, bBlast, _3GPP_META_INFO_CLASSIFICATION_ENTITY_KEY, StringMetaItem_ClassificationEntity);
+ CopyString(pValues, bBlast, _3GPP_META_INFO_CLASSIFICATION_INFO_KEY, StringMetaItem_ClassificationInfo);
+ CopyString(pValues, bBlast, _3GPP_META_INFO_LOCATION_NAME_KEY, StringMetaItem_LocationName);
+ CopyString(pValues, bBlast, _3GPP_META_INFO_LOCATION_ASTRONOMICAL_BODY_KEY, StringMetaItem_LocationAstronomicalBody);
+ CopyString(pValues, bBlast, _3GPP_META_INFO_LOCATION_ADDITIONAL_NOTES_KEY, StringMetaItem_LocationAdditionalNotes);
+ CopyString(pValues, bBlast, _3GPP_META_INFO_LOCATION_LONGITUDE_KEY, StringMetaItem_LocationLongitude);
+ CopyString(pValues, bBlast, _3GPP_META_INFO_LOCATION_LATITUDE_KEY, StringMetaItem_LocationLatitude);
+ CopyString(pValues, bBlast, _3GPP_META_INFO_LOCATION_ALTITUDE_KEY, StringMetaItem_LocationAltitude);
+
+ CopyULONG32(pValues, bBlast, _3GPP_META_INFO_CLASSIFICATION_TABLE_KEY, UlongMetaItem_ClassificationTable);
+ CopyULONG32(pValues, bBlast, _3GPP_META_INFO_LOCATION_ROLE_KEY, UlongMetaItem_LocationRole);
+
+ // keyword section
+ if(bBlast)
+ {
+ RemoveKeywordProperties(pValues);
+ }
+
+ EncodedString sTmp;
+ ULONG32 ulKeywordCount = GetKeywordCount();
+ if(ulKeywordCount)
+ {
+ PropTools::CopyPropertyULONG32(pValues, TRUE, ULONG32(ulKeywordCount),
+ _3GPP_META_INFO_KEYWORD_COUNT_KEY, TRUE);
+ for(ULONG32 i = 0; i < ulKeywordCount; i++)
+ {
+ char key[128];
+ sprintf(key, _3GPP_META_INFO_KEYWORD_KEY, int(i));
+ GetKeyword(i, sTmp);
+ PropTools::CopyPropertyBuffer(pValues, sTmp, key, TRUE);
+ }
+ }
+ }
+}
+
+void MetaInfo::CopyFromValues(IHXValues* pValues, HXBOOL bBlast, ULONG32 metaInfoSetFlags)
+{
+ if(!pValues)
+ {
+ return;
+ }
+
+ // Generic
+ if(metaInfoSetFlags & METAINFO_SET_GENERIC)
+ {
+ CopyString(StringMetaItem_Title, bBlast, pValues, _GENERIC_META_INFO_TITLE_KEY);
+ CopyString(StringMetaItem_Composer, bBlast, pValues, _GENERIC_META_INFO_COMPOSER_KEY);
+ CopyString(StringMetaItem_Copyright, bBlast, pValues, _GENERIC_META_INFO_COPYRIGHT_KEY);
+ CopyString(StringMetaItem_Comment, bBlast, pValues, _GENERIC_META_INFO_COMMENT_KEY);
+ CopyString(StringMetaItem_Artist, bBlast, pValues, _GENERIC_META_INFO_ARTIST_KEY);
+ CopyString(StringMetaItem_Genre, bBlast, pValues, _GENERIC_META_INFO_GENRE_KEY);
+ CopyString(StringMetaItem_Album, bBlast, pValues, _GENERIC_META_INFO_ALBUM_KEY);
+
+ CopyULONG32(UlongMetaItem_TrackNumber, bBlast, pValues, _GENERIC_META_INFO_TRACK_NUMBER_KEY);
+ CopyULONG32(UlongMetaItem_RecordingYear, bBlast, pValues, _GENERIC_META_INFO_RECORDING_YEAR_KEY);
+ }
+
+ // iTunes
+ if(metaInfoSetFlags & METAINFO_SET_ITUNES_SPECIFIC)
+ {
+ CopyString(StringMetaItem_TrackSubtitle, bBlast, pValues, _ITUNES_META_INFO_TRACK_SUBTITLE_KEY);
+ CopyString(StringMetaItem_GeneratorTool, bBlast, pValues, _ITUNES_META_INFO_GENERATOR_TOOL_KEY);
+ CopyString(StringMetaItem_Grouping, bBlast, pValues, _ITUNES_META_INFO_GROUPING_KEY);
+ CopyString(StringMetaItem_AlbumArtist, bBlast, pValues, _ITUNES_META_INFO_ALBUM_ARTIST_KEY);
+ CopyString(StringMetaItem_Lyrics, bBlast, pValues, _ITUNES_META_INFO_LYRICS_KEY);
+
+ CopyULONG32(UlongMetaItem_BeatsPerMinute, bBlast, pValues, _ITUNES_META_INFO_BEATS_PER_MINUTE_KEY);
+ CopyULONG32(UlongMetaItem_PartOfCompilation, bBlast, pValues, _ITUNES_META_INFO_PART_OF_COMPILATION_KEY);
+ CopyULONG32(UlongMetaItem_ExplicitContent, bBlast, pValues, _ITUNES_META_INFO_EXPLICIT_CONTENT_KEY);
+ CopyULONG32(UlongMetaItem_TrackCount, bBlast, pValues, _ITUNES_META_INFO_TRACK_COUNT_KEY);
+ CopyULONG32(UlongMetaItem_DiscNumber, bBlast, pValues, _ITUNES_META_INFO_DISC_NUMBER_KEY);
+ CopyULONG32(UlongMetaItem_DiscCount, bBlast, pValues, _ITUNES_META_INFO_DISC_COUNT_KEY);
+ }
+
+ // 3GPP
+ if(metaInfoSetFlags & METAINFO_SET_3GPP_SPECIFIC)
+ {
+ CopyString(StringMetaItem_GlobalLanguageEncoding, bBlast, pValues, _3GPP_META_INFO_GLOBAL_LANGUAGE_ENCODING_KEY);
+ CopyString(StringMetaItem_RatingEntity, bBlast, pValues, _3GPP_META_INFO_RATING_ENTITY_KEY);
+ CopyString(StringMetaItem_RatingCriteria, bBlast, pValues, _3GPP_META_INFO_RATING_CRITERIA_KEY);
+ CopyString(StringMetaItem_RatingInfo, bBlast, pValues, _3GPP_META_INFO_RATING_INFO_KEY);
+ CopyString(StringMetaItem_ClassificationEntity, bBlast, pValues, _3GPP_META_INFO_CLASSIFICATION_ENTITY_KEY);
+ CopyString(StringMetaItem_ClassificationInfo, bBlast, pValues, _3GPP_META_INFO_CLASSIFICATION_INFO_KEY);
+ CopyString(StringMetaItem_LocationName, bBlast, pValues, _3GPP_META_INFO_LOCATION_NAME_KEY);
+ CopyString(StringMetaItem_LocationAstronomicalBody, bBlast, pValues, _3GPP_META_INFO_LOCATION_ASTRONOMICAL_BODY_KEY);
+ CopyString(StringMetaItem_LocationAdditionalNotes, bBlast, pValues, _3GPP_META_INFO_LOCATION_ADDITIONAL_NOTES_KEY);
+ CopyString(StringMetaItem_LocationLongitude, bBlast, pValues, _3GPP_META_INFO_LOCATION_LONGITUDE_KEY);
+ CopyString(StringMetaItem_LocationLatitude, bBlast, pValues, _3GPP_META_INFO_LOCATION_LATITUDE_KEY);
+ CopyString(StringMetaItem_LocationAltitude, bBlast, pValues, _3GPP_META_INFO_LOCATION_ALTITUDE_KEY);
+
+ CopyULONG32(UlongMetaItem_ClassificationTable, bBlast, pValues, _3GPP_META_INFO_CLASSIFICATION_TABLE_KEY);
+ CopyULONG32(UlongMetaItem_LocationRole, bBlast, pValues, _3GPP_META_INFO_LOCATION_ROLE_KEY);
+
+ // keyword section
+ if(bBlast)
+ {
+ ClearKeywords();
+ }
+
+ EncodedString sTmp;
+ ULONG32 ulKeywordCount = 0;
+ if(PropTools::CopyPropertyULONG32(ulKeywordCount, pValues, _3GPP_META_INFO_KEYWORD_COUNT_KEY))
+ {
+ for(ULONG32 i = 0; i < ulKeywordCount; i++)
+ {
+ char key[128];
+ sprintf(key, _3GPP_META_INFO_KEYWORD_KEY, int(i));
+ if(PropTools::CopyPropertyBuffer(sTmp, pValues, key))
+ {
+ AddKeyword(sTmp);
+ }
+ }
+ }
+
+ RemoveKeywordDuplicates();
+ }
+}
+
+HX_RESULT MetaInfo::GetStringItem(eStringMetaItem itemName, EncodedString& out) const
+{
+ out = m_stringItems[itemName];
+ return out.IsEmpty() ? HXR_FAILED : HXR_OK;
+}
+
+HX_RESULT MetaInfo::SetStringItem(eStringMetaItem itemName, const EncodedString& val, ULONG32 metaFlavorFlags)
+{
+ switch(itemName)
+ {
+ case StringMetaItem_GlobalLanguageEncoding:
+ return SetGlobalLanguageEncoding(val);
+
+ case StringMetaItem_RatingEntity:
+ case StringMetaItem_RatingCriteria:
+ case StringMetaItem_ClassificationEntity:
+ return SetStringAsciiMaxLen(m_stringItems[itemName], val, 4);
+
+ case StringMetaItem_LocationLongitude:
+ case StringMetaItem_LocationLatitude:
+ case StringMetaItem_LocationAltitude:
+ return SetStringFixedPointNum(m_stringItems[itemName], val);
+ }
+
+ // default assignment
+ m_stringItems[itemName] = val;
+ return HXR_OK;
+}
+
+HX_RESULT MetaInfo::GetUlongItem(eUlongMetaItem itemName, ULONG32& out) const
+{
+ out = m_ulongItems[itemName];
+ return m_ulongItemValidFlags[itemName] ? HXR_OK : HXR_FAILED;
+}
+
+HX_RESULT MetaInfo::SetUlongItem(eUlongMetaItem itemName, ULONG32 val, HXBOOL bValid, ULONG32 metaFlavorFlags)
+{
+ switch(itemName)
+ {
+ case UlongMetaItem_TrackNumber:
+ {
+ ULONG32 maxVal = 0x0000FFFF; //iTunes
+ if(metaFlavorFlags & METADATA_FLAVOR_3GPP)
+ {
+ maxVal = 0x000000FF;
+ }
+ return SetUlong(m_ulongItems[itemName], m_ulongItemValidFlags[itemName], val, bValid, 0, maxVal);
+ }
+
+ case UlongMetaItem_RecordingYear:
+ {
+ ULONG32 maxVal = 0x0000FFFF; //3GPP
+ if(metaFlavorFlags & METADATA_FLAVOR_ITUNES)
+ {
+ maxVal = 9999;
+ }
+ return SetUlong(m_ulongItems[itemName], m_ulongItemValidFlags[itemName], val, bValid, 0, maxVal);
+ }
+
+ case UlongMetaItem_PartOfCompilation:
+ case UlongMetaItem_ExplicitContent:
+ return SetUlongBoolean(m_ulongItems[itemName], m_ulongItemValidFlags[itemName], val, bValid);
+
+ case UlongMetaItem_TrackCount:
+ case UlongMetaItem_DiscNumber:
+ case UlongMetaItem_DiscCount:
+ return SetUlong16(m_ulongItems[itemName], m_ulongItemValidFlags[itemName], val, bValid);
+
+ case UlongMetaItem_ClassificationTable:
+ return SetUlong16(m_ulongItems[itemName], m_ulongItemValidFlags[itemName], val, bValid);
+
+ case UlongMetaItem_LocationRole:
+ return SetUlong8(m_ulongItems[itemName], m_ulongItemValidFlags[itemName], val, bValid);
+ }
+
+ // default assignment
+ SetUlong(m_ulongItems[itemName], m_ulongItemValidFlags[itemName], val, bValid);
+ return HXR_OK;
+}
+
+ULONG32 MetaInfo::GetKeywordCount() const
+{
+ return (ULONG32)m_aKeywords.GetSize();
+}
+
+HX_RESULT MetaInfo::GetKeyword(ULONG32 index, EncodedString& out) const
+{
+ INT32 idx = INT32(index);
+ if(idx < m_aKeywords.GetSize())
+ {
+ out = *((EncodedString*)m_aKeywords[idx]);
+ return HXR_OK;
+ }
+ return HXR_FAILED;
+}
+
+HX_RESULT MetaInfo::ClearKeywords()
+{
+ ClearPropertyStringArray(m_aKeywords);
+ return HXR_OK;
+}
+
+HX_RESULT MetaInfo::AddKeyword(const EncodedString& val)
+{
+ if(val.GetByteLength() > 255)
+ {
+ return HXR_INVALID_PARAMETER;
+ }
+
+ for(INT32 i = 0; i < m_aKeywords.GetSize(); i++)
+ {
+ if(*((EncodedString*)m_aKeywords[i]) == val)
+ {
+ return HXR_OK;
+ }
+ }
+ m_aKeywords.Add(new EncodedString(val));
+ return HXR_OK;
+}
+
+HX_RESULT MetaInfo::RemoveKeyword(const EncodedString& val)
+{
+ for(INT32 i = 0; i < m_aKeywords.GetSize(); i++)
+ {
+ EncodedString* s = (EncodedString*)m_aKeywords[i];
+ if(*s == val)
+ {
+ delete s;
+ // Remaining keywords are shifted to fill the hole,
+ // search index must stay the same for new iteration.
+ m_aKeywords.RemoveAt(i--, 1);
+ }
+ }
+ return HXR_OK;
+}
+
+HX_RESULT MetaInfo::RemoveKeywordDuplicates()
+{
+ CHXPtrArray aTmpKeywords;
+ for(INT32 i = 0; i < m_aKeywords.GetSize(); i++)
+ {
+ aTmpKeywords.Add(new EncodedString(*((EncodedString*)m_aKeywords[i])));
+ }
+
+ ClearPropertyStringArray(m_aKeywords);
+
+ for(INT32 i = 0; i < aTmpKeywords.GetSize(); i++)
+ {
+ AddKeyword(*((EncodedString*)aTmpKeywords[i]));
+ }
+
+ ClearPropertyStringArray(aTmpKeywords);
+ return HXR_OK;
+}
+
+HX_RESULT MetaInfo::SetGlobalLanguageEncoding(const EncodedString& val)
+{
+ if(!val.IsAsciiOnly() || (val.GetCodeUnitLength(FALSE, FALSE) != 3))
+ {
+ return HXR_INVALID_PARAMETER;
+ }
+
+ EncodedString valConv;
+ val.ConvertToUTF8(valConv);
+ if(!val.GetData())
+ {
+ return HXR_FAILED;
+ }
+
+ CHXISO639LangCodeRegistry lcreg;
+ if(!lcreg.IsValidLangCode(valConv.GetData()))
+ {
+ return HXR_INVALID_PARAMETER;
+ }
+
+ m_stringItems[StringMetaItem_GlobalLanguageEncoding] = valConv;
+ return HXR_OK;
+}
+
+HX_RESULT MetaInfo::SetStringAsciiMaxLen(EncodedString& dst, const EncodedString& val, ULONG32 maxLen)
+{
+ if(!val.IsAsciiOnly() || (val.GetCodeUnitLength(FALSE, FALSE) > maxLen))
+ {
+ return HXR_INVALID_PARAMETER;
+ }
+
+ dst = val;
+ return HXR_OK;
+}
+
+HX_RESULT MetaInfo::SetStringFixedPointNum(EncodedString& dst, const EncodedString& val)
+{
+ EncodedString normVal = val;
+ if(!PropTools::IsFixedPointNumber(normVal, TRUE))
+ {
+ return HXR_FAILED;
+ }
+
+ dst = normVal;
+ return HXR_OK;
+}
+
+void MetaInfo::Update(EncodedString& dst, const EncodedString& src)
+{
+ if(!src.IsEmpty())
+ {
+ dst = src;
+ }
+}
+
+void MetaInfo::Dump(const char* propName, const EncodedString& val)
+{
+ if(!val.IsEmpty())
+ {
+ printf("%s: ", propName);
+ val.Dump();
+ printf("\n");
+ }
+}
+
+void MetaInfo::CopyString(eStringMetaItem dstItemName, HXBOOL bBlast, IHXValues* pSrcValues, const char* srcEnginePropName)
+{
+ EncodedString sTmp;
+ if(PropTools::CopyPropertyBuffer(sTmp, pSrcValues, srcEnginePropName))
+ {
+ m_stringItems[dstItemName] = sTmp;
+ }
+ else if(bBlast)
+ {
+ m_stringItems[dstItemName].Clear();
+ }
+}
+
+void MetaInfo::CopyString(IHXValues* pDstValues, HXBOOL bBlast, const char* dstEnginePropName, eStringMetaItem srcItemName) const
+{
+ PropTools::CopyPropertyBuffer(pDstValues, m_stringItems[srcItemName], dstEnginePropName, bBlast);
+}
+
+HX_RESULT MetaInfo::SetUlong(ULONG32& dstVal, HXBOOL& dstValid, ULONG32 srcVal, HXBOOL srcValid,
+ ULONG32 minVal, ULONG32 maxVal)
+{
+ if(IsInRange(srcVal, minVal, maxVal))
+ {
+ dstVal = srcVal;
+ dstValid = srcValid;
+ return HXR_OK;
+ }
+ return HXR_INVALID_PARAMETER;
+}
+
+void MetaInfo::Update(ULONG32& dst, HXBOOL& dstValid, ULONG32 src, HXBOOL srcValid)
+{
+ if(srcValid)
+ {
+ dstValid = srcValid;
+ dst = src;
+ }
+}
+
+void MetaInfo::Dump(const char* propName, ULONG32 val, HXBOOL bValid)
+{
+ if(bValid)
+ {
+ printf("%s: dec=%u, hex=0x%08x\n", propName, val, val);
+ }
+}
+
+void MetaInfo::CopyULONG32(eUlongMetaItem dstItemName, HXBOOL bBlast, IHXValues* pSrcValues, const char* srcEnginePropName)
+{
+ ULONG32 uTmp = 0;
+ if(PropTools::CopyPropertyULONG32(uTmp, pSrcValues, srcEnginePropName))
+ {
+ m_ulongItems[dstItemName] = uTmp;
+ m_ulongItemValidFlags[dstItemName] = TRUE;
+ }
+ else if(bBlast)
+ {
+ m_ulongItems[dstItemName] = 0;
+ m_ulongItemValidFlags[dstItemName] = FALSE;
+ }
+}
+
+void MetaInfo::CopyULONG32(IHXValues* pDstValues, HXBOOL bBlast, const char* dstEnginePropName, eUlongMetaItem srcItemName) const
+{
+ PropTools::CopyPropertyULONG32(pDstValues, m_ulongItemValidFlags[srcItemName],
+ m_ulongItems[srcItemName], dstEnginePropName, bBlast);
+}
+
+void MetaInfo::ClearPropertyStringArray(CHXPtrArray& aStrings)
+{
+ for(INT32 i = 0; i < aStrings.GetSize(); i++)
+ {
+ delete (EncodedString*)aStrings[i];
+ }
+
+ aStrings.RemoveAll();
+}
+
Index: pub/metautil.h
===================================================================
RCS file: /cvsroot/datatype/common/util/pub/metautil.h,v
retrieving revision 1.4
diff -d -H -w -U30 -r1.4 metautil.h
--- pub/metautil.h 6 Jul 2007 22:00:24 -0000 1.4
+++ pub/metautil.h 19 Oct 2009 12:45:29 -0000
@@ -64,38 +64,275 @@
* to the IHXFileFormatObject::GetFileHeader() call.
*
* In the function below, an IHXRequest is passed
* in. If HX_RESULT returns HXR_OK, then the other
* variables passed in by referenced can then be
* examined in this order:
*
* If "AcceptMetaInfo" is present in the request headers,
* then rbAcceptMetaInfoPresent will be TRUE. Otherwise,
* it will be FALSE and rbAllMetaInfoRequested and
* rpRequestedMetaInfo will not be altered.
*
* If rbAcceptMetaInfoPresent is TRUE and
* AcceptMetaInfo = "*", then rbAllMetaInfoRequested
* will be TRUE and rpRequestedMetaInfo will be NULL.
*
* If rbAcceptMetaInfoPresent is TRUE and
* AcceptMetaInfo is a delimited string of property
* names, then rbAllMetaInfoRequested will be FALSE
* and rpRequestedMetaInfo will be non-NULL and will
* contain this list of property names as ULONG32
* properties. These property names can then be retrieved
* by using the IHXValues::GetFirstPropertyULONG32()
* and IHXValues::GetNextPropertyULONG32() calls.
* Note that this does not imply that the properties
* are necessarily ULONG32 properties - it's just
* more convenient to make them ULONG32 properties
* than CString or Buffer properties.
*/
+#include "hxtypes.h"
+#include "ihxmetaeditor.h"
+#include "metainfokeys.h"
+#include "carray.h"
+#include "encstr.h"
+
+
HX_RESULT CheckMetaInfoRequest(IHXRequest* pRequest,
IHXCommonClassFactory* pFactory,
REF(HXBOOL) rbAcceptMetaInfoPresent,
REF(HXBOOL) rbAllMetaInfoRequested,
REF(IHXValues*) rpRequestedMetaInfo);
+//
+// ID3 utilities
+//
+class ID3Tools
+{
+public:
+ static HXBOOL GenreOrdinalFromName(const char* szGenreName, UINT8& outOrdinal,
+ HXBOOL bCaseSensitiveSearch = TRUE);
+
+ static const char* GenreNameFromOrdinal(UINT8 uGenreOrdinal);
+
+ // returns number of entries
+ static ULONG32 ParseGenreNameList(CHXPtrArray& outGenreOrdinals, const char* szGenreNames,
+ HXBOOL bCaseSensitiveSearch = TRUE, char separator = ',',
+ HXBOOL bTrimWhitespace = TRUE);
+
+ static void MakeGenreNameList(CHXString& outGenreNames, const CHXPtrArray& genreOrdinals,
+ const char* szSeparator = ",");
+};
+
+//
+// Known metadata tools
+//
+class MetaInfo
+{
+public:
+ static HX_RESULT RemoveKeywordProperties(IHXValues* pValues);
+ static HX_RESULT CopyKeywordProperties(IHXValues* dst, IHXValues* src, HXBOOL bBlast);
+
+ static HX_RESULT RemoveAllProperties(IHXValues* pValues, ULONG32 metaInfoSetFlags);
+ static HX_RESULT CopyAllProperties(IHXValues* dst, IHXValues* src, ULONG32 metaInfoSetFlags, HXBOOL bBlast);
+
+ static ULONG32 GetSetsFromFlavors(ULONG32 metaFlavorFlags);
+ static CHXString GetFlavorName(METADATA_FLAVOR flavor);
+ static CHXString GetFlavorNames(ULONG32 metaFlavorFlags);
+
+ enum eStringMetaItem
+ {
+ StringMetaItem_StringItemBegin = 0,
+
+ StringMetaItem_Title = StringMetaItem_StringItemBegin,
+ StringMetaItem_Artist,
+ StringMetaItem_Album,
+ StringMetaItem_Genre,
+ StringMetaItem_Composer,
+ StringMetaItem_Comment,
+ StringMetaItem_Copyright,
+
+ StringMetaItem_TrackSubtitle, //iTunes
+ StringMetaItem_GeneratorTool, //iTunes
+ StringMetaItem_Grouping, //iTunes
+ StringMetaItem_AlbumArtist, //iTunes
+ StringMetaItem_Lyrics, //iTunes
+
+ StringMetaItem_GlobalLanguageEncoding, //3GPP, exactly 3 ASCII characters, must be valid ISO639.2/T language code
+ StringMetaItem_RatingEntity, //3GPP, max 4 ASCII characters
+ StringMetaItem_RatingCriteria, //3GPP, max 4 ASCII characters
+ StringMetaItem_RatingInfo, //3GPP
+ StringMetaItem_ClassificationEntity, //3GPP, max 4 ASCII characters
+ StringMetaItem_ClassificationInfo, //3GPP
+ StringMetaItem_LocationName, //3GPP
+ StringMetaItem_LocationAstronomicalBody, //3GPP
+ StringMetaItem_LocationAdditionalNotes, //3GPP
+ StringMetaItem_LocationLongitude, //3GPP, fixed point number format
+ StringMetaItem_LocationLatitude, //3GPP, fixed point number format
+ StringMetaItem_LocationAltitude, //3GPP, fixed point number format
+
+ StringMetaItem_StringItemEnd, //special
+ StringMetaItem_StringItemCount = StringMetaItem_StringItemEnd - StringMetaItem_StringItemBegin, //special
+
+ StringMetaItem_Keywords //special, uncounted
+ };
+
+ static ULONG32 GetSetsWhichSupportItem(eStringMetaItem itemName);
+ static HXBOOL IsItemSupportedByAnySet(eStringMetaItem itemName, ULONG32 metaInfoSetFlags)
+ {
+ return (GetSetsWhichSupportItem(itemName) & metaInfoSetFlags) != 0;
+ }
+ static HXBOOL IsItemSupportedByAllSets(eStringMetaItem itemName, ULONG32 metaInfoSetFlags)
+ {
+ return (GetSetsWhichSupportItem(itemName) & metaInfoSetFlags) != metaInfoSetFlags;
+ }
+
+ static ULONG32 GetFlavorsWhichSupportItem(eStringMetaItem itemName);
+ static HXBOOL IsItemSupportedByAnyFlavor(eStringMetaItem itemName, ULONG32 metaFlavorFlags)
+ {
+ return (GetFlavorsWhichSupportItem(itemName) & metaFlavorFlags) != 0;
+ }
+ static HXBOOL IsItemSupportedByAllFlavors(eStringMetaItem itemName, ULONG32 metaFlavorFlags)
+ {
+ return (GetFlavorsWhichSupportItem(itemName) & metaFlavorFlags) == metaFlavorFlags;
+ }
+ static HXBOOL IsItemValueValidForFlavors(eStringMetaItem itemName, const EncodedString& val, ULONG32 metaFlavorFlags);
+
+ enum eUlongMetaItem
+ {
+ UlongMetaItem_UlongItemBegin = 0,
+ UlongMetaItem_TrackNumber = UlongMetaItem_UlongItemBegin, //3GPP UINT8, iTunes INT16
+ UlongMetaItem_RecordingYear, //3GPP UINT16, iTunes YYYY format [0-9999]
+
+ UlongMetaItem_BeatsPerMinute, //iTunes
+ UlongMetaItem_PartOfCompilation, //iTunes
+ UlongMetaItem_ExplicitContent, //iTunes
+ UlongMetaItem_TrackCount, //iTunes INT16
+ UlongMetaItem_DiscNumber, //iTunes INT16
+ UlongMetaItem_DiscCount, //iTunes INT16
+
+ UlongMetaItem_ClassificationTable, //3GPP UINT16
+ UlongMetaItem_LocationRole, //3GPP UINT8
+
+ UlongMetaItem_UlongItemEnd, //special
+ UlongMetaItem_UlongItemCount = UlongMetaItem_UlongItemEnd - UlongMetaItem_UlongItemBegin, //special
+ };
+
+ static ULONG32 GetSetsWhichSupportItem(eUlongMetaItem itemName);
+ static HXBOOL IsItemSupportedByAnySet(eUlongMetaItem itemName, ULONG32 metaInfoSetFlags)
+ {
+ return (GetSetsWhichSupportItem(itemName) & metaInfoSetFlags) != 0;
+ }
+ static HXBOOL IsItemSupportedByAllSets(eUlongMetaItem itemName, ULONG32 metaInfoSetFlags)
+ {
+ return (GetSetsWhichSupportItem(itemName) & metaInfoSetFlags) != metaInfoSetFlags;
+ }
+
+ static ULONG32 GetFlavorsWhichSupportItem(eUlongMetaItem itemName);
+ static HXBOOL IsItemSupportedByAnyFlavor(eUlongMetaItem itemName, ULONG32 metaFlavorFlags)
+ {
+ return (GetFlavorsWhichSupportItem(itemName) & metaFlavorFlags) != 0;
+ }
+ static HXBOOL IsItemSupportedByAllFlavors(eUlongMetaItem itemName, ULONG32 metaFlavorFlags)
+ {
+ return (GetFlavorsWhichSupportItem(itemName) & metaFlavorFlags) != metaFlavorFlags;
+ }
+ static HXBOOL IsItemValueValidForFlavors(eUlongMetaItem itemName, ULONG32 val, ULONG32 metaFlavorFlags);
+
+public:
+ MetaInfo();
+ ~MetaInfo();
+
+ MetaInfo(const MetaInfo& rhs);
+ MetaInfo& operator=(const MetaInfo& rhs);
+
+ void Dump(ULONG32 metaInfoSetFlags = METAINFO_SET_ALL);
+
+ void Clear();
+ void ClearItems(ULONG32 metaInfoSetFlags = METAINFO_SET_ALL);
+ void UpdateItems(const MetaInfo& src, ULONG32 metaInfoSetFlags = METAINFO_SET_ALL);
+
+ void CopyToValues(IHXValues* pValues, HXBOOL bBlast, ULONG32 metaInfoSetFlags = METAINFO_SET_ALL) const;
+ void CopyFromValues(IHXValues* pValues, HXBOOL bBlast, ULONG32 metaInfoSetFlags = METAINFO_SET_ALL);
+
+ // Getters always update <out>.
+ // String getters return success if <out> is empty.
+ // UINT getters return success if the value copied to <out> is considered valid.
+ HX_RESULT GetStringItem(eStringMetaItem itemName, EncodedString& out) const;
+ HX_RESULT SetStringItem(eStringMetaItem itemName, const EncodedString& val, ULONG32 metaFlavorFlags = METADATA_FLAVOR_ALL);
+
+ HX_RESULT GetUlongItem(eUlongMetaItem itemName, ULONG32& out) const;
+ HX_RESULT SetUlongItem(eUlongMetaItem itemName, ULONG32 val, HXBOOL bValid, ULONG32 metaFlavorFlags = METADATA_FLAVOR_ALL);
+
+ // 3GPP keywords
+ ULONG32 GetKeywordCount() const;
+
+ // Returns FALSE if <index> is out of range.
+ HX_RESULT GetKeyword(ULONG32 index, EncodedString& out) const;
+ HX_RESULT ClearKeywords();
+
+ // Returns FALSE if the byte-length of <val> is greater than 255 (maximum allowed by 3GPP).
+ // Also, maximum number of keywords that can be written to 3GPP file is 255 (this method
+ // does not check this to allow easier addition/removal, so this should be checked after
+ // changes by calling GetKeywordCount and taking appropriate actions).
+ HX_RESULT AddKeyword(const EncodedString& val);
+ HX_RESULT RemoveKeyword(const EncodedString& val);
+ HX_RESULT RemoveKeywordDuplicates();
+
+private:
+ HX_RESULT SetGlobalLanguageEncoding(const EncodedString& val);
+ static HX_RESULT SetStringAsciiMaxLen(EncodedString& dst, const EncodedString& val, ULONG32 maxLen);
+ static HX_RESULT SetStringFixedPointNum(EncodedString& dst, const EncodedString& val);
+ static void Update(EncodedString& dst, const EncodedString& src);
+ static void Dump(const char* propName, const EncodedString& val);
+ void CopyString(eStringMetaItem dstItemName, HXBOOL bBlast, IHXValues* pSrcValues, const char* srcEnginePropName);
+ void CopyString(IHXValues* pDstValues, HXBOOL bBlast, const char* dstEnginePropName, eStringMetaItem srcItemName) const;
+
+ static HXBOOL IsInRange(ULONG32 val, ULONG32 min, ULONG32 max)
+ {
+ return (val >= min) && (val <= max);
+ }
+ static HXBOOL IsInRange16(ULONG32 val)
+ {
+ return IsInRange(val, 0, 0x0000FFFF);
+ }
+ static HXBOOL IsInRange8(ULONG32 val)
+ {
+ return IsInRange(val, 0, 0x000000FF);
+ }
+ static HXBOOL IsInRangeBoolean(ULONG32 val)
+ {
+ return IsInRange(val, 0, 1);
+ }
+ static HX_RESULT SetUlong(ULONG32& dstVal, HXBOOL& dstValid, ULONG32 srcVal, HXBOOL srcValid,
+ ULONG32 minVal = 0, ULONG32 maxVal = 0xFFFFFFFF);
+
+ static HX_RESULT SetUlong16(ULONG32& dstVal, HXBOOL& dstValid, ULONG32 srcVal, HXBOOL srcValid)
+ {
+ return SetUlong(dstVal, dstValid, srcVal, srcValid, 0, 0x0000FFFF);
+ }
+ static HX_RESULT SetUlong8(ULONG32& dstVal, HXBOOL& dstValid, ULONG32 srcVal, HXBOOL srcValid)
+ {
+ return SetUlong(dstVal, dstValid, srcVal, srcValid, 0, 0x000000FF);
+ }
+ static HX_RESULT SetUlongBoolean(ULONG32& dstVal, HXBOOL& dstValid, ULONG32 srcVal, HXBOOL srcValid)
+ {
+ return SetUlong(dstVal, dstValid, srcVal, srcValid, 0, 1);
+ }
+ static void Update(ULONG32& dst, HXBOOL& dstValid, ULONG32 src, HXBOOL srcValid);
+ static void Dump(const char* propName, ULONG32 val, HXBOOL bValid);
+ void CopyULONG32(eUlongMetaItem dstItemName, HXBOOL bBlast, IHXValues* pSrcValues, const char* srcEnginePropName);
+ void CopyULONG32(IHXValues* pDstValues, HXBOOL bBlast, const char* dstEnginePropName, eUlongMetaItem srcItemName) const;
+
+ static void ClearPropertyStringArray(CHXPtrArray& aStrings);
+
+private:
+ EncodedString m_stringItems[StringMetaItem_StringItemCount];
+
+ HXBOOL m_ulongItemValidFlags[UlongMetaItem_UlongItemCount];
+ ULONG32 m_ulongItems[UlongMetaItem_UlongItemCount];
+
+ CHXPtrArray m_aKeywords;
+};
#endif /* #ifndef METAUTIL_H */
datatype_include.diff
(text/x-patch, 7.9 KB)
Index: metainfokeys.h
===================================================================
RCS file: /cvsroot/datatype/include/metainfokeys.h,v
retrieving revision 1.3
diff -d -H -w -U30 -r1.3 metainfokeys.h
--- metainfokeys.h 5 Nov 2007 21:36:26 -0000 1.3
+++ metainfokeys.h 19 Oct 2009 12:41:59 -0000
@@ -9,63 +9,109 @@
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
* in which case the RCSL will apply. You may also obtain the license terms
* directly from RealNetworks. You may not use this file except in
* compliance with the RPSL or, if you have a valid RCSL with RealNetworks
* applicable to this file, the RCSL. Please see the applicable RPSL or
* RCSL for the rights, obligations and limitations governing use of the
* contents of the file.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the portions
* it created.
*
* This file, and the files included with this file, is distributed and made
* available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#ifndef _METAINFOKEYS_H_
#define _METAINFOKEYS_H_
-#if (defined HELIX_FEATURE_3GPP_METAINFO || defined HELIX_FEATURE_SERVER)
+
+typedef enum
+{
+ METAINFO_SET_GENERIC = 0x00000001,
+ METAINFO_SET_3GPP_SPECIFIC = 0x00000010,
+ METAINFO_SET_3GPP_ALL = METAINFO_SET_GENERIC | METAINFO_SET_3GPP_SPECIFIC,
+ METAINFO_SET_ITUNES_SPECIFIC = 0x00000100,
+ METAINFO_SET_ITUNES_ALL = METAINFO_SET_GENERIC | METAINFO_SET_ITUNES_SPECIFIC,
+ METAINFO_SET_ALL = METAINFO_SET_GENERIC | METAINFO_SET_3GPP_SPECIFIC | METAINFO_SET_ITUNES_SPECIFIC
+} METAINFO_SET;
+
+// Generic set
+#define _GENERIC_META_INFO_TITLE_KEY "Title"
+#define _GENERIC_META_INFO_COMPOSER_KEY "Author"
+#define _GENERIC_META_INFO_COPYRIGHT_KEY "Copyright"
+#define _GENERIC_META_INFO_COMMENT_KEY "Abstract"
+#define _GENERIC_META_INFO_ARTIST_KEY "Performer"
+#define _GENERIC_META_INFO_GENRE_KEY "Genre"
+#define _GENERIC_META_INFO_ALBUM_KEY "AlbumTitle"
+#define _GENERIC_META_INFO_TRACK_NUMBER_KEY "TrackNumber"
+#define _GENERIC_META_INFO_RECORDING_YEAR_KEY "RecordingYear"
+
+// iTunes aliases for Generic set, for use in file-format/file-writer
+#define _ITUNES_META_INFO_TITLE_KEY _GENERIC_META_INFO_TITLE_KEY
+#define _ITUNES_META_INFO_COMPOSER_KEY _GENERIC_META_INFO_COMPOSER_KEY
+#define _ITUNES_META_INFO_COPYRIGHT_KEY _GENERIC_META_INFO_COPYRIGHT_KEY
+#define _ITUNES_META_INFO_COMMENT_KEY _GENERIC_META_INFO_COMMENT_KEY
+#define _ITUNES_META_INFO_ARTIST_KEY _GENERIC_META_INFO_ARTIST_KEY
+#define _ITUNES_META_INFO_GENRE_KEY _GENERIC_META_INFO_GENRE_KEY
+#define _ITUNES_META_INFO_ALBUM_KEY _GENERIC_META_INFO_ALBUM_KEY
+#define _ITUNES_META_INFO_TRACK_NUMBER_KEY _GENERIC_META_INFO_TRACK_NUMBER_KEY
+#define _ITUNES_META_INFO_RELEASE_DATE_KEY _GENERIC_META_INFO_RECORDING_YEAR_KEY
+
+// iTunes specific set
+#define _ITUNES_META_INFO_TRACK_SUBTITLE_KEY "TrackSubtitle"
+#define _ITUNES_META_INFO_GENERATOR_TOOL_KEY "GeneratorTool"
+#define _ITUNES_META_INFO_GROUPING_KEY "Grouping"
+#define _ITUNES_META_INFO_ALBUM_ARTIST_KEY "AlbumArtist"
+#define _ITUNES_META_INFO_LYRICS_KEY "Lyrics"
+#define _ITUNES_META_INFO_BEATS_PER_MINUTE_KEY "BeatsPerMinute"
+#define _ITUNES_META_INFO_PART_OF_COMPILATION_KEY "PartOfCompilation"
+#define _ITUNES_META_INFO_EXPLICIT_CONTENT_KEY "ExplicitContent"
+#define _ITUNES_META_INFO_TRACK_COUNT_KEY "TrackCount"
+#define _ITUNES_META_INFO_DISC_NUMBER_KEY "DiscNumber"
+#define _ITUNES_META_INFO_DISC_COUNT_KEY "DiscCount"
+
+// 3GPP aliases for Generic set, for use in file-format/file-writer
+#define _3GPP_META_INFO_TITLE_KEY _GENERIC_META_INFO_TITLE_KEY
+#define _3GPP_META_INFO_AUTHOR_KEY _GENERIC_META_INFO_COMPOSER_KEY
+#define _3GPP_META_INFO_COPYRIGHT_KEY _GENERIC_META_INFO_COPYRIGHT_KEY
+#define _3GPP_META_INFO_DESCRIPTION_KEY _GENERIC_META_INFO_COMMENT_KEY
+#define _3GPP_META_INFO_PERFORMER_KEY _GENERIC_META_INFO_ARTIST_KEY
+#define _3GPP_META_INFO_GENRE_KEY _GENERIC_META_INFO_GENRE_KEY
+#define _3GPP_META_INFO_ALBUM_TITLE_KEY _GENERIC_META_INFO_ALBUM_KEY
+#define _3GPP_META_INFO_TRACK_NUMBER_KEY _GENERIC_META_INFO_TRACK_NUMBER_KEY
+#define _3GPP_META_INFO_RECORDING_YEAR_KEY _GENERIC_META_INFO_RECORDING_YEAR_KEY
+
+// 3GPP specific set
#define _3GPP_META_INFO_GLOBAL_LANGUAGE_ENCODING_KEY "GlobalLanguageEncoding"
-#define _3GPP_META_INFO_TITLE_KEY "Title"
-#define _3GPP_META_INFO_AUTHOR_KEY "Author"
-#define _3GPP_META_INFO_COPYRIGHT_KEY "Copyright"
-#ifdef HELIX_FEATURE_3GPP_METAINFO
-#define _3GPP_META_INFO_DESCRIPTION_KEY "Abstract"
-#define _3GPP_META_INFO_PERFORMER_KEY "Performer"
-#define _3GPP_META_INFO_GENRE_KEY "Genre"
-#define _3GPP_META_INFO_RATING_KEY "Rating" //obsolete define, use RATING_CRITERIA instead
#define _3GPP_META_INFO_RATING_ENTITY_KEY "RatingEntity"
-#define _3GPP_META_INFO_RATING_CRITERIA_KEY "Rating"
+#define _3GPP_META_INFO_RATING_CRITERIA_KEY "RatingCriteria"
#define _3GPP_META_INFO_RATING_INFO_KEY "RatingInfo"
#define _3GPP_META_INFO_CLASSIFICATION_ENTITY_KEY "ClassificationEntity"
-#define _3GPP_META_INFO_CLASSIFICATION_INFO_KEY "ClassificationInfo"
#define _3GPP_META_INFO_CLASSIFICATION_TABLE_KEY "ClassificationTable"
-#define _3GPP_META_INFO_KEYWORD_COUNT_KEY "KeywordCount"
-#define _3GPP_META_INFO_KEYWORD_KEY "Keyword%d"
+#define _3GPP_META_INFO_CLASSIFICATION_INFO_KEY "ClassificationInfo"
#define _3GPP_META_INFO_LOCATION_NAME_KEY "LocationName"
#define _3GPP_META_INFO_LOCATION_ASTRONOMICAL_BODY_KEY "LocationAstronomicalBody"
#define _3GPP_META_INFO_LOCATION_ADDITIONAL_NOTES_KEY "LocationAdditionalNotes"
#define _3GPP_META_INFO_LOCATION_ROLE_KEY "LocationRole"
#define _3GPP_META_INFO_LOCATION_LONGITUDE_KEY "LocationLongitude"
#define _3GPP_META_INFO_LOCATION_LATITUDE_KEY "LocationLatitude"
#define _3GPP_META_INFO_LOCATION_ALTITUDE_KEY "LocationAltitude"
-#define _3GPP_META_INFO_ALBUM_TITLE_KEY "AlbumTitle"
-#define _3GPP_META_INFO_TRACK_NUMBER_KEY "AlbumTrackNumber"
-#define _3GPP_META_INFO_RECORDING_YEAR_KEY "RecordingYear"
-#endif // HELIX_FEATURE_3GPP_METAINFO
-#endif // HELIX_FEATURE_3GPP_METAINFO || HELIX_FEATURE_SERVER
+#define _3GPP_META_INFO_KEYWORD_COUNT_KEY "KeywordCount"
+#define _3GPP_META_INFO_KEYWORD_KEY "Keyword%d"
+#define _3GPP_META_INFO_ID32_BLOB_KEY "ID32BLOB"
+
#endif // _METAINFOKEYS_H_
datatype_mp4_fileformat.diff
(text/x-patch, 140.2 KB) - not displayed
datatype_mp4_filewriter.diff
(text/x-patch, 97.5 KB)
Index: 3gpmeta.cpp
===================================================================
RCS file: /cvsroot/datatype/mp4/filewriter/3gpmeta.cpp,v
retrieving revision 1.2
diff -d -H -b -B -w -U30 -r1.2 3gpmeta.cpp
--- 3gpmeta.cpp 20 Apr 2009 17:24:05 -0000 1.2
+++ 3gpmeta.cpp 19 Oct 2009 13:16:56 -0000
@@ -489,30 +489,71 @@
return retVal;
}
C3GPAtom_yrrc::C3GPAtom_yrrc()
: CMP4VersionedAtom(MP4_BUILD_ATOMID('y','r','r','c'))
{
m_year = 0;
}
void C3GPAtom_yrrc::SetRecordingYear(UINT16 year)
{
m_year = year;
}
STDMETHODIMP_(UINT32) C3GPAtom_yrrc::GetCurrentSize(THIS_ HXBOOL bIncludeChildren)
{
return CMP4VersionedAtom::GetCurrentSize( bIncludeChildren ) +
sizeof(UINT16);
}
STDMETHODIMP C3GPAtom_yrrc::WriteToBuffer(THIS_ UCHAR*& pBuffer, HXBOOL bIncludeChildren)
{
HX_RESULT retVal = HXR_OK;
if( pBuffer )
{
CMP4VersionedAtom::WriteAtomAndVersionInfo( pBuffer );
CMP4Atom::WriteToBufferAndInc( pBuffer, m_year );
}
return retVal;
}
+
+C3GPAtom_ID32::C3GPAtom_ID32()
+ : C3GPAtom_LangBase(MP4_BUILD_ATOMID('I','D','3','2'))
+ , m_pBlob(0)
+ , m_uBlobSize(0)
+{
+}
+
+C3GPAtom_ID32::~C3GPAtom_ID32()
+{
+ HX_VECTOR_DELETE(m_pBlob);
+}
+
+void C3GPAtom_ID32::SetBlob(UCHAR* pData, UINT32 size)
+{
+ HX_VECTOR_DELETE(m_pBlob);
+ m_uBlobSize = size;
+ m_pBlob = new UCHAR[size];
+ memcpy(m_pBlob, pData, size);
+}
+
+STDMETHODIMP_(UINT32) C3GPAtom_ID32::GetCurrentSize(THIS_ HXBOOL bIncludeChildren)
+{
+ return C3GPAtom_LangBase::GetCurrentSize( bIncludeChildren ) +
+ m_uBlobSize;
+}
+
+STDMETHODIMP C3GPAtom_ID32::WriteToBuffer(THIS_ UCHAR*& pBuffer, HXBOOL bIncludeChildren)
+{
+ HX_RESULT retVal = HXR_OK;
+ if(pBuffer)
+ {
+ CMP4VersionedAtom::WriteAtomAndVersionInfo( pBuffer );
+ C3GPAtom_LangBase::WriteLanguageToBuffer( pBuffer );
+ if(m_uBlobSize)
+ {
+ CMP4Atom::WriteToBufferAndInc( pBuffer, (UCHAR*)m_pBlob, m_uBlobSize );
+ }
+ }
+ return retVal;
+}
Index: 3gpmeta.h
===================================================================
RCS file: /cvsroot/datatype/mp4/filewriter/3gpmeta.h,v
retrieving revision 1.4
diff -d -H -b -B -w -U30 -r1.4 3gpmeta.h
--- 3gpmeta.h 20 Apr 2009 17:24:05 -0000 1.4
+++ 3gpmeta.h 19 Oct 2009 13:16:58 -0000
@@ -12,63 +12,66 @@
* in which case the RCSL will apply. You may also obtain the license terms
* directly from RealNetworks. You may not use this file except in
* compliance with the RPSL or, if you have a valid RCSL with RealNetworks
* applicable to this file, the RCSL. Please see the applicable RPSL or
* RCSL for the rights, obligations and limitations governing use of the
* contents of the file.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the portions
* it created.
*
* This file, and the files included with this file, is distributed and made
* available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#ifndef _3GPMETA_H_
#define _3GPMETA_H_
#include "mp4atoms.h"
#include "proptools.h"
+//*****************************************************************************
// 3GP asset meta data
-// top level 3GP asset meta data is a user-data box
-// most 3GP meta info sub-boxes has the same format of full_box + language + string
+// Container box for 3GP asset metadata is 'udta' box.
+// Exception is ID3v2 box which must reside in 'meta' box.
+// 'meta' box itself can reside at file, 'moov' or 'trak' level.
+// Most 3GP metadata boxes have the same format: full_box + language + string
//
class C3GPAtom_LangBase : public CMP4VersionedAtom
{
public:
static void ConfigureStringOutput(HXBOOL bUseUTF16);
static HXBOOL IsStringOutputUTF16(HXBOOL bUseUTF16);
public:
C3GPAtom_LangBase(UINT32 ulAtomID);
void InitLanguage();
void SetLanguage(const UCHAR* lang);
void SetLanguage(const char* lang)
{
SetLanguage(reinterpret_cast<const UCHAR*>(lang));
}
UINT32 GetLanguageSize()
{
return sizeof(UINT16);
}
void WriteLanguageToBuffer(UCHAR*& pBuffer);
STDMETHOD_(UINT32, GetCurrentSize)(THIS_ HXBOOL bIncludeChildren = FALSE);
STDMETHOD(WriteToBuffer)(THIS_ UCHAR*& pBuffer, HXBOOL bIncludeChildren = FALSE);
protected:
// utilities which simplify definitions of string atom parts
static char* EncodeStringForOutput(const char* psz, HX_TEXT_ENCODING_TYPE et);
void InitStringPartImp(char*& pszPart);
void DeleteStringPartImp(char*& pszPart);
@@ -261,31 +264,48 @@
void SetString_AlbumTitle(const char* psz, HX_TEXT_ENCODING_TYPE et)
{
SetStringPartImp(m_pszAlbumTitle, psz, et);
}
void SetTrackNumber(HXBOOL includeTrackNum, UINT8 trackNum);
STDMETHOD_(UINT32, GetCurrentSize)(THIS_ HXBOOL bIncludeChildren = FALSE);
STDMETHOD(WriteToBuffer)(THIS_ UCHAR*& pBuffer, HXBOOL bIncludeChildren = FALSE);
private:
char* m_pszAlbumTitle;
HXBOOL m_include_tracknum;
UINT8 m_tracknum;
};
// Recording Year
class C3GPAtom_yrrc : public CMP4VersionedAtom
{
public:
C3GPAtom_yrrc();
void SetRecordingYear(UINT16 year);
STDMETHOD_(UINT32, GetCurrentSize)(THIS_ HXBOOL bIncludeChildren = FALSE);
STDMETHOD(WriteToBuffer)(THIS_ UCHAR*& pBuffer, HXBOOL bIncludeChildren = FALSE);
private:
UINT16 m_year;
};
+// ID32
+class C3GPAtom_ID32 : public C3GPAtom_LangBase
+{
+public:
+ C3GPAtom_ID32();
+ virtual ~C3GPAtom_ID32();
+
+ void SetBlob(UCHAR* pData, UINT32 size);
+
+ STDMETHOD_(UINT32, GetCurrentSize)(THIS_ HXBOOL bIncludeChildren = FALSE);
+ STDMETHOD(WriteToBuffer)(THIS_ UCHAR*& pBuffer, HXBOOL bIncludeChildren = FALSE);
+
+private:
+ UCHAR* m_pBlob;
+ UINT32 m_uBlobSize;
+};
+
#endif /* _3GPMETA_H_ */
Index: m4amdatoms.h
===================================================================
RCS file: /cvsroot/datatype/mp4/filewriter/m4amdatoms.h,v
retrieving revision 1.6
diff -d -H -b -B -w -U30 -r1.6 m4amdatoms.h
--- m4amdatoms.h 20 Apr 2009 17:24:05 -0000 1.6
+++ m4amdatoms.h 19 Oct 2009 13:16:58 -0000
@@ -16,377 +16,537 @@
* RCSL for the rights, obligations and limitations governing use of the
* contents of the file.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the portions
* it created.
*
* This file, and the files included with this file, is distributed and made
* available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
// m4amdatoms.h: atoms specific to m4a metadata
#ifndef _M4AMDATOMS_H_
#define _M4AMDATOMS_H_
#include "mp4atoms.h"
//iTunes stype meta info
// meta; this is the top level atom inside the udta, and all
// metadata atoms live inside it
-class CM4AAtom_meta : public CMP4VersionedAtom
+class CiTunesAtom_meta : public CMP4VersionedAtom
{
public:
- CM4AAtom_meta() : CMP4VersionedAtom(MP4_BUILD_ATOMID('m','e','t','a'))
+ CiTunesAtom_meta() : CMP4VersionedAtom(MP4_BUILD_ATOMID('m','e','t','a'))
{}
STDMETHOD( WriteToBuffer ) (THIS_ UCHAR*& pBuffer, HXBOOL bIncludeChildren = FALSE )
{
HX_RESULT retVal = HXR_OK;
if( pBuffer )
{
CMP4VersionedAtom::WriteAtomAndVersionInfo( pBuffer );
if( bIncludeChildren )
{
retVal = ChildrenWriteToBuffer( pBuffer );
}
}
return retVal;
}
};
-class CM4AAtom_ilst : public CMP4ContainerAtom
-{
-public:
- CM4AAtom_ilst() : CMP4ContainerAtom(MP4_BUILD_ATOMID('i','l','s','t'))
- {}
-};
-
-class CM4AAtom_hdlr : public CMP4VersionedAtom
+class CiTunesAtom_hdlr : public CMP4VersionedAtom
{
public:
- CM4AAtom_hdlr() : CMP4VersionedAtom(MP4_BUILD_ATOMID('h','d','l','r'))
+ CiTunesAtom_hdlr() : CMP4VersionedAtom(MP4_BUILD_ATOMID('h','d','l','r'))
{
m_uiHdlrType = 0;
m_uiHdlrSubType = MP4_BUILD_ATOMID('m','d','i','r');
m_uiHdlrManufacturer = MP4_BUILD_ATOMID('a','p','p','l');
m_uiComponentFlags = 0;
m_uiComponentFlagsMask = 0;
m_pszName = NULL;
m_uiNameLength = 2;
}
- ~CM4AAtom_hdlr()
+ ~CiTunesAtom_hdlr()
{
HX_VECTOR_DELETE( m_pszName );
}
STDMETHOD_( UINT32, GetCurrentSize ) ( THIS_ HXBOOL bIncludeChildren = FALSE )
{
UINT32 len = CMP4VersionedAtom::GetCurrentSize( bIncludeChildren )
+ 4 + 4 + 4 + 4 + 4;
len += m_uiNameLength;
return len;
}
STDMETHOD( WriteToBuffer ) (THIS_ UCHAR*& pBuffer, HXBOOL bIncludeChildren = FALSE)
{
HX_RESULT retVal = HXR_OK;
if( pBuffer )
{
CMP4VersionedAtom::WriteAtomAndVersionInfo( pBuffer );
CMP4Atom::WriteToBufferAndInc( pBuffer, m_uiHdlrType );
CMP4Atom::WriteToBufferAndInc( pBuffer, m_uiHdlrSubType );
CMP4Atom::WriteToBufferAndInc( pBuffer, m_uiHdlrManufacturer );
CMP4Atom::WriteToBufferAndInc( pBuffer, m_uiComponentFlags );
CMP4Atom::WriteToBufferAndInc( pBuffer, m_uiComponentFlagsMask );
if( m_pszName )
{
CMP4Atom::WriteToBufferAndInc( pBuffer, m_pszName, m_uiNameLength );
} else
{
CMP4Atom::WriteToBufferAndInc( pBuffer, (UCHAR*)"\0Z", 2 );
}
if( bIncludeChildren )
{
retVal = ChildrenWriteToBuffer( pBuffer );
}
}
return retVal;
}
private:
UINT32 m_uiHdlrType;
UINT32 m_uiHdlrSubType;
UINT32 m_uiHdlrManufacturer;
UINT32 m_uiComponentFlags;
UINT32 m_uiComponentFlagsMask;
UCHAR* m_pszName;
UINT32 m_uiNameLength;
};
-class CM4AAtom_data : public CMP4VersionedAtom
+class CiTunesAtom_ilst : public CMP4ContainerAtom
{
public:
- CM4AAtom_data() : CMP4VersionedAtom(MP4_BUILD_ATOMID('d','a','t','a'))
+ CiTunesAtom_ilst() : CMP4ContainerAtom(MP4_BUILD_ATOMID('i','l','s','t'))
+ {}
+};
+
+class CiTunesAtom_data : public CMP4Atom
{
- m_reserved = 0;
- m_ucBinStrBuf = NULL;
- m_uiIntBuf = NULL;
- m_uiDataLength = 0;
+public:
+ CiTunesAtom_data() : CMP4Atom(MP4_BUILD_ATOMID('d','a','t','a'))
+ {
+ m_typeIndicatorReserved = 0;
+ m_typeIndicatorTypeSetIdentifier = 0;
+ SetTypeIndicatorTypeCode(TypeIndicatorTypeCode_Implicit);
+ m_localeIndicator = 0;
+ m_uiByteBufLength = 0;
+ m_ucByteBuf = NULL;
}
- ~CM4AAtom_data()
+ ~CiTunesAtom_data()
{
- HX_VECTOR_DELETE( m_ucBinStrBuf );
- HX_VECTOR_DELETE( m_uiIntBuf );
+ ClearData();
}
STDMETHOD_(UINT32, GetCurrentSize ) (THIS_ HXBOOL bIncludeChildren = FALSE)
{
- UINT32 len = CMP4VersionedAtom::GetCurrentSize(bIncludeChildren)
- + 4 + m_uiDataLength;
- return len;
+ // BaseAtomSize + TypeIndicatorReserved + TypeIndicatorTypeSetIdentifier + TypeIndicatorTypeCode + LocaleIndicator
+ UINT32 len = 8 + 2 + 1 + 1 + 4;
+
+ if( m_uiByteBufLength )
+ {
+ len += m_uiByteBufLength;
+ }
+
+ return len + (bIncludeChildren ? GetSizeOfChildren() : 0);
}
STDMETHOD( WriteToBuffer ) (THIS_ UCHAR*& pBuffer, HXBOOL bIncludeChildren = FALSE)
{
HX_RESULT retVal = HXR_OK;
if( pBuffer )
{
- CMP4VersionedAtom::WriteAtomAndVersionInfo( pBuffer );
+ CMP4Atom::WriteToBufferAndInc( pBuffer, GetCurrentSize() );
+ CMP4Atom::WriteToBufferAndInc( pBuffer, m_ulAtomID );
- CMP4Atom::WriteToBufferAndInc( pBuffer, m_reserved );
+ CMP4Atom::WriteToBufferAndInc( pBuffer, m_typeIndicatorReserved );
+ CMP4Atom::WriteToBufferAndInc( pBuffer, m_typeIndicatorTypeSetIdentifier );
+ CMP4Atom::WriteToBufferAndInc( pBuffer, m_typeIndicatorTypeCode );
+ CMP4Atom::WriteToBufferAndInc( pBuffer, m_localeIndicator );
- if( m_uiFlags == _DataFlags::INT )
- {
- CMP4Atom::WriteToBufferAndInc( pBuffer, m_uiIntBuf, m_uiDataLength );
- }
- else
+ if( m_uiByteBufLength )
{
- CMP4Atom::WriteToBufferAndInc( pBuffer, m_ucBinStrBuf, m_uiDataLength );
+ CMP4Atom::WriteToBufferAndInc( pBuffer, m_ucByteBuf, m_uiByteBufLength );
}
if( bIncludeChildren )
{
retVal = ChildrenWriteToBuffer( pBuffer );
}
}
return retVal;
}
/*
* Local routines
*/
- STDMETHOD( SetString ) (THIS_ const UCHAR* pszString)
+ STDMETHOD( SetBytes ) (THIS_ const UCHAR* pBytes, UINT32 len )
{
- HX_RESULT retVal = HXR_INVALID_PARAMETER;
+ HX_RESULT retVal = AllocBuffer(len);
- if( pszString )
+ if( SUCCEEDED(retVal) && pBytes )
{
- UINT32 len = strlen((const char*)pszString);
- m_ucBinStrBuf = new UCHAR[ len ];
- retVal = HXR_OUTOFMEMORY;
-
- if( m_ucBinStrBuf )
+ memcpy(m_ucByteBuf, pBytes, len);
+ }
+ return retVal;
+ }
+ STDMETHOD( SetUTF8String ) (THIS_ const char* pStr, UINT32 byteLengthWithoutTerm )
{
- memcpy( m_ucBinStrBuf, pszString, len );
- m_uiDataLength = len;
- CMP4VersionedAtom::m_uiFlags = _DataFlags::STRING;
+ HX_RESULT retVal = SetBytes((const UCHAR*)pStr, byteLengthWithoutTerm);
+ if( SUCCEEDED(retVal) )
+ {
+ SetTypeIndicatorTypeCode(TypeIndicatorTypeCode_UTF8);
+ }
+ return retVal;
+ }
+ STDMETHOD( SetUTF16BEString ) (THIS_ const char* pStr, UINT32 byteLengthWithoutTerm )
+ {
+ HX_RESULT retVal = SetBytes((const UCHAR*)pStr, byteLengthWithoutTerm);
+ if( SUCCEEDED(retVal) )
+ {
+ SetTypeIndicatorTypeCode(TypeIndicatorTypeCode_UTF16BE);
+ }
+ return retVal;
+ }
+ STDMETHOD( SetUInteger32 ) (THIS_ ULONG32 value )
+ {
+ // 4 bytes
+ HX_RESULT retVal = AllocBuffer(4);
+ if( SUCCEEDED(retVal) )
+ {
+ // write integer in BE order
+ UCHAR* pBuffer = m_ucByteBuf;
+ WriteToBufferAndInc(pBuffer, value);
+ SetTypeIndicatorTypeCode(TypeIndicatorTypeCode_Integer);
+ }
+ return retVal;
+ }
+ STDMETHOD( SetUInteger16 ) (THIS_ ULONG32 value )
+ {
+ // 2 bytes
+ HX_RESULT retVal = AllocBuffer(2);
+ if( SUCCEEDED(retVal) )
+ {
+ // write integer in BE order
+ UCHAR* pBuffer = m_ucByteBuf;
+ WriteToBufferAndInc(pBuffer, static_cast<UINT16>(value & 0x000000FF));
+ SetTypeIndicatorTypeCode(TypeIndicatorTypeCode_Integer);
+ }
+ return retVal;
+ }
+ STDMETHOD( SetUInteger8 ) (THIS_ ULONG32 value )
+ {
+ // 1 byte
+ HX_RESULT retVal = AllocBuffer(1);
+ if( SUCCEEDED(retVal) )
+ {
+ m_ucByteBuf[0] = static_cast<UCHAR>(value & 0x000000FF);
+ SetTypeIndicatorTypeCode(TypeIndicatorTypeCode_Integer);
+ }
+ return retVal;
+ }
+ STDMETHOD( SetSpecial_TrackNumberCount ) (THIS_ ULONG32 trackNumber, ULONG32 trackCount )
+ {
+ // 2 bytes reserved + 2 bytes track number + 2 bytes track count
+ // + 1 byte playlist-name length (must be set to 0) + 1 byte playlist-name terminator
+ // The last byte should not exist by iTMF spec since playlist-name length field mustbe 0,
+ // but most tools expect it, iTunes 9 included. Since the encoding of playlist-name is not specified,
+ // we can think of the last byte as of C-string 0-terminator.
+ const UINT32 dataLength = 8;
+ HX_RESULT retVal = AllocBuffer(dataLength);
+ if( SUCCEEDED(retVal) )
+ {
+ memset(m_ucByteBuf, 0, dataLength);
- retVal = HXR_OK;
+ UCHAR* pTmp = m_ucByteBuf + 2;
+ WriteToBufferAndInc(pTmp, static_cast<UINT16>(trackNumber & 0x0000FFFF));
+ WriteToBufferAndInc(pTmp, static_cast<UINT16>(trackCount & 0x0000FFFF));
+
+ SetTypeIndicatorTypeCode(TypeIndicatorTypeCode_Implicit);
}
+ return retVal;
+ }
+ STDMETHOD( SetSpecial_DiscNumberCount ) (THIS_ ULONG32 discNumber, ULONG32 discCount )
+ {
+ // 2 bytes reserved + 2 bytes disc number + 2 bytes disc count
+ const UINT32 dataLength = 6;
+ HX_RESULT retVal = AllocBuffer(dataLength);
+ if( SUCCEEDED(retVal) )
+ {
+ memset(m_ucByteBuf, 0, dataLength);
+
+ UCHAR* pTmp = m_ucByteBuf + 2;
+ WriteToBufferAndInc(pTmp, static_cast<UINT16>(discNumber & 0x0000FFFF));
+ WriteToBufferAndInc(pTmp, static_cast<UINT16>(discCount & 0x0000FFFF));
+
+ SetTypeIndicatorTypeCode(TypeIndicatorTypeCode_Implicit);
}
return retVal;
}
- STDMETHOD( SetBinary ) (THIS_ const UCHAR* pBinary, UINT32 len )
+ STDMETHOD( SetSpecial_PredefinedGenreEntries ) (THIS_ CHXPtrArray& genreEntries )
{
- HX_RESULT retVal = HXR_INVALID_PARAMETER;
+ if(!genreEntries.GetSize())
+ {
+ return HXR_FAILED;
+ }
- if( pBinary )
+ // 2*count bytes
+ const UINT32 dataLength = genreEntries.GetSize() * 2;
+ HX_RESULT retVal = AllocBuffer(dataLength);
+ if( SUCCEEDED(retVal) )
{
- m_ucBinStrBuf = new UCHAR[ len ];
- retVal = HXR_OUTOFMEMORY;
+ UCHAR* pTmp = m_ucByteBuf;
- if( m_ucBinStrBuf )
+ for(ULONG32 i = 0; i < genreEntries.GetSize(); i++)
{
- memcpy( m_ucBinStrBuf, pBinary, len );
- CMP4VersionedAtom::m_uiFlags = _DataFlags::BINARY;
- retVal = HXR_OK;
+ UINT16 entry = (UINT16)(ULONG32)genreEntries.GetAt(i);
+ WriteToBufferAndInc(pTmp, entry);
}
+
+ // The TypeIndicatorTypeCode_Genres makes most tools (including iTunes9)
+ // ignore this atom, so use implicit.
+ SetTypeIndicatorTypeCode(TypeIndicatorTypeCode_Implicit);
+ //SetTypeIndicatorTypeCode(TypeIndicatorTypeCode_Genres);
}
return retVal;
}
- STDMETHOD( SetInt ) (THIS_ const UINT32* pInt, UINT32 len )
+
+protected:
+ void ClearData()
{
- HX_RESULT retVal = HXR_INVALID_PARAMETER;
+ m_uiByteBufLength = 0;
+ HX_VECTOR_DELETE( m_ucByteBuf );
- if( pInt )
+ SetTypeIndicatorTypeCode(TypeIndicatorTypeCode_Implicit);
+ }
+
+ HX_RESULT AllocBuffer(ULONG32 len)
+ {
+ ClearData();
+
+ HX_RESULT retVal = HXR_INVALID_PARAMETER;
+ if(len)
{
- m_uiIntBuf = new UINT32[ len ];
retVal = HXR_OUTOFMEMORY;
+ m_ucByteBuf = new UCHAR[len];
- if( m_uiIntBuf )
+ if(m_ucByteBuf)
{
- memcpy( m_uiIntBuf, pInt, len << 2 );
- CMP4VersionedAtom::m_uiFlags = _DataFlags::INT;
+ m_uiByteBufLength = len;
+ memset(m_ucByteBuf, 0, len);
retVal = HXR_OK;
}
}
return retVal;
}
- STDMETHOD( SetByte ) (THIS_ const UCHAR* pByte, UINT32 len )
+
+ enum TypeIndicatorTypeCode
{
- HX_RESULT retVal = SetBinary( pByte, len );
- if( SUCCEEDED( retVal ) )
+ TypeIndicatorTypeCode_Implicit = 0, //no type needs to be indicated because only one type is allowed
+ TypeIndicatorTypeCode_UTF8 = 1, //without count or null terminator
+ TypeIndicatorTypeCode_UTF16BE = 2, //without count or null terminator
+ TypeIndicatorTypeCode_Genres = 18, //special enumeration
+ TypeIndicatorTypeCode_Integer = 21 //signed big-endian integer in 1,2,3,4,8 bytes
+ };
+
+ void SetTypeIndicatorTypeCode(TypeIndicatorTypeCode tc)
{
- CMP4VersionedAtom::m_uiFlags = _DataFlags::BYTE;
- }
- return retVal;
+ m_typeIndicatorTypeCode = (UCHAR)tc;
}
-protected:
- // XXX Probably not the best naming ever. The distinctions here
- // aren't very clear
- enum _DataFlags
- {
- INT=0x00,
- STRING=0x01,
- BINARY=0x0D,
- BYTE=0x15,
- };
private:
- UINT32 m_reserved;
- UCHAR* m_ucBinStrBuf; // used for STRING, BINARY, BYTE
- UINT32* m_uiIntBuf; // used for INT
- UINT32 m_uiDataLength;
+ UINT16 m_typeIndicatorReserved; //reserved to be 0
+ UCHAR m_typeIndicatorTypeSetIdentifier; //only one type set defined: 0
+ UCHAR m_typeIndicatorTypeCode;
+ UINT32 m_localeIndicator; //reserved to be 0
+ UINT32 m_uiByteBufLength;
+ UCHAR* m_ucByteBuf;
};
// track name
// string
-class CM4AAtom_nam : public CMP4ContainerAtom
+class CiTunesAtom_A9nam : public CMP4ContainerAtom
{
public:
- CM4AAtom_nam() : CMP4ContainerAtom(MP4_BUILD_ATOMID(0xA9,'n','a','m'))
+ CiTunesAtom_A9nam() : CMP4ContainerAtom(MP4_BUILD_ATOMID(0xA9,'n','a','m'))
{}
};
-// track artist
+// track subtitle
// string
-class CM4AAtom_art : public CMP4ContainerAtom
+class CiTunesAtom_A9st3 : public CMP4ContainerAtom
{
public:
- CM4AAtom_art() : CMP4ContainerAtom(MP4_BUILD_ATOMID(0xA9,'A','R','T'))
+ CiTunesAtom_A9st3() : CMP4ContainerAtom(MP4_BUILD_ATOMID(0xA9,'s','t','3'))
{}
};
-// album name
+// track artist
// string
-class CM4AAtom_alb : public CMP4ContainerAtom
+class CiTunesAtom_A9ART : public CMP4ContainerAtom
{
public:
- CM4AAtom_alb() : CMP4ContainerAtom(MP4_BUILD_ATOMID(0xA9,'a','l','b'))
+ CiTunesAtom_A9ART() : CMP4ContainerAtom(MP4_BUILD_ATOMID(0xA9,'A','R','T'))
{}
};
-// genre name
+// album name
// string
-class CM4AAtom_gen : public CMP4ContainerAtom
+class CiTunesAtom_A9alb : public CMP4ContainerAtom
{
public:
- CM4AAtom_gen() : CMP4ContainerAtom(MP4_BUILD_ATOMID(0xA9,'g','e','n'))
+ CiTunesAtom_A9alb() : CMP4ContainerAtom(MP4_BUILD_ATOMID(0xA9,'a','l','b'))
{}
};
-// track number
-// int array, 1-2 items
-class CM4AAtom_trkn: public CMP4ContainerAtom
+// user genre
+// string
+class CiTunesAtom_A9gen : public CMP4ContainerAtom
{
public:
- CM4AAtom_trkn() : CMP4ContainerAtom(MP4_BUILD_ATOMID('t','r','k','n'))
+ CiTunesAtom_A9gen() : CMP4ContainerAtom(MP4_BUILD_ATOMID(0xA9,'g','e','n'))
{}
};
-// disk number
-// int array, 1-2 items
-class CM4AAtom_disk : public CMP4ContainerAtom
+// copyright
+// string
+class CiTunesAtom_cprt : public CMP4ContainerAtom
{
public:
- CM4AAtom_disk() : CMP4ContainerAtom(MP4_BUILD_ATOMID('d','i','s','k'))
+ CiTunesAtom_cprt() : CMP4ContainerAtom(MP4_BUILD_ATOMID('c','p','r','t'))
{}
};
-// day (year)
+// year
// string
-class CM4AAtom_day : public CMP4ContainerAtom
+class CiTunesAtom_A9day : public CMP4ContainerAtom
{
public:
- CM4AAtom_day() : CMP4ContainerAtom(MP4_BUILD_ATOMID(0xA9,'d','a','y'))
+ CiTunesAtom_A9day() : CMP4ContainerAtom(MP4_BUILD_ATOMID(0xA9,'d','a','y'))
{}
};
// comment
// string
-class CM4AAtom_cmt : public CMP4ContainerAtom
+class CiTunesAtom_A9cmt : public CMP4ContainerAtom
{
public:
- CM4AAtom_cmt() : CMP4ContainerAtom(MP4_BUILD_ATOMID(0xA9,'c','m','t'))
+ CiTunesAtom_A9cmt() : CMP4ContainerAtom(MP4_BUILD_ATOMID(0xA9,'c','m','t'))
{}
};
// composer
// string
-class CM4AAtom_wrt : public CMP4ContainerAtom
+class CiTunesAtom_A9wrt : public CMP4ContainerAtom
{
public:
- CM4AAtom_wrt() : CMP4ContainerAtom(MP4_BUILD_ATOMID(0xA9,'w','r','t'))
+ CiTunesAtom_A9wrt() : CMP4ContainerAtom(MP4_BUILD_ATOMID(0xA9,'w','r','t'))
{}
};
-// cover art
-// binary
-class CM4AAtom_covr : public CMP4ContainerAtom
+// tools
+// string
+class CiTunesAtom_A9too : public CMP4ContainerAtom
{
public:
- CM4AAtom_covr() : CMP4ContainerAtom(MP4_BUILD_ATOMID('c','o','v','r'))
+ CiTunesAtom_A9too() : CMP4ContainerAtom(MP4_BUILD_ATOMID(0xa9,'t','o','o'))
{}
};
-// tempo
-// byte (2)
-class CM4AAtom_tmpo : public CMP4ContainerAtom
+// grouping
+// string
+class CiTunesAtom_grup : public CMP4ContainerAtom
{
public:
- CM4AAtom_tmpo() : CMP4ContainerAtom(MP4_BUILD_ATOMID('t','m','p','o'))
+ CiTunesAtom_grup() : CMP4ContainerAtom(MP4_BUILD_ATOMID('g','r','u','p'))
{}
};
-// compilation
-// byte (1)
-class CM4AAtom_cmpl : public CMP4ContainerAtom
+// album artist
+// string
+class CiTunesAtom_aART : public CMP4ContainerAtom
{
public:
- CM4AAtom_cmpl() : CMP4ContainerAtom(MP4_BUILD_ATOMID('c','m','p','l'))
+ CiTunesAtom_aART() : CMP4ContainerAtom(MP4_BUILD_ATOMID('a','A','R','T'))
{}
};
-// tools
+// lyrics
// string
-class CM4AAtom_too : public CMP4ContainerAtom
+class CiTunesAtom_A9lyr : public CMP4ContainerAtom
{
public:
- CM4AAtom_too() : CMP4ContainerAtom(MP4_BUILD_ATOMID(0xa9,'t','o','o'))
+ CiTunesAtom_A9lyr() : CMP4ContainerAtom(MP4_BUILD_ATOMID(0xa9,'l','y','r'))
+ {}
+};
+
+// track number
+// special format
+class CiTunesAtom_trkn: public CMP4ContainerAtom
+{
+public:
+ CiTunesAtom_trkn() : CMP4ContainerAtom(MP4_BUILD_ATOMID('t','r','k','n'))
+ {}
+};
+
+// disc number
+// special format
+class CiTunesAtom_disk : public CMP4ContainerAtom
+{
+public:
+ CiTunesAtom_disk() : CMP4ContainerAtom(MP4_BUILD_ATOMID('d','i','s','k'))
+ {}
+};
+
+// predefined genre
+// uint16 array
+class CiTunesAtom_gnre : public CMP4ContainerAtom
+{
+public:
+ CiTunesAtom_gnre() : CMP4ContainerAtom(MP4_BUILD_ATOMID('g','n','r','e'))
+ {}
+};
+
+// beats per minute
+// signed int32
+class CiTunesAtom_tmpo : public CMP4ContainerAtom
+{
+public:
+ CiTunesAtom_tmpo() : CMP4ContainerAtom(MP4_BUILD_ATOMID('t','m','p','o'))
+ {}
+};
+
+// compilation
+// signed int8
+class CiTunesAtom_cpil : public CMP4ContainerAtom
+{
+public:
+ CiTunesAtom_cpil() : CMP4ContainerAtom(MP4_BUILD_ATOMID('c','p','i','l'))
+ {}
+};
+
+// content rating
+// signed int8
+class CiTunesAtom_rtng : public CMP4ContainerAtom
+{
+public:
+ CiTunesAtom_rtng() : CMP4ContainerAtom(MP4_BUILD_ATOMID('r','t','n','g'))
{}
};
#endif /* _M4AMDATOMS_H_ */
Index: mp4atoms.h
===================================================================
RCS file: /cvsroot/datatype/mp4/filewriter/mp4atoms.h,v
retrieving revision 1.14
diff -d -H -b -B -w -U30 -r1.14 mp4atoms.h
--- mp4atoms.h 23 May 2009 09:35:06 -0000 1.14
+++ mp4atoms.h 19 Oct 2009 13:17:01 -0000
@@ -429,60 +429,81 @@
class CMP4VersionedAtom : public CMP4Atom
{
public:
CMP4VersionedAtom(UINT32 uiAtomID)
: CMP4Atom(uiAtomID)
, m_ucVersion(0)
, m_uiFlags(0)
{
};
STDMETHOD_(UINT32, GetCurrentSize ) (THIS_ HXBOOL bIncludeChildren = FALSE)
{
return 8 + 1 + 3 + (bIncludeChildren ? GetSizeOfChildren() : 0);
}
protected:
// The derived object should set up the buffer first, then call us
void WriteAtomAndVersionInfo( UCHAR*& p )
{
UINT32 verflags = (((UINT32)m_ucVersion) << 24) | (m_uiFlags & 0x00ffffff);
// XXX the below GetCurrentSize() call should hit the most derived obj...
CMP4Atom::WriteToBufferAndInc( p, GetCurrentSize(TRUE) );
CMP4Atom::WriteToBufferAndInc( p, m_ulAtomID );
CMP4Atom::WriteToBufferAndInc( p, verflags );
}
UCHAR m_ucVersion;
UINT32 m_uiFlags; // actually 24 bit
};
+class CMP4VersionedContainerAtom : public CMP4VersionedAtom
+{
+public:
+ CMP4VersionedContainerAtom(UINT32 uiAtomID) : CMP4VersionedAtom(uiAtomID)
+ {}
+ STDMETHOD( WriteToBuffer )(THIS_ UCHAR*& pBuffer, HXBOOL bIncludeChildren=FALSE)
+ {
+ HX_RESULT retVal = HXR_OK;
+ if( pBuffer )
+ {
+ CMP4VersionedAtom::WriteAtomAndVersionInfo( pBuffer );
+ if( bIncludeChildren )
+ {
+ retVal = ChildrenWriteToBuffer( pBuffer );
+ }
+ }
+ return retVal;
+ }
+};
+
+
// Conceptually, there has to be a 'root' atom which represents
// the file itself; this atom is never written, and isn't really
// a container, but within it are all the top-level atoms,
// represented as children
// atom: file
// container: n/a
// purpose: provides a top level atom, specific to our implementation
class CMP4Atom_file : public CMP4Atom
{
public:
CMP4Atom_file() : CMP4Atom(MP4_BUILD_ATOMID('f','i','l','e'))
{}
STDMETHOD_(UINT32, GetCurrentSize ) (THIS_ HXBOOL bIncludeChildren = FALSE)
{
return bIncludeChildren ? GetSizeOfChildren() : 0;
}
STDMETHOD( WriteToBuffer ) (THIS_ UCHAR*& pBuffer,
HXBOOL bIncludeChildren=FALSE)
{
HX_RESULT retVal = HXR_NOTIMPL;
if( bIncludeChildren )
{
retVal = ChildrenWriteToBuffer( pBuffer );
}
return retVal;
}
};
// atom: ftyp
@@ -2554,62 +2575,70 @@
// way to retain the streeam data. instead, we have a length
// field which indicates the total number of bytes we actually
// wrote, and when queried for our size we give only our actual
// atom size (non inclusive of the bytes we wrote)
class CMP4Atom_mdat : public CMP4ContainerAtom
{
public:
CMP4Atom_mdat() : CMP4ContainerAtom(MP4_BUILD_ATOMID('m','d','a','t'))
{
m_uiBytesWritten = 0;
}
STDMETHOD( WriteToBuffer ) (THIS_ UCHAR*& pBuffer,
HXBOOL bIncludeChildren= FALSE)
{
HX_RESULT retVal = HXR_OK;
if( pBuffer )
{
CMP4Atom::WriteToBufferAndInc( pBuffer, GetCurrentSize() + m_uiBytesWritten );
CMP4Atom::WriteToBufferAndInc( pBuffer, m_ulAtomID );
}
// XXX we should never have children, so ignore bIncludeChildren
return retVal;
}
MP4_ATOM_PROPERTY(BytesWritten, UINT32, m_uiBytesWritten);
private:
UINT32 m_uiBytesWritten;
};
-
-
+// atom: meta
+// container: file, moov, trak
+// purpose: container for general (descriptive, annotative) meta-data
+// note: must contain hdlr atom as first child
+class CMP4Atom_meta : public CMP4VersionedContainerAtom
+{
+public:
+ CMP4Atom_meta() : CMP4VersionedContainerAtom(MP4_BUILD_ATOMID('m','e','t','a'))
+ {}
+};
////////////////////////////////////////////////////
//
// BEGIN: AMR NB, WB, WB+ MPEG4 (3GPP) Atoms Section
//
////////////////////////////////////////////////////
// 3GPP AMRSpecificBox, part of the AMRSampleEntry box. The same AMRSpecificBox
// is used for both the sample entry box for AMR-NB and AMR-WB.
class CMP4Atom_dAMR : public CMP4Atom
{
public:
CMP4Atom_dAMR() :
CMP4Atom(MP4_BUILD_ATOMID('d','a','m','r')),
m_ulDecoderInfoSize(0),
m_pDecoderInfo(NULL)
{
}
~CMP4Atom_dAMR()
{
HX_VECTOR_DELETE(m_pDecoderInfo);
}
STDMETHOD_(UINT32, GetCurrentSize ) (THIS_ HXBOOL bIncludeChildren = FALSE)
{
return 8 + m_ulDecoderInfoSize;
Index: mp4sm.cpp
===================================================================
RCS file: /cvsroot/datatype/mp4/filewriter/mp4sm.cpp,v
retrieving revision 1.19
diff -d -H -b -B -w -U30 -r1.19 mp4sm.cpp
--- mp4sm.cpp 16 Oct 2009 16:46:17 -0000 1.19
+++ mp4sm.cpp 19 Oct 2009 13:17:08 -0000
@@ -19,60 +19,61 @@
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the portions
* it created.
*
* This file, and the files included with this file, is distributed and made
* available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "hxassert.h"
#include "hxbuffer.h"
#include "chxpckts.h"
#include "pckunpck.h"
#include "mp4arch.h"
#include "mp4sm.h"
#include "mp4atoms.h"
#include "asmrulep.h"
#include "m4amdatoms.h"
#include "pspmeta.h"
#include "3gpmeta.h"
#include "metainfokeys.h"
+#include "metautil.h"
#include "iso639.h"
#include "proptools.h"
#include "private_clsids.h"
// Added for branching off to type specific atoms build
#include "mp4atomgateway.h"
#include "cspkt.h"
#define MP4_RESERVE_BLOCK_SIZE (1024)
#define MP4_DEFAULT_METADATA_RESERVE_SIZE (2 * 1024)
#define SAMPLERATE_AS_MEDIA_TIMESCALE 1
const UCHAR CPSPAtom_USMT::sm_userType[16] = {'U', 'S', 'M', 'T', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// class to handle managing the stbl, will eventually
// be pulled out into mp4fwlib
class CStblManager
{
public:
CStblManager(CMP4StreamMixer *pSm, CMP4Atom_stbl* pStbl, IHXValues* pStreamHdr, IUnknown* pContext)
{
m_pStreamMixer = pSm;
pSm->AddRef();
m_bFirstPacket = TRUE;
m_uiLastTimeStamp = 0;
m_uiSampleCounter = 0;
@@ -626,180 +627,197 @@
}
CMP4StreamMixer::HintInfo::HintInfo(CHXHintContext &hctx)
: hinting(hctx), trak(NULL), tkhd(NULL), mdhd(NULL), sdp(NULL), stblmgr(NULL), trackid(NULL)
{
}
CMP4StreamMixer::HintInfo::~HintInfo()
{
}
CMP4StreamMixer::CMP4StreamMixer(IUnknown* pContext, CMP4Archiver* pArchiver)
: m_lRefCount(0)
, m_ulLastTimestamp(0)
, m_ulActualDuration(0)
, m_ulReportedDuration(0)
, m_uiByteCount(0)
, m_uiReservedBlockCount(0)
, m_ulFirstTimestamp(0)
, m_eIsRtp(UNCHECKED)
, m_bMoovAtEnd(FALSE)
, m_bForceMoovFirst(FALSE)
, m_pMvhd(NULL)
, m_pFileHeader(NULL)
, m_pStreamInfo(NULL)
, m_ulStreamCount(0)
, m_ulStreamGroupCount(0)
, m_ulStreamHeaderReceived(0)
, m_ulStreamDoneReceived(0)
, m_eMetaFlavor(META_ITUNES)
+ , m_bRequestedOutputMetaFlavor3GPP(FALSE)
+ , m_bRequestedOutputMetaFlavorITUNES(FALSE)
, m_bUTF16Output(FALSE)
, m_e3gpMode(M3GPP_NONE)
, m_bTSInterleave(FALSE)
, m_bGenerateHintTracks(FALSE)
, m_uiBaseWriteOffset(0)
, m_uiCurrentOffset(0)
, m_uiGlobalFlush(0)
{
m_pContext = pContext;
HX_ADDREF(m_pContext);
HX_ASSERT( pArchiver );
m_pArchiver = pArchiver;
m_pArchiver->AddRef();
m_pRootAtom = new CMP4Atom_file();
HX_ASSERT( m_pRootAtom );
m_pRootAtom->AddRef();
}
CMP4StreamMixer::~CMP4StreamMixer()
{
HX_RELEASE( m_pArchiver );
HX_RELEASE( m_pRootAtom );
HX_RELEASE( m_pFileHeader );
HX_VECTOR_DELETE(m_pStreamInfo);
HX_RELEASE( m_pContext );
}
STDMETHODIMP CMP4StreamMixer::QueryInterface( THIS_ REFIID riid, void** ppvObj )
{
// dont support, for now
return HXR_NOINTERFACE;
}
STDMETHODIMP_(ULONG32) CMP4StreamMixer::AddRef()
{
return InterlockedIncrement( &m_lRefCount );
}
STDMETHODIMP_(ULONG32) CMP4StreamMixer::Release()
{
if( InterlockedDecrement( &m_lRefCount ) > 0 )
{
return m_lRefCount;
}
delete this;
return 0;
}
STDMETHODIMP CMP4StreamMixer::SetProperties( THIS_ IHXValues* pProperties )
{
- // UTF16 output option
ULONG32 ulVal = 0;
+
+ // Meta-data flavor options
+ PropTools::CopyPropertyULONG32(ulVal, pProperties, "MetaDataFlavor");
+
+ const ULONG32 METADATA_FLAVOR_3GPP = 0x00000001; //from ihxmetaeditor.h
+ m_bRequestedOutputMetaFlavor3GPP = (ulVal & METADATA_FLAVOR_3GPP) != 0;
+
+ const ULONG32 METADATA_FLAVOR_ITUNES = 0x00000010; //from ihxmetaeditor.h
+ m_bRequestedOutputMetaFlavorITUNES = (ulVal & METADATA_FLAVOR_ITUNES) != 0;
+
+ // UTF16 output option
PropTools::CopyPropertyULONG32(ulVal, pProperties, "UTF16Output");
m_bUTF16Output = ulVal ? TRUE : FALSE;
+ // Compatibility option
PropTools::CopyPropertyBuffer(m_spCompatibility, pProperties, "Compatibility");
+ // 3GPP Mode option
IHXBuffer *buf;
if (SUCCEEDED(pProperties->GetPropertyCString("3GPPMode", buf)))
{
UINT32 n = buf->GetSize();
const char *p3gpmode = (const char *)buf->GetBuffer();
if (n >= 4 && strncasecmp(p3gpmode, "none", 4) == 0)
{
m_e3gpMode = M3GPP_NONE;
}
else if (n >= 7 && strncasecmp(p3gpmode, "general", 7) == 0)
{
m_e3gpMode = M3GPP_GENERAL;
}
else if (n >= 5 && strncasecmp(p3gpmode, "basic", 5) == 0)
{
m_e3gpMode = M3GPP_BASIC;
}
else if (n >= 9 && strncasecmp(p3gpmode, "streaming", 9) == 0)
{
m_e3gpMode = M3GPP_STREAMING;
}
else if (n >= 6 && strncasecmp(p3gpmode, "progdl", 6) == 0)
{
m_e3gpMode = M3GPP_PROGDL;
}
else if (n >= 8 && strncasecmp(p3gpmode, "streamdl", 8) == 0)
{
m_e3gpMode = M3GPP_STREAMDL;
}
else if (n >= 4 && strncasecmp(p3gpmode, "rel5", 4) == 0)
{
m_e3gpMode = M3GPP_REL5;
}
HX_RELEASE(buf);
switch (m_e3gpMode)
{
case M3GPP_PROGDL:
case M3GPP_STREAMDL:
m_bTSInterleave = TRUE;
break;
default:
break;
}
}
// The default setting for hinting depends on the profile we are using
switch (m_e3gpMode)
{
case M3GPP_STREAMING:
case M3GPP_STREAMDL:
ulVal = 1;
break;
default:
ulVal = 0;
break;
}
+
+ // GenerateHintTracks option
pProperties->GetPropertyULONG32("GenerateHintTracks", ulVal);
m_bGenerateHintTracks = ulVal ? TRUE : FALSE;
+ // ForceMoovFirst option
ulVal = 0;
pProperties->GetPropertyULONG32("ForceMoovFirst", ulVal);
if (ulVal != 0)
{
m_bForceMoovFirst = TRUE;
}
return HXR_OK;
}
STDMETHODIMP CMP4StreamMixer::SetFileHeader( THIS_ IHXValues* pFileHeader )
{
HX_RESULT retVal = HXR_OK;
pFileHeader->AddRef();
m_pFileHeader = pFileHeader;
//get stream count; this may be bigger than the actual number of tracks in
//the output file, depending on how many NUL handlers are there
m_pFileHeader->GetPropertyULONG32("StreamCount", m_ulStreamCount);
m_pFileHeader->GetPropertyULONG32("StreamGroupCount", m_ulStreamGroupCount);
if (m_ulStreamCount)
{
m_pStreamInfo = new StreamInfo[m_ulStreamCount];
}
HX_ASSERT(m_pStreamInfo);
m_ulStreamHeaderReceived = 0;
@@ -1367,124 +1385,124 @@
CMP4Atom_free* pFree = NULL;
CMP4Atom_moov* pMoov = NULL;
CMP4Atom_mdat* pMdat = NULL;
pFtyp = new CMP4Atom_ftyp;
if( pFtyp )
{
m_pRootAtom->AddChild( pFtyp );
retVal = HXR_OK;
//try to guess file branding info by file extension
//default, MP4
pFtyp->SetMajorBrand("M4V ");
pFtyp->SetMinorVersion(0);
pFtyp->SetCompatibleBrands("M4V M4A mp42isom");
//default meta data flavor
m_eMetaFlavor = META_ITUNES;
CHXString fileExt;
if ( SUCCEEDED(m_pArchiver->GetFileExtension(fileExt)) )
{
if (stricmp(fileExt, ".3gp") == 0)
{
//3GP
pFtyp->SetMajorBrand("3gp7");
pFtyp->SetMinorVersion(0x200);
pFtyp->SetCompatibleBrands("3gp73gp6isom");
- m_eMetaFlavor = META_3GP;
+ m_eMetaFlavor = META_3GPP;
}
else
if (stricmp(fileExt, ".3g2") == 0)
{
//3G2
pFtyp->SetMajorBrand("3g2a");
pFtyp->SetCompatibleBrands("3g2a");
pFtyp->SetMinorVersion(0);
- m_eMetaFlavor = META_3GP;
+ m_eMetaFlavor = META_3GPP;
}
else
if ( stricmp(fileExt, ".m4a") == 0
|| stricmp(fileExt, ".m4p") == 0 )
{
//M4A, M4P
pFtyp->SetMajorBrand("M4A ");
pFtyp->SetMinorVersion(0);
pFtyp->SetCompatibleBrands("M4A mp42isom");
m_eMetaFlavor = META_ITUNES;
}
}
// When in proper 3GPP-mode, only include rel6/rel5 definitions.
// Note that we don't even check that everything is conformant,
// just adjust those things we can affect.
switch (m_e3gpMode)
{
case M3GPP_GENERAL:
pFtyp->SetMajorBrand("3gg6");
pFtyp->SetMinorVersion(0);
pFtyp->SetCompatibleBrands("3gg63gp6isom");
- m_eMetaFlavor = META_3GP;
+ m_eMetaFlavor = META_3GPP;
break;
case M3GPP_BASIC:
pFtyp->SetMajorBrand("3gp6");
pFtyp->SetMinorVersion(0);
pFtyp->SetCompatibleBrands("3gp63gp5isom");
- m_eMetaFlavor = META_3GP;
+ m_eMetaFlavor = META_3GPP;
break;
case M3GPP_STREAMING:
pFtyp->SetMajorBrand("3gs6");
pFtyp->SetMinorVersion(0);
pFtyp->SetCompatibleBrands("3gs63gg63gp5isom");
- m_eMetaFlavor = META_3GP;
+ m_eMetaFlavor = META_3GPP;
break;
case M3GPP_PROGDL:
pFtyp->SetMajorBrand("3gr6");
pFtyp->SetMinorVersion(0);
pFtyp->SetCompatibleBrands("3gr63gp63gg63gp5isom");
- m_eMetaFlavor = META_3GP;
+ m_eMetaFlavor = META_3GPP;
break;
case M3GPP_STREAMDL:
pFtyp->SetMajorBrand("3gs6");
pFtyp->SetMinorVersion(0);
pFtyp->SetCompatibleBrands("3gs63gr63gg63gp5isom");
- m_eMetaFlavor = META_3GP;
+ m_eMetaFlavor = META_3GPP;
break;
case M3GPP_REL5:
pFtyp->SetMajorBrand("3gp5");
pFtyp->SetMinorVersion(0);
pFtyp->SetCompatibleBrands("3gp53gp4isom");
- m_eMetaFlavor = META_3GP;
+ m_eMetaFlavor = META_3GPP;
break;
}
}
if( SUCCEEDED( retVal ) )
{
retVal = HXR_OUTOFMEMORY;
pMoov = new CMP4Atom_moov;
if( pMoov )
{
retVal = HXR_OK;
}
}
if( SUCCEEDED( retVal ) )
{
retVal = HXR_OUTOFMEMORY;
pMdat = new CMP4Atom_mdat();
if( pMdat )
{
retVal = HXR_OK;
}
}
if( SUCCEEDED( retVal ) )
{
if( m_bMoovAtEnd )
@@ -1581,69 +1599,69 @@
if (ulTrackType == MP4_BUILD_ATOMID('v','i','d','e'))
{
bHasVideo = TRUE;
}
}
}
}
}
for (UINT32 i = 0; i < m_ulStreamCount && SUCCEEDED(retVal); ++i)
{
HintInfo *hi = m_pStreamInfo[i].m_pHintInfo;
if (hi != NULL && hi->trak != NULL)
pMoov->AddChild(hi->trak);
}
}
// Do we need to generate a udta box that is a child
// of the moov box?
if (SUCCEEDED(retVal) && NeedToAddUdtaChildToMoovBox())
{
// Set the return value
retVal = HXR_OUTOFMEMORY;
// Create the udta box
CMP4Atom_udta* pUdta = new CMP4Atom_udta();
if (pUdta)
{
// Clear the return value
retVal = HXR_OK;
// Check the meta-data format we are supposed to generate
- if (m_eMetaFlavor == META_ITUNES)
+ if (m_bRequestedOutputMetaFlavorITUNES || (m_eMetaFlavor == META_ITUNES))
{
- // Build iPod meta-data
- BuildIPODMetaData(pUdta);
+ // Build iTunes meta-data
+ BuildiTunesMetaData(pUdta);
}
- else if (m_eMetaFlavor == META_3GP)
+ if (m_bRequestedOutputMetaFlavor3GPP || (m_eMetaFlavor == META_3GPP))
{
// Build 3GP meta-data
- Build3GPMetaData(pUdta);
+ Build3GPMetaData(pUdta, pMoov);
}
// Are we generating a hinted file?
if (m_bGenerateHintTracks)
{
// Add the hnti box as a child of the udta box
AddMovieHintInformation(pUdta);
}
// Add this udta box as a child of the moov box
pMoov->AddChild(pUdta);
}
}
// uuid/USMT atom for PSP style meta info
if( SUCCEEDED( retVal ) && m_eMetaFlavor == META_PSP )
{
retVal = HXR_OUTOFMEMORY;
CPSPAtom_USMT* pUsmt = new CPSPAtom_USMT();
if( pUsmt )
{
retVal = HXR_OK;
// Call out to build the metadata tree
BuildPSPMetaData( pUsmt );
pMoov->AddChild( pUsmt );
}
}
}
@@ -1720,118 +1738,133 @@
{
ulEstimatedSize += size + 40 +
HINTTRACK_SDP_FRAG_MAX_SIZE;
}
}
}
m_uiReservedBlockCount = 1 + (ulEstimatedSize / MP4_RESERVE_BLOCK_SIZE);
ulStblWriteOffset = 8 + (m_uiReservedBlockCount * MP4_RESERVE_BLOCK_SIZE);
}
m_uiBaseWriteOffset = ulStblWriteOffset;
m_uiCurrentOffset = 0;
}
return retVal;
}
HX_RESULT CMP4StreamMixer::BuildTrack( UINT16 usStreamNum, CMP4Atom* pTrak )
{
HX_RESULT retVal = HXR_OK;
UINT32 ulTrackType = MP4_BUILD_ATOMID('n','u','l','l');
m_pStreamInfo[usStreamNum].m_pStreamHeader->GetPropertyULONG32("TrackType", ulTrackType);
// Set up pTrak children
// trak
// tkhd
// mdia
+ // meta
if (SUCCEEDED(retVal))
{
// tkhd
retVal = HXR_OUTOFMEMORY;
m_pStreamInfo[usStreamNum].m_pTkhd = new CMP4Atom_tkhd();
if (m_pStreamInfo[usStreamNum].m_pTkhd)
{
retVal = HXR_OK;
// Assign the track ID we previously chose in ChooseTrackIDs()
m_pStreamInfo[usStreamNum].m_pTkhd->SetTrackID(m_pStreamInfo[usStreamNum].m_ulTrackID);
// Set the alternate group
UINT32 ulAlternateGroup = 0;
if (m_ulStreamGroupCount &&
m_pStreamInfo[usStreamNum].m_ulStreamGroupNumber != HX_INVALID_STREAM_GROUP_NUMBER &&
m_pStreamInfo[usStreamNum].m_ulStreamGroupNumber < m_ulStreamGroupCount)
{
ulAlternateGroup = m_pStreamInfo[usStreamNum].m_ulStreamGroupNumber + 1;
}
m_pStreamInfo[usStreamNum].m_pTkhd->SetAlternateGroup((UINT16) ulAlternateGroup);
if (ulTrackType == MP4_BUILD_ATOMID('v','i','d','e'))
{
UINT32 ulWidth = 0 , ulHeight = 0;
m_pStreamInfo[usStreamNum].m_pStreamHeader->GetPropertyULONG32("Width", ulWidth);
m_pStreamInfo[usStreamNum].m_pStreamHeader->GetPropertyULONG32("Height", ulHeight);
m_pStreamInfo[usStreamNum].m_pTkhd->SetWidth((UINT16) ulWidth);
m_pStreamInfo[usStreamNum].m_pTkhd->SetHeight((UINT16) ulHeight);
}
pTrak->AddChild( m_pStreamInfo[usStreamNum].m_pTkhd );
}
retVal = BuildMdia(usStreamNum, pTrak, NULL);
if (SUCCEEDED(retVal))
{
// Do we need to add a udta box child to this trak box?
if (NeedToAddUdtaChildToTrakBox((CMP4Atom_trak*) pTrak, (UINT32) usStreamNum))
{
// Set the return value
retVal = HXR_OUTOFMEMORY;
// Create a udta box
CMP4Atom_udta* pUdtaBox = new CMP4Atom_udta();
if (pUdtaBox)
{
// Clear the return value
retVal = HXR_OK;
// Add this child to the trak box
pTrak->AddChild(pUdtaBox);
// Handle switch groups here. This will check to see if
// there is a "SwitchGroupID" property in the stream header,
// and if so, add a tsel child box to the udta box.
SetSwitchGroup(pUdtaBox, (UINT32) usStreamNum);
}
}
}
+
+ // build meta atom at stream level (3GPP flavor only)
+ if( SUCCEEDED( retVal ) &&
+ (m_eMetaFlavor == META_3GPP || m_bRequestedOutputMetaFlavor3GPP))
+ {
+ // ID32, setup box hierarchy: trak/meta/[hdlr, ID32]
+ CMP4Atom_meta* pMeta = NULL;
+ retVal = Build3GPMetaDataID32(m_pStreamInfo[usStreamNum].m_pStreamHeader, &pMeta);
+
+ if( SUCCEEDED( retVal ) && pMeta )
+ {
+ retVal = pTrak->AddChild( pMeta );
+ }
+ }
}
if (SUCCEEDED(retVal) && m_bGenerateHintTracks)
{
HintInfo *hi = new HintInfo(m_HintContext);
if (hi == NULL)
{
return HXR_OUTOFMEMORY;
}
retVal = hi->hinting.SetStreamHeader(m_pStreamInfo[usStreamNum].m_pStreamHeader);
if (SUCCEEDED(retVal))
{
m_pStreamInfo[usStreamNum].m_pHintInfo = hi;
// Assign the trackID we chose in ChooseTrackIDs()
hi->trackid = m_pStreamInfo[usStreamNum].m_ulHintTrackID;
// Set the hint track ID into the stream header
m_pStreamInfo[usStreamNum].m_pStreamHeader->SetPropertyULONG32("TrackID", hi->trackid);
hi->trak = new CMP4Atom_trak;
if (hi->trak == NULL)
{
return HXR_OUTOFMEMORY;
}
hi->tkhd = new CMP4Atom_tkhd;
if (hi->tkhd == NULL)
{
return HXR_OUTOFMEMORY;
}
@@ -1972,63 +2005,65 @@
{
// The first question is: does the trak box already HAVE a udta box child? If
// so then we don't need to add another one.
CMP4Atom_udta* pUdtaBox = (CMP4Atom_udta*) pTrakBox->FindChild(MP4_BUILD_ATOMID('u','d','t','a'));
if (!pUdtaBox)
{
// The trak box does not already have a udta child. The next question is: is this
// stream involved in a switch group? If so, then we will need a udta box child
// of the trak box in order to put our tsel (track selection) box in.
if (IsStreamInSwitchGroup(ulStreamNumber))
{
// For now, these are the only criteria. So if we made it here, we need
// to add a udta child to this trak box.
// XXXMEH - if we are hinting, we always add a udta box to the trak
// box for the hint track. However, if we are doing hinting of
// single-rate streams, then it's unclear if the trak box for the
// media tracks need udta children or not. For now, I'll assume that
// we only need udta children for media trak boxes if that track
// is in a switch group.
bRet = TRUE;
}
}
}
return bRet;
}
HXBOOL CMP4StreamMixer::NeedToAddUdtaChildToMoovBox()
{
// We need to generate a udta box as a child of the moov box if
- // we are either generating iTunes or 3GP meta-data OR we
+ // we are either generating iTunes or 3GPP meta-data OR we
// are generating hint tracks.
- return (m_eMetaFlavor == META_ITUNES || m_eMetaFlavor == META_3GP || m_bGenerateHintTracks);
+ return (m_bRequestedOutputMetaFlavorITUNES || m_eMetaFlavor == META_ITUNES
+ || m_bRequestedOutputMetaFlavor3GPP || m_eMetaFlavor == META_3GPP
+ || m_bGenerateHintTracks);
}
HX_RESULT
CMP4StreamMixer::AddMovieHintInformation(CMP4Atom_udta* pUdta)
{
HX_RESULT retVal = HXR_INVALID_PARAMETER;
if (pUdta)
{
// Clear the return value
retVal = HXR_OK;
// Does this udta box already have a hnti child box?
CMP4Atom_hnti* pHnti = (CMP4Atom_hnti*) pUdta->FindChild(MP4_BUILD_ATOMID('h','n','t','i'));
if (!pHnti)
{
// Set the return value
retVal = HXR_OUTOFMEMORY;
// This udta box does NOT already have a hnti child box, so create one
pHnti = new CMP4Atom_hnti();
if (pHnti)
{
// Create a CMP4Atom_RTPMovieHintInformation child box
CMP4Atom_RTPMovieHintInformation* pRTP = new CMP4Atom_RTPMovieHintInformation();
if (pRTP)
{
// Generate the movie-level SDP
CHXString strMovieLevelSDP;
retVal = GenerateMovieLevelSDP(&strMovieLevelSDP);
if (SUCCEEDED(retVal))
{
@@ -3387,262 +3422,566 @@
{
retVal = HXR_OK;
pStbl->AddChild( pStco );
}
}
if( SUCCEEDED( retVal ) )
{
if (pHinfo == NULL)
{
retVal = HXR_OUTOFMEMORY;
// pass off the stbl atom to the stbl manager
m_pStreamInfo[usStreamNum].m_pStblManager = new CStblManager(this, pStbl, m_pStreamInfo[usStreamNum].m_pStreamHeader, m_pContext);
if( m_pStreamInfo[usStreamNum].m_pStblManager )
{
retVal = HXR_OK;
}
}
else
{
pHinfo->stblmgr = new CStblManager(this, pStbl, m_pStreamInfo[usStreamNum].m_pStreamHeader, m_pContext);
retVal = pHinfo->stblmgr == NULL ? HXR_OUTOFMEMORY : HXR_OK;
}
}
return retVal;
}
-HX_RESULT CMP4StreamMixer::BuildIPODMetaData( CMP4Atom* pUdta )
+// iTunes Utilities
+class iTunesMetadataTransferPort
+{
+public:
+ iTunesMetadataTransferPort()
+ : m_ulLengthLimit(0)
+ , m_bUTF16Output(FALSE)
+ {
+ }
+
+ virtual ~iTunesMetadataTransferPort() {;}
+ virtual HXBOOL ExtractData(IHXValues& values, const char* szPropName) = 0;
+ virtual HX_RESULT InjectData(CiTunesAtom_data& dataAtom) = 0;
+
+ void SetUTF16Output(HXBOOL bUTF16 = FALSE)
+ {
+ m_bUTF16Output = bUTF16;
+ }
+
+ // LengthLimit=0 means no limit
+ void SetLengthLimit(ULONG32 ulLengthLimit = 0)
+ {
+ m_ulLengthLimit = ulLengthLimit;
+ }
+
+ ULONG32 CalcInjectedStringByteLength(const EncodedString& es)
+ {
+ ULONG32 codeUnitLen = es.GetCodeUnitLength(FALSE, FALSE);
+ if((m_ulLengthLimit > 0) && (codeUnitLen > m_ulLengthLimit))
+ {
+ // only cover encoding we're exporting to atoms
+ switch(es.GetEncoding())
+ {
+ case HX_TEXT_ENCODING_TYPE_UTF16BE:
+ return m_ulLengthLimit * 2;
+
+ case HX_TEXT_ENCODING_TYPE_UTF8:
+ return m_ulLengthLimit;
+ }
+ }
+ return es.GetByteLength(FALSE);
+ }
+
+protected:
+ ULONG32 m_ulLengthLimit;
+ HXBOOL m_bUTF16Output;
+};
+
+class iTunesStringTransferPort : public iTunesMetadataTransferPort
+{
+public:
+ virtual HXBOOL ExtractData(IHXValues& values, const char* szPropName)
+ {
+ return szPropName ? PropTools::CopyPropertyBuffer(m_strValue, &values, szPropName) : FALSE;
+ }
+ virtual HX_RESULT InjectData(CiTunesAtom_data& dataAtom)
+ {
+ if(m_bUTF16Output)
+ {
+ // big-endian, no BOM, no terminator
+ EncodedString strValueOut;
+ if(m_strValue.ConvertToUTF16(strValueOut, TRUE, FALSE))
+ {
+ return dataAtom.SetUTF16BEString(strValueOut.GetData(), CalcInjectedStringByteLength(strValueOut));
+ }
+ return HXR_FAILED;
+ }
+
+ // UTF8
+ EncodedString strValueOut;
+ if(m_strValue.ConvertToUTF8(strValueOut))
+ {
+ // no terminator
+ return dataAtom.SetUTF8String(strValueOut.GetData(), CalcInjectedStringByteLength(strValueOut));
+ }
+ return HXR_FAILED;
+ }
+
+private:
+ EncodedString m_strValue;
+};
+
+class iTunesULongTransferPort : public iTunesMetadataTransferPort
+{
+public:
+ iTunesULongTransferPort() : m_ulValue(0)
+ {;}
+
+ virtual HXBOOL ExtractData(IHXValues& values, const char* szPropName)
+ {
+ return szPropName ? PropTools::CopyPropertyULONG32(m_ulValue, &values, szPropName) : FALSE;
+ }
+
+protected:
+ ULONG32 m_ulValue;
+};
+
+class iTunesUInteger32TransferPort : public iTunesULongTransferPort
+{
+public:
+ virtual HX_RESULT InjectData(CiTunesAtom_data& dataAtom)
+ {
+ return dataAtom.SetUInteger32(m_ulValue);
+ }
+};
+
+class iTunesUInteger16TransferPort : public iTunesULongTransferPort
+{
+public:
+ virtual HX_RESULT InjectData(CiTunesAtom_data& dataAtom)
+ {
+ return dataAtom.SetUInteger16(m_ulValue);
+ }
+};
+
+class iTunesUInteger8TransferPort : public iTunesULongTransferPort
+{
+public:
+ virtual HX_RESULT InjectData(CiTunesAtom_data& dataAtom)
+ {
+ return dataAtom.SetUInteger8(m_ulValue);
+ }
+};
+
+class iTunesRecordingYearTransferPort : public iTunesULongTransferPort
+{
+public:
+ virtual HX_RESULT InjectData(CiTunesAtom_data& dataAtom)
+ {
+ // Release date is in YYYY-MM-DD format, trailing fields can be omitted so we will write out YYYY.
+ ULONG32 uRecYear = (m_ulValue <= 9999) ? m_ulValue : 0;
+
+ char szOutputBuffer[8];
+ sprintf(szOutputBuffer, "%04d", uRecYear);
+
+ EncodedString strRecYearUTF8(szOutputBuffer, HX_TEXT_ENCODING_TYPE_UTF8);
+
+ // always output UTF8, no terminator
+ return dataAtom.SetUTF8String(strRecYearUTF8.GetData(), strRecYearUTF8.GetByteLength(FALSE));
+ }
+};
+
+void CMP4StreamMixer::MetaiTunes_AddItemAtom(HX_RESULT& retVal, CiTunesAtom_ilst* pIlst,
+ const char* pPropName, iTunesMetadataTransferPort& transfer)
+{
+ if( FAILED(retVal) )
+ {
+ return;
+ }
+
+ if( !pPropName || !pIlst )
+ {
+ retVal = HXR_INVALID_PARAMETER;
+ return;
+ }
+
+ if( !m_pFileHeader )
+ {
+ retVal = HXR_FAILED;
+ return;
+ }
+
+ if( transfer.ExtractData(*m_pFileHeader, pPropName) )
+ {
+ CMP4ContainerAtom* pItem = 0;
+ retVal = MetaiTunes_CreateItemAtomFromPropertyName(pPropName, &pItem);
+
+ if( SUCCEEDED(retVal) && pItem )
+ {
+ retVal = HXR_OUTOFMEMORY;
+
+ CiTunesAtom_data* pData = new CiTunesAtom_data();
+ if( pData )
+ {
+ retVal = transfer.InjectData(*pData);
+
+ if( SUCCEEDED( retVal ) )
+ {
+ pItem->AddChild( pData );
+ pIlst->AddChild( pItem );
+ }
+ }
+
+ if( FAILED( retVal ) )
+ {
+ delete pData;
+ delete pItem;
+ }
+ }
+ }
+}
+
+HX_RESULT CMP4StreamMixer::MetaiTunes_CreateItemAtomFromPropertyName(const char* pPropName, CMP4ContainerAtom** ppItemAtom)
+{
+ if( !ppItemAtom || *ppItemAtom )
+ {
+ return HXR_INVALID_PARAMETER;
+ }
+
+ HX_RESULT retVal = HXR_OK;
+
+ if (!strcmp(pPropName, _ITUNES_META_INFO_TITLE_KEY))
+ {
+ *ppItemAtom = new CiTunesAtom_A9nam();
+ }
+ else if (!strcmp(pPropName, _ITUNES_META_INFO_ARTIST_KEY))
+ {
+ *ppItemAtom = new CiTunesAtom_A9ART();
+ }
+ else if (!strcmp(pPropName, _ITUNES_META_INFO_COPYRIGHT_KEY))
+ {
+ *ppItemAtom = new CiTunesAtom_cprt();
+ }
+ else if (!strcmp(pPropName, _ITUNES_META_INFO_COMPOSER_KEY))
+ {
+ *ppItemAtom = new CiTunesAtom_A9wrt();
+ }
+ else if (!strcmp(pPropName, _ITUNES_META_INFO_COMMENT_KEY))
+ {
+ *ppItemAtom = new CiTunesAtom_A9cmt();
+ }
+ else if (!strcmp(pPropName, _ITUNES_META_INFO_ALBUM_KEY))
+ {
+ *ppItemAtom = new CiTunesAtom_A9alb();
+ }
+ else if (!strcmp(pPropName, _ITUNES_META_INFO_GENRE_KEY))
+ {
+ *ppItemAtom = new CiTunesAtom_A9gen();
+ }
+ else if (!strcmp(pPropName, _ITUNES_META_INFO_TRACK_SUBTITLE_KEY))
+ {
+ *ppItemAtom = new CiTunesAtom_A9st3();
+ }
+ else if (!strcmp(pPropName, _ITUNES_META_INFO_GENERATOR_TOOL_KEY))
+ {
+ *ppItemAtom = new CiTunesAtom_A9too();
+ }
+ else if (!strcmp(pPropName, _ITUNES_META_INFO_GROUPING_KEY))
+ {
+ *ppItemAtom = new CiTunesAtom_grup();
+ }
+ else if (!strcmp(pPropName, _ITUNES_META_INFO_ALBUM_ARTIST_KEY))
+ {
+ *ppItemAtom = new CiTunesAtom_aART();
+ }
+ else if (!strcmp(pPropName, _ITUNES_META_INFO_LYRICS_KEY))
+ {
+ *ppItemAtom = new CiTunesAtom_A9lyr();
+ }
+ else if (!strcmp(pPropName, _ITUNES_META_INFO_RELEASE_DATE_KEY))
+ {
+ *ppItemAtom = new CiTunesAtom_A9day();
+ }
+ else if (!strcmp(pPropName, _ITUNES_META_INFO_BEATS_PER_MINUTE_KEY))
+ {
+ *ppItemAtom = new CiTunesAtom_tmpo();
+ }
+ else if (!strcmp(pPropName, _ITUNES_META_INFO_PART_OF_COMPILATION_KEY))
+ {
+ *ppItemAtom = new CiTunesAtom_cpil();
+ }
+ else if (!strcmp(pPropName, _ITUNES_META_INFO_EXPLICIT_CONTENT_KEY))
+ {
+ *ppItemAtom = new CiTunesAtom_rtng();
+ }
+ else
+ {
+ // unknown property name
+ retVal = HXR_INVALID_PARAMETER;
+ }
+
+ if ( SUCCEEDED(retVal) && !(*ppItemAtom) )
+ {
+ retVal = HXR_OUTOFMEMORY;
+ }
+
+ return retVal;
+}
+
+HX_RESULT CMP4StreamMixer::BuildiTunesMetaData( CMP4Atom* pUdta )
{
HX_RESULT retVal = HXR_OUTOFMEMORY;
// The metadata tree looks like this
// udta
// meta
// hdlr
// ilst
// free
- CM4AAtom_meta* pMeta = new CM4AAtom_meta();
+ CiTunesAtom_meta* pMeta = new CiTunesAtom_meta();
if( pMeta )
{
retVal = HXR_OK;
pUdta->AddChild( pMeta );
}
CMP4Atom_free* pFree = NULL;
- CM4AAtom_ilst* pIlst = NULL;
+ CiTunesAtom_ilst* pIlst = NULL;
if( SUCCEEDED( retVal ) )
{
retVal = HXR_OUTOFMEMORY;
// hdlr
- CM4AAtom_hdlr* pHdlr = new CM4AAtom_hdlr();
+ CiTunesAtom_hdlr* pHdlr = new CiTunesAtom_hdlr();
if( pHdlr )
{
retVal = HXR_OK;
pMeta->AddChild( pHdlr );
}
// ilst
if( SUCCEEDED( retVal ) )
{
retVal = HXR_OUTOFMEMORY;
- pIlst = new CM4AAtom_ilst();
+ pIlst = new CiTunesAtom_ilst();
if( pIlst )
{
retVal = HXR_OK;
pMeta->AddChild( pIlst );
}
}
// free. only create this if we are putting moov in the middle
if( !m_bMoovAtEnd && !m_bForceMoovFirst)
{
if( SUCCEEDED( retVal ) )
{
retVal = HXR_OUTOFMEMORY;
pFree = new CMP4Atom_free();
if( pFree )
{
retVal = HXR_OK;
// reserve space for metadata
pFree->SetFreeSize(MP4_DEFAULT_METADATA_RESERVE_SIZE);
pMeta->AddChild( pFree );
}
}
}
}
// Now build out the ilst
if( SUCCEEDED( retVal ) )
{
- CM4AAtom_data* pData = NULL;
- IHXBuffer* pBuf = NULL;
+ // string properties
+ // Although not mentioned by iTMF spec, iTunes have 255 character limit on string properties.
+ const ULONG32 ulStringLengthLimit = 255;
- if( SUCCEEDED( m_pFileHeader->GetPropertyBuffer( "Author", pBuf ) ) && pBuf )
- {
- retVal = HXR_OUTOFMEMORY;
+ iTunesStringTransferPort stringTranferPort;
+ stringTranferPort.SetLengthLimit(ulStringLengthLimit);
+ stringTranferPort.SetUTF16Output(m_bUTF16Output);
- CM4AAtom_art* pArtist = new CM4AAtom_art();
- if( pArtist )
- {
- retVal = HXR_OUTOFMEMORY;
- pData = new CM4AAtom_data();
- if( pData )
- {
- retVal = pData->SetString( pBuf->GetBuffer() );
+ MetaiTunes_AddItemAtom(retVal, pIlst, _ITUNES_META_INFO_TITLE_KEY, stringTranferPort);
+ MetaiTunes_AddItemAtom(retVal, pIlst, _ITUNES_META_INFO_COMPOSER_KEY, stringTranferPort);
+ MetaiTunes_AddItemAtom(retVal, pIlst, _ITUNES_META_INFO_COPYRIGHT_KEY, stringTranferPort);
+ MetaiTunes_AddItemAtom(retVal, pIlst, _ITUNES_META_INFO_COMMENT_KEY, stringTranferPort);
+ MetaiTunes_AddItemAtom(retVal, pIlst, _ITUNES_META_INFO_ARTIST_KEY, stringTranferPort);
+ MetaiTunes_AddItemAtom(retVal, pIlst, _ITUNES_META_INFO_GENRE_KEY, stringTranferPort);
+ MetaiTunes_AddItemAtom(retVal, pIlst, _ITUNES_META_INFO_ALBUM_KEY, stringTranferPort);
+ MetaiTunes_AddItemAtom(retVal, pIlst, _ITUNES_META_INFO_TRACK_SUBTITLE_KEY, stringTranferPort);
+ MetaiTunes_AddItemAtom(retVal, pIlst, _ITUNES_META_INFO_GENERATOR_TOOL_KEY, stringTranferPort);
+ MetaiTunes_AddItemAtom(retVal, pIlst, _ITUNES_META_INFO_GROUPING_KEY, stringTranferPort);
+ MetaiTunes_AddItemAtom(retVal, pIlst, _ITUNES_META_INFO_ALBUM_ARTIST_KEY, stringTranferPort);
+
+ // Lyrics atom (which is not described by iTMF spec) does not have 255 character limit.
+ // However it must be in UTF8 format.
+ stringTranferPort.SetLengthLimit(0);
+ stringTranferPort.SetUTF16Output(FALSE);
+ MetaiTunes_AddItemAtom(retVal, pIlst, _ITUNES_META_INFO_LYRICS_KEY, stringTranferPort);
+
+ // predefined genre
if( SUCCEEDED( retVal ) )
{
- pArtist->AddChild( pData );
- pIlst->AddChild( pArtist );
- pData = NULL;
- }
- }
- }
- HX_RELEASE( pBuf );
- }
- if( SUCCEEDED( m_pFileHeader->GetPropertyBuffer( "Title", pBuf ) ) && pBuf )
+ // try converting user defined genres to the list of ID3 predefined genres
+ EncodedString strGenres;
+ if(PropTools::CopyPropertyBuffer(strGenres, m_pFileHeader, _ITUNES_META_INFO_GENRE_KEY))
{
- retVal = HXR_OUTOFMEMORY;
-
- CM4AAtom_nam* pName = new CM4AAtom_nam();
- if( pName )
+ // need UTF8 to compare with ID3 names
+ EncodedString strGenresUTF8;
+ if(strGenres.ConvertToUTF8(strGenresUTF8))
{
- retVal = HXR_OUTOFMEMORY;
- pData = new CM4AAtom_data();
- if( pData )
+ // iTunes user defined genre can be a comma separated list
+ CHXPtrArray genreEntries;
+ if(ID3Tools::ParseGenreNameList(genreEntries, strGenresUTF8.GetData(), FALSE, ',', TRUE))
{
- retVal = pData->SetString( pBuf->GetBuffer() );
- if( SUCCEEDED( retVal ) )
+ // iTunes stores genre ordinals with ID3 value +1
+ for(ULONG32 i = 0; i < genreEntries.GetSize(); i++)
{
- pName->AddChild( pData );
- pIlst->AddChild( pName );
- pData = NULL;
- }
- }
- }
- HX_RELEASE( pBuf );
+ UINT8 uGenreOrdinal = (UINT8)(ULONG32)genreEntries.GetAt(i) + 1;
+ genreEntries.SetAt(i, (void*)(ULONG32)uGenreOrdinal);
}
- if( SUCCEEDED( m_pFileHeader->GetPropertyCString( "Generated By", pBuf ) ) && pBuf )
- {
retVal = HXR_OUTOFMEMORY;
- CM4AAtom_too* pTools = new CM4AAtom_too();
- if( pTools )
- {
- retVal = HXR_OUTOFMEMORY;
- pData = new CM4AAtom_data();
- if( pData )
- {
- retVal = pData->SetString( pBuf->GetBuffer() );
- if( SUCCEEDED( retVal ) )
+ CiTunesAtom_gnre* pItem = new CiTunesAtom_gnre();
+ CiTunesAtom_data* pData = new CiTunesAtom_data();
+
+ if(pItem && pData)
{
- pTools->AddChild( pData );
- pIlst->AddChild( pTools );
- pData = NULL;
+ retVal = pData->SetSpecial_PredefinedGenreEntries(genreEntries);
+ }
+
+ MetaiTunes_LinkAtoms(retVal, pIlst, pItem, pData);
}
}
}
- HX_RELEASE( pBuf );
}
- if( SUCCEEDED( m_pFileHeader->GetPropertyBuffer( "Genre", pBuf ) ) && pBuf )
+ // recording year (type conversion), always outputed as UTF8
+ iTunesRecordingYearTransferPort recYearTranferPort;
+ MetaiTunes_AddItemAtom(retVal, pIlst, _ITUNES_META_INFO_RELEASE_DATE_KEY, recYearTranferPort);
+
+ // BPM should be 32 bits according to iTMF spec, but most implementations expect 16 bits
+ iTunesUInteger16TransferPort uint16TranferPort;
+ MetaiTunes_AddItemAtom(retVal, pIlst, _ITUNES_META_INFO_BEATS_PER_MINUTE_KEY, uint16TranferPort);
+
+ // uint8 properties
+ iTunesUInteger8TransferPort uint8TranferPort;
+ MetaiTunes_AddItemAtom(retVal, pIlst, _ITUNES_META_INFO_PART_OF_COMPILATION_KEY, uint8TranferPort);
+ MetaiTunes_AddItemAtom(retVal, pIlst, _ITUNES_META_INFO_EXPLICIT_CONTENT_KEY, uint8TranferPort);
+
+ // track number/count
+ if(SUCCEEDED(retVal))
{
- retVal = HXR_OUTOFMEMORY;
+ ULONG32 ulTrackNumber = 0;
+ HXBOOL bHaveTN = PropTools::CopyPropertyULONG32(ulTrackNumber, m_pFileHeader, _ITUNES_META_INFO_TRACK_NUMBER_KEY);
- CM4AAtom_gen* pGenre = new CM4AAtom_gen();
- if( pGenre )
+ ULONG32 ulTrackCount = 0;
+ HXBOOL bHaveTC = PropTools::CopyPropertyULONG32(ulTrackCount, m_pFileHeader, _ITUNES_META_INFO_TRACK_COUNT_KEY);
+
+ if(bHaveTN || bHaveTC)
{
retVal = HXR_OUTOFMEMORY;
- pData = new CM4AAtom_data();
- if( pData )
- {
- retVal = pData->SetString( pBuf->GetBuffer() );
- if( SUCCEEDED( retVal ) )
+
+ CiTunesAtom_trkn* pItem = new CiTunesAtom_trkn();
+ CiTunesAtom_data* pData = new CiTunesAtom_data();
+
+ if(pItem && pData)
{
- pGenre->AddChild( pData );
- pIlst->AddChild( pGenre );
- pData = NULL;
- }
+ retVal = pData->SetSpecial_TrackNumberCount(ulTrackNumber, ulTrackCount);
}
+
+ MetaiTunes_LinkAtoms(retVal, pIlst, pItem, pData);
}
- HX_RELEASE( pBuf );
}
- if( SUCCEEDED( m_pFileHeader->GetPropertyBuffer( "Album", pBuf ) ) && pBuf )
+
+ // disc number/count
+ if(SUCCEEDED(retVal))
{
- retVal = HXR_OUTOFMEMORY;
+ ULONG32 ulDiscNumber = 0;
+ HXBOOL bHaveDN = PropTools::CopyPropertyULONG32(ulDiscNumber, m_pFileHeader, _ITUNES_META_INFO_DISC_NUMBER_KEY);
- CM4AAtom_alb* pAlbum = new CM4AAtom_alb();
- if( pAlbum )
+ ULONG32 ulDiscCount = 0;
+ HXBOOL bHaveDC = PropTools::CopyPropertyULONG32(ulDiscCount, m_pFileHeader, _ITUNES_META_INFO_DISC_COUNT_KEY);
+
+ if(bHaveDN || bHaveDC)
{
retVal = HXR_OUTOFMEMORY;
- pData = new CM4AAtom_data();
- if( pData )
- {
- retVal = pData->SetString( pBuf->GetBuffer() );
- if( SUCCEEDED( retVal ) )
+
+ CiTunesAtom_disk* pItem = new CiTunesAtom_disk();
+ CiTunesAtom_data* pData = new CiTunesAtom_data();
+
+ if(pItem && pData)
{
- pAlbum->AddChild( pData );
- pIlst->AddChild( pAlbum );
- pData = NULL;
- }
+ retVal = pData->SetSpecial_DiscNumberCount(ulDiscNumber, ulDiscCount);
}
+
+ MetaiTunes_LinkAtoms(retVal, pIlst, pItem, pData);
}
- HX_RELEASE( pBuf );
}
-
}
// Resize our free atom (if present) given our new metadata
if( SUCCEEDED( retVal ) && pFree )
{
UINT32 size = pUdta->GetCurrentSize( TRUE );
size -= MP4_DEFAULT_METADATA_RESERVE_SIZE;
pFree->SetFreeSize( MP4_DEFAULT_METADATA_RESERVE_SIZE - size );
}
return retVal;
}
+void CMP4StreamMixer::MetaiTunes_LinkAtoms(HX_RESULT& retVal, CiTunesAtom_ilst* pIlst, CMP4ContainerAtom* pItem, CiTunesAtom_data* pData)
+{
+ if(SUCCEEDED(retVal) && pIlst && pItem && pData)
+ {
+ pItem->AddChild(pData);
+ pIlst->AddChild(pItem);
+ }
+
+ if(FAILED(retVal) || !pItem || !pData)
+ {
+ delete pItem;
+ delete pData;
+ }
+}
+
HX_RESULT CMP4StreamMixer::BuildPSPMetaData( CMP4Atom* pUsmt )
{
HX_RESULT retVal = HXR_OUTOFMEMORY;
CPSPAtom_MTDT* pMtdt = new CPSPAtom_MTDT();
if( pMtdt )
{
retVal = HXR_OK;
pUsmt->AddChild( pMtdt );
}
if( SUCCEEDED( retVal ) )
{
IHXBuffer* pBuf = NULL;
if( SUCCEEDED( m_pFileHeader->GetPropertyBuffer( "Author", pBuf ) ) && pBuf )
{
pMtdt->SetAuthor( (const char*)pBuf->GetBuffer() );
HX_RELEASE( pBuf );
}
if( SUCCEEDED( m_pFileHeader->GetPropertyBuffer( "Title", pBuf ) ) && pBuf )
{
pMtdt->SetTitle( (const char*)pBuf->GetBuffer() );
HX_RELEASE( pBuf );
}
}
@@ -3777,61 +4116,61 @@
HXBOOL CMP4StreamMixer::Meta3GP_ExtractFixedPoint(const EncodedString& s, INT32& outWhole, UINT32& outFrac, UINT32& outFixed)
{
if(s.IsEmpty() || !s.IsAsciiOnly())
{
return FALSE;
}
EncodedString val;
s.ConvertToUTF8(val);
if(!val.GetData())
{
return FALSE;
}
// ignore trailing junk; if there's any, it won't be written to the file anyway
if(sscanf(val.GetData(), "%ld.%lu", &outWhole, &outFrac) == 2)
{
outFixed = (outWhole << 16) | (outFrac << 0);
return TRUE;
}
if(sscanf(val.GetData(), "%ld", &outWhole) == 1)
{
outFrac = 0;
outFixed = (outWhole << 16);
return TRUE;
}
return FALSE;
}
-HX_RESULT CMP4StreamMixer::Build3GPMetaData( CMP4Atom* pUdta )
+HX_RESULT CMP4StreamMixer::Build3GPMetaData( CMP4Atom* pUdta, CMP4Atom* pMoov )
{
HX_RESULT retVal = HXR_OK;
// configure UTF16 output
C3GPAtom_LangBase::ConfigureStringOutput(m_bUTF16Output);
// Title
Meta3GP_AddAtom_StringBase(retVal, pUdta, new C3GPAtom_titl(), _3GPP_META_INFO_TITLE_KEY);
// Description
Meta3GP_AddAtom_StringBase(retVal, pUdta, new C3GPAtom_dscp(), _3GPP_META_INFO_DESCRIPTION_KEY);
// Copyright
Meta3GP_AddAtom_StringBase(retVal, pUdta, new C3GPAtom_cprt(), _3GPP_META_INFO_COPYRIGHT_KEY);
// Performer
Meta3GP_AddAtom_StringBase(retVal, pUdta, new C3GPAtom_perf(), _3GPP_META_INFO_PERFORMER_KEY);
// Author
Meta3GP_AddAtom_StringBase(retVal, pUdta, new C3GPAtom_auth(), _3GPP_META_INFO_AUTHOR_KEY);
// Genre
Meta3GP_AddAtom_StringBase(retVal, pUdta, new C3GPAtom_gnre(), _3GPP_META_INFO_GENRE_KEY);
// Rating
C3GPAtom_rtng* pRtng = new C3GPAtom_rtng();
if( Meta3GP_NewAtomGuard(retVal, pRtng) )
{
retVal = HXR_OK;
@@ -3846,139 +4185,139 @@
UINT32 uCriteria = 0;
EncodedString sCriteria;
HXBOOL resCrit = PropTools::CopyPropertyBuffer(sCriteria, m_pFileHeader, _3GPP_META_INFO_RATING_CRITERIA_KEY);
if(resCrit)
{
Meta3GP_ExtractUINT32(sCriteria, uCriteria);
}
EncodedString sInfo;
HXBOOL resInfo = PropTools::CopyPropertyBuffer(sInfo, m_pFileHeader, _3GPP_META_INFO_RATING_INFO_KEY);
if(resEnt || resCrit || resInfo)
{
if(resEnt)
{
pRtng->SetRatingEntity(uEntity);
}
if(resCrit)
{
pRtng->SetRatingCriteria(uCriteria);
}
if(resInfo)
{
pRtng->SetString_RatingInfo(sInfo.GetData(), sInfo.GetEncoding());
}
Meta3GP_SetLanguageEncoding(pRtng);
pUdta->AddChild(pRtng);
}
else
{
- delete pRtng;
+ HX_DELETE(pRtng);
}
}
// Classification
C3GPAtom_clsf* pClsf = new C3GPAtom_clsf();
if( Meta3GP_NewAtomGuard(retVal, pClsf) )
{
retVal = HXR_OK;
UINT32 uEntity = 0;
EncodedString sEntity;
HXBOOL resEnt = PropTools::CopyPropertyBuffer(sEntity, m_pFileHeader, _3GPP_META_INFO_CLASSIFICATION_ENTITY_KEY);
if(resEnt)
{
Meta3GP_ExtractUINT32(sEntity, uEntity);
}
ULONG32 uTable = 0;
HXBOOL resTable = PropTools::CopyPropertyULONG32(uTable, m_pFileHeader, _3GPP_META_INFO_CLASSIFICATION_TABLE_KEY);
EncodedString sInfo;
HXBOOL resInfo = PropTools::CopyPropertyBuffer(sInfo, m_pFileHeader, _3GPP_META_INFO_CLASSIFICATION_INFO_KEY);
if(resEnt || resTable || resInfo)
{
if(resEnt)
{
pClsf->SetClassificationEntity(uEntity);
}
if(resTable)
{
pClsf->SetClassificationTable(UINT16(uTable));
}
if(resInfo)
{
pClsf->SetString_ClassificationInfo(sInfo.GetData(), sInfo.GetEncoding());
}
Meta3GP_SetLanguageEncoding(pClsf);
pUdta->AddChild(pClsf);
}
else
{
- delete pClsf;
+ HX_DELETE(pClsf);
}
}
// Keywords
C3GPAtom_kywd* pKywd = new C3GPAtom_kywd();
if( Meta3GP_NewAtomGuard(retVal, pKywd) )
{
retVal = HXR_OK;
HXBOOL bEmpty = TRUE;
ULONG32 uCount = 0;
HXBOOL resCount = PropTools::CopyPropertyULONG32(uCount, m_pFileHeader, _3GPP_META_INFO_KEYWORD_COUNT_KEY);
if(resCount && (uCount > 0))
{
for(ULONG32 i = 0; i < uCount; i++)
{
char key[64];
snprintf(key, 64, _3GPP_META_INFO_KEYWORD_KEY, i);
EncodedString sKeyword;
if(PropTools::CopyPropertyBuffer(sKeyword, m_pFileHeader, key))
{
pKywd->AddKeyword(sKeyword.GetData(), sKeyword.GetEncoding());
}
}
if(pKywd->GetKeywordCount() > 0)
{
bEmpty = FALSE;
Meta3GP_SetLanguageEncoding(pKywd);
pUdta->AddChild(pKywd);
}
}
if(bEmpty)
{
- delete pKywd;
+ HX_DELETE(pKywd);
}
}
// Location
C3GPAtom_loci* pLoci = new C3GPAtom_loci();
if( Meta3GP_NewAtomGuard(retVal, pLoci) )
{
retVal = HXR_OK;
EncodedString sName;
HXBOOL resName = PropTools::CopyPropertyBuffer(sName, m_pFileHeader, _3GPP_META_INFO_LOCATION_NAME_KEY);
EncodedString sAstro;
HXBOOL resAstro = PropTools::CopyPropertyBuffer(sAstro, m_pFileHeader, _3GPP_META_INFO_LOCATION_ASTRONOMICAL_BODY_KEY);
EncodedString sAddNotes;
HXBOOL resAddNotes = PropTools::CopyPropertyBuffer(sAddNotes, m_pFileHeader, _3GPP_META_INFO_LOCATION_ADDITIONAL_NOTES_KEY);
ULONG32 uRole = 0;
HXBOOL resRole = PropTools::CopyPropertyULONG32(uRole, m_pFileHeader, _3GPP_META_INFO_LOCATION_ROLE_KEY);
INT32 coordWhole = 0;
UINT32 coordFrac = 0;
EncodedString sLong;
UINT32 uLong = 0;
HXBOOL resLong = PropTools::CopyPropertyBuffer(sLong, m_pFileHeader, _3GPP_META_INFO_LOCATION_LONGITUDE_KEY) &&
Meta3GP_ExtractFixedPoint(sLong, coordWhole, coordFrac, uLong);
EncodedString sLat;
@@ -3999,113 +4338,178 @@
}
if(resAstro)
{
pLoci->SetString_AstronomicalBody(sAstro.GetData(), sAstro.GetEncoding());
}
if(resAddNotes)
{
pLoci->SetString_AdditionalNotes(sAddNotes.GetData(), sAddNotes.GetEncoding());
}
if(resRole)
{
pLoci->SetRole(UINT8(uRole));
}
if(resLong)
{
pLoci->SetLongitude(uLong);
}
if(resLat)
{
pLoci->SetLatitude(uLat);
}
if(resAlt)
{
pLoci->SetAltitude(uAlt);
}
Meta3GP_SetLanguageEncoding(pLoci);
pUdta->AddChild(pLoci);
}
else
{
- delete pLoci;
+ HX_DELETE(pLoci);
}
}
// Album
C3GPAtom_albm* pAlbm = new C3GPAtom_albm();
if( Meta3GP_NewAtomGuard(retVal, pAlbm) )
{
retVal = HXR_OK;
EncodedString sTitle;
HXBOOL resTitle = PropTools::CopyPropertyBuffer(sTitle, m_pFileHeader, _3GPP_META_INFO_ALBUM_TITLE_KEY);
ULONG32 uTrackNum = 0;
HXBOOL resTrackNum = PropTools::CopyPropertyULONG32(uTrackNum, m_pFileHeader, _3GPP_META_INFO_TRACK_NUMBER_KEY);
if(resTitle || resTrackNum)
{
if(resTitle)
{
pAlbm->SetString_AlbumTitle(sTitle.GetData(), sTitle.GetEncoding());
}
if(resTrackNum)
{
pAlbm->SetTrackNumber(TRUE, UINT8(uTrackNum));
}
Meta3GP_SetLanguageEncoding(pAlbm);
pUdta->AddChild(pAlbm);
}
else
{
- delete pAlbm;
+ HX_DELETE(pAlbm);
}
}
// Recording Year
C3GPAtom_yrrc* pYrrc = new C3GPAtom_yrrc();
if( Meta3GP_NewAtomGuard(retVal, pYrrc) )
{
retVal = HXR_OK;
ULONG32 uRecYear = 0;
if(PropTools::CopyPropertyULONG32(uRecYear, m_pFileHeader, _3GPP_META_INFO_RECORDING_YEAR_KEY))
{
pYrrc->SetRecordingYear(UINT16(uRecYear));
pUdta->AddChild(pYrrc);
}
else
{
- delete pYrrc;
+ HX_DELETE(pYrrc);
+ }
+ }
+
+ // ID32, setup box hierarchy: file/moov/meta/[hdlr, ID32]
+ CMP4Atom_meta* pMeta = NULL;
+ if(SUCCEEDED(retVal))
+ {
+ retVal = Build3GPMetaDataID32(m_pFileHeader, &pMeta);
+ if(SUCCEEDED(retVal) && pMeta)
+ {
+ retVal = pMoov->AddChild(pMeta);
+ }
+ }
+
+ return retVal;
+}
+
+HX_RESULT CMP4StreamMixer::Build3GPMetaDataID32( IHXValues* pHeader, CMP4Atom_meta** ppMeta )
+{
+ if(!ppMeta)
+ {
+ return HXR_POINTER;
+ }
+ if(!pHeader)
+ {
+ return HXR_INVALID_PARAMETER;
}
+
+ *ppMeta = NULL;
+
+ IHXBuffer* pBlobID32 = NULL;
+ HX_RESULT retVal = HXR_OK;
+
+ if(SUCCEEDED(pHeader->GetPropertyBuffer(_3GPP_META_INFO_ID32_BLOB_KEY, pBlobID32)))
+ {
+ retVal = HXR_OUTOFMEMORY;
+
+ // setup box hierarchy: meta/[hdlr, ID32]
+ CMP4Atom_meta* pMeta = new CMP4Atom_meta();
+ CMP4Atom_hdlr* pHdlr = new CMP4Atom_hdlr();
+ C3GPAtom_ID32* pID32 = new C3GPAtom_ID32();
+
+ if(pMeta && pHdlr && pID32)
+ {
+ // 'hdlr' must be the first child of 'meta'
+ pHdlr->SetHandlerType("ID32");
+ pMeta->AddChild(pHdlr);
+
+ Meta3GP_SetLanguageEncoding(pID32);
+ pID32->SetBlob((UCHAR*)pBlobID32->GetBuffer(), pBlobID32->GetSize());
+ pMeta->AddChild(pID32);
+
+ retVal = HXR_OK;
}
+ if(SUCCEEDED(retVal))
+ {
+ *ppMeta = pMeta;
+ }
+ else
+ {
+ HX_DELETE(pMeta);
+ HX_DELETE(pHdlr);
+ HX_DELETE(pID32);
+ }
+ }
+ HX_RELEASE(pBlobID32);
+
return retVal;
}
HX_RESULT CMP4StreamMixer::StartBuildStsdEntry( CMP4Atom_stsd* pStsd, UINT16 usStreamNum )
{
return BuildStsdEntry(pStsd, usStreamNum);
}
// Build out the stsd entry for a specific stream; we only have one stream in this case, but
// extending this to handle multiple streams should be easy
HX_RESULT CMP4StreamMixer::BuildStsdEntry( CMP4Atom_stsd* pStsd, UINT16 usStreamNum )
{
// stream handler should have set SampleFormat already
UINT32 ulSampleFormat = 0;
m_pStreamInfo[usStreamNum].m_pStreamHeader->GetPropertyULONG32("SampleFormat", ulSampleFormat);
switch (ulSampleFormat)
{
case MP4_BUILD_ATOMID('m', 'p', '4', 'a'):
return BuildMP4AStsdEntry(pStsd, usStreamNum);
break;
case MP4_BUILD_ATOMID('m', 'p', '4', 'v'):
return BuildMP4VStsdEntry(pStsd, usStreamNum);
break;
case MP4_BUILD_ATOMID('a', 'v', 'c', '1'):
return BuildAVC1StsdEntry(pStsd, usStreamNum);
break;
case MP4_BUILD_ATOMID('h', '2', '6', '3'):
return BuildH263StsdEntry(pStsd, usStreamNum);
break;
Index: mp4sm.h
===================================================================
RCS file: /cvsroot/datatype/mp4/filewriter/mp4sm.h,v
retrieving revision 1.12
diff -d -H -b -B -w -U30 -r1.12 mp4sm.h
--- mp4sm.h 10 Jun 2009 16:06:40 -0000 1.12
+++ mp4sm.h 19 Oct 2009 13:17:08 -0000
@@ -25,66 +25,72 @@
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#ifndef _MP4LAYOUT_H_
#define _MP4LAYOUT_H_
#include "hxslist.h"
#include "pckunpck.h"
#include "mp4fwplg.h"
#include "proptools.h"
#include "chxhintgen.h"
// fdecl
class CMP4Atom;
class CMP4Atom_mvhd;
class CMP4Atom_trak;
class CMP4Atom_tkhd;
class CMP4Atom_mdhd;
class CMP4Atom_stsd;
class CMP4Atom_sdp;
class CMP4Atom_udta;
+class CMP4Atom_meta;
class CMP4Archiver;
class CMP4VersionedAtom;
+class CMP4ContainerAtom;
+class CiTunesAtom_ilst;
+class CiTunesAtom_data;
class C3GPAtom_LangBase;
class C3GPAtom_StringBase;
+class iTunesMetadataTransferPort;
+
class CStblManager;
class CHXString;
#define HX_INVALID_STREAM_GROUP_NUMBER 0xFFFFFFFF
#define HX_INVALID_SWITCH_GROUP_ID 0
#define HX_INVALID_TRACK_ID 0
#define HX_TRACK_ID_BASE 200
#define HX_HINT_TRACK_ID_BASE 65536
class CMP4StreamMixer : public IMP4StreamMixer
{
private:
class HintInfo;
public:
CMP4StreamMixer( IUnknown* pContext, CMP4Archiver* pArchiver );
~CMP4StreamMixer();
/*
* IUnknown
*/
STDMETHOD(QueryInterface) ( THIS_ REFIID riid, void** ppvObj );
STDMETHOD_(ULONG32,AddRef) ( THIS );
STDMETHOD_(ULONG32,Release) ( THIS );
/*
* IMP4StreamMixer routines
*/
STDMETHOD(SetProperties) (THIS_ IHXValues* pProperties );
STDMETHOD(SetFileHeader) (THIS_ IHXValues* pFileHeader );
STDMETHOD(SetStreamHeader) (THIS_ IHXValues* pStreamHeader );
@@ -179,172 +185,179 @@
~StreamInfo();
IHXValues* m_pStreamHeader;
CStblManager* m_pStblManager;
HXBOOL m_bHaveSeenFirstPacket;
HXBOOL m_bIsAudio;
HXBOOL m_bIsVideo;
UINT32 m_ulFirstTimestamp;
UINT32 m_ulLastTimestamp;
UINT32 m_ulLastTimestampDelta;
UINT32 m_ulFirstRTPTimestamp;
UINT32 m_ulStreamGroupNumber;
UINT32 m_ulSwitchGroupID;
UINT32 m_ulAvgBitRate;
UINT32 m_ulASMAverageBandwidth;
UINT32 m_ulTrackID;
UINT32 m_ulHintTrackID;
UINT32 m_ulBaseRule;
UINT32 m_ulNumASMRules;
HXASMRuleInfo* m_pASMRuleInfo;
CHXSimpleList* m_pPacketList;
CMP4Atom_tkhd* m_pTkhd;
CMP4Atom_mdhd* m_pMdhd;
HintInfo* m_pHintInfo;
};
// Build the entire atom tree
HX_RESULT BuildMP4Atoms();
// Build the metadata subtree
- HX_RESULT BuildIPODMetaData( CMP4Atom* pUdta );
+ HX_RESULT BuildiTunesMetaData( CMP4Atom* pUdta );
HX_RESULT BuildPSPMetaData( CMP4Atom* pUsmt );
- HX_RESULT Build3GPMetaData( CMP4Atom* pUdta );
+ HX_RESULT Build3GPMetaData( CMP4Atom* pUdta, CMP4Atom* pMoov );
+ HX_RESULT Build3GPMetaDataID32( IHXValues* pHeader, CMP4Atom_meta** ppMeta );
// Build the trak subtree
HX_RESULT BuildTrack( UINT16 usStreamNum, CMP4Atom* pTrak );
HXBOOL IsStreamInSwitchGroup(UINT32 ulStreamNumber, UINT32* pulSwitchGroupID = NULL);
void SetSwitchGroup(CMP4Atom_udta* pUdtaAtom, UINT32 ulStreamNumber);
HXBOOL NeedToAddUdtaChildToTrakBox(CMP4Atom_trak* pTrakBox, UINT32 ulStreamNumber);
HXBOOL NeedToAddUdtaChildToMoovBox();
HX_RESULT AddMovieHintInformation(CMP4Atom_udta* pUdta);
HX_RESULT GenerateMovieLevelSDP(CHXString* pSDPStr);
HX_RESULT GenerateAltGroupSDP(CHXString* pAltGroupSDPStr);
HX_RESULT FindStreamNumInAlternateGroupWithAvgBandwidth(UINT32 ulStreamGroupNumber, UINT32 ulStreamBandwidth, UINT32* pulStreamNum);
HX_RESULT GetTrackIDForAssociatedHintTrack(UINT32 ulStreamNumber, UINT32* pulHintTrackID);
HX_RESULT ParseASMRulePropertyUINT32(IHXValues* pProps, const char* pszName, UINT32 ulFlag, UINT32* pulAllFlags, UINT32* pulValue);
HX_RESULT ParseASMRulePropertyPresence(IHXValues* pProps, const char* pszName, UINT32 ulFlag, UINT32* pulAllFlags, HXBOOL* pbValue);
HX_RESULT ParseASMRuleProperties(IHXValues* pProps, HXASMRuleInfo* pInfo);
HX_RESULT ParseStreamASMRuleBook(StreamInfo* pInfo);
HX_RESULT FindStreamInSwitchGroup(UINT32 ulSwitchGroupID, UINT32 ulASMRule, UINT32* pulStreamNumber);
HX_RESULT ChangePacketStreamNumber(IHXPacket* pPacket, UINT32 ulNewStreamNumber, REF(IHXPacket*) rpPacket);
void CheckForRTPPackets(IHXPacket* pPacket);
void ChooseTrackIDs();
HX_RESULT DetermineStreamType(IHXValues* pStreamHeader, HXBOOL* pbIsAudio, HXBOOL* pbIsVideo);
HX_RESULT GetStreamBandwidth(UINT32 ulStreamNum, UINT32* pulBandwidth);
void AddHintingStatisticsBoxes(CMP4Atom_udta* pUdta);
// Method used to sort stream headers by "AvgBitRate" property
static int StreamHeaderAvgBitRateSort(void* pHdr1, void* pHdr2);
// Build the mdia subtree
HX_RESULT BuildMdia(UINT16 usStreamNum, CMP4Atom *pTrak, HintInfo *pHinfo);
// Build out an stsd entry for a specific stream
HX_RESULT BuildStsdEntry( CMP4Atom_stsd* pStsd, UINT16 usStreamNum );
HX_RESULT BuildMP4AStsdEntry( CMP4Atom_stsd* pStsd, UINT16 usStreamNum );
HX_RESULT BuildMP4VStsdEntry( CMP4Atom_stsd* pStsd, UINT16 usStreamNum );
HX_RESULT BuildAVC1StsdEntry( CMP4Atom_stsd* pStsd, UINT16 usStreamNum );
HX_RESULT BuildH263StsdEntry( CMP4Atom_stsd* pStsd, UINT16 usStreamNum );
HX_RESULT BuildAMRStsdEntry( CMP4Atom_stsd* pStsd, UINT16 usStreamNum );
// 3GP Utilities
void Meta3GP_SetLanguageEncoding(C3GPAtom_LangBase* pAtom, const char* propertySpec = 0);
HXBOOL Meta3GP_NewAtomGuard(HX_RESULT& retVal, CMP4VersionedAtom* pAtom);
void Meta3GP_AddAtom_StringBase(HX_RESULT& retVal, CMP4Atom* pUdta, C3GPAtom_StringBase* pAtom, const char* pPropName);
void Meta3GP_ExtractUINT32(const EncodedString& s, UINT32& out);
void Meta3GP_ExtractUINT16(const EncodedString& s, UINT16& out);
HXBOOL Meta3GP_ExtractFixedPoint(const EncodedString& s, INT32& outWhole, UINT32& outFrac, UINT32& outFixed);
+ void MetaiTunes_LinkAtoms(HX_RESULT& retVal, CiTunesAtom_ilst* pIlst, CMP4ContainerAtom* pItem, CiTunesAtom_data* pData);
+ void MetaiTunes_AddItemAtom(HX_RESULT& retVal, CiTunesAtom_ilst* pIlst, const char* pPropName, iTunesMetadataTransferPort& transfer);
+ HX_RESULT MetaiTunes_CreateItemAtomFromPropertyName(const char* pPropName, CMP4ContainerAtom** ppItemAtom);
+
// Fix up the duration if it differs from the reported one
HX_RESULT UpdateDuration( UINT32 ulDuration );
// Update track duration
HX_RESULT UpdateTrackDuration( UINT16 usStreamNo, UINT32 ulDuration );
HX_RESULT FinalizeSDP(UINT32 ulStreamNum);
HX_RESULT FlushPackets( UINT16 uiStreamNo );
HX_RESULT FlushHintPackets( UINT16 uiStreamNo );
// Routine to dump out atom contents
HX_RESULT DumpAtoms();
LONG32 m_lRefCount;
CMP4Atom* m_pRootAtom;
// We retain copies of these so we can adjust the duration
// after all packets are received without having to do
// multiple atom searches
CMP4Atom_mvhd* m_pMvhd;
CMP4Atom_mdhd* m_pMdhd;
UINT32 m_ulReportedDuration;
UINT32 m_ulActualDuration;
UINT32 m_ulLastTimestamp;
UINT32 m_ulFirstTimestamp;
HXBOOL m_bMoovAtEnd;
HXBOOL m_bForceMoovFirst;
IUnknown* m_pContext;
IHXValues* m_pFileHeader;
UINT32 m_ulStreamCount;
UINT32 m_ulStreamGroupCount;
UINT32 m_ulStreamHeaderReceived;
UINT32 m_ulStreamDoneReceived;
CHXHintContext m_HintContext;
StreamInfo* m_pStreamInfo;
CMP4Archiver* m_pArchiver;
enum RTPPacketStream
{
UNCHECKED = 0,
IS_RTP = 1,
NOT_RTP = 2,
};
RTPPacketStream m_eIsRtp;
UINT32 m_uiByteCount;
UINT32 m_uiReservedBlockCount;
enum MetaFlavor
{
META_ITUNES,
- META_3GP,
+ META_3GPP,
META_PSP
};
MetaFlavor m_eMetaFlavor;
+ HXBOOL m_bRequestedOutputMetaFlavor3GPP;
+ HXBOOL m_bRequestedOutputMetaFlavorITUNES;
HXBOOL m_bUTF16Output;
EncodedString m_spCompatibility;
protected:
enum ThreeGPPMode
{
M3GPP_NONE,
M3GPP_GENERAL,
M3GPP_BASIC,
M3GPP_STREAMING,
M3GPP_PROGDL,
M3GPP_STREAMDL,
M3GPP_REL5
};
ThreeGPPMode m_e3gpMode;
HXBOOL m_bTSInterleave;
HXBOOL m_bGenerateHintTracks;
friend class CStblManager;
UINT32 m_uiBaseWriteOffset;
UINT32 m_uiCurrentOffset;
UINT32 m_uiGlobalFlush;
};
#endif // _MP4SM_H_
datatype_tools_dtdriver_apps_meta3gp.diff
(text/x-patch, 82.8 KB)
Index: Umakefil_meta3gp
===================================================================
RCS file: /cvsroot/datatype/tools/dtdriver/apps/meta3gp/Umakefil_meta3gp,v
retrieving revision 1.2
diff -d -H -b -B -w -U30 -r1.2 Umakefil_meta3gp
--- Umakefil_meta3gp 6 Nov 2007 11:39:02 -0000 1.2
+++ Umakefil_meta3gp 19 Oct 2009 12:56:58 -0000
@@ -1,33 +1,33 @@
UmakefileVersion(2,0)
project.AddModuleIncludes("common/include",
"common/log/logobserverfile/pub",
"datatype/include",
+ "datatype/common/util/pub",
"datatype/common/filewriter/pub",
"datatype/tools/dtdriver/engine/pub",
"datatype/tools/minicntx/pub",
"datatype/tools/metaeditor/pub",
"producersdk/include")
project.AddModuleLibraries( "client/common/container[contclntlib]",
"client/common/system[sysclntlib]",
"client/common/util[utlclntlib]",
"common/runtime[runtlib]",
"common/dbgtool[debuglib]",
"common/util[utillib]",
"common/container[contlib]",
"common/system[syslib]",
"common/fileio[fileiolib]",
- "common/log/logutil[logutillib]")
-
-project.AddModuleLibraries("datatype/tools/metaeditor[metautil3gplib]")
+ "common/log/logutil[logutillib]",
+ "datatype/common/util[dtutillib]")
project.AddDefines( 'HELIX_FEATURE_ALLOW_DEPRECATED_SMARTPOINTERS' )
project.AddSources( "main.cpp",
"dlliids.cpp")
ProgramTarget('meta3gp')
DependTarget()
Index: main.cpp
===================================================================
RCS file: /cvsroot/datatype/tools/dtdriver/apps/meta3gp/main.cpp,v
retrieving revision 1.1
diff -d -H -b -B -w -U30 -r1.1 main.cpp
--- main.cpp 5 Nov 2007 22:46:15 -0000 1.1
+++ main.cpp 19 Oct 2009 12:57:00 -0000
@@ -31,87 +31,78 @@
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
/****************************************************************************
* Includes
*/
#include <stdlib.h>
#include <stdarg.h>
#include "hlxclib/time.h"
#include "hlxclib/stdio.h"
#include "hlxclib/wchar.h"
#include "hxtypes.h"
#include "hlxosstr.h"
#include "ffdriver.h"
#include "cstrmsrt.h"
#include "hxmemprb.h"
#include "hxtick.h"
#include "chxpckts.h"
#include "pckunpck.h"
#include "dllpath.h"
#include "filespecutils.h"
#include "metainfokeys.h"
#include "uniconv.h"
#include "proptools.h"
#include "dllacces.h"
#include "ihxmetaeditor.h"
-#include "metautil3gp.h"
+#include "metautil.h"
/****************************************************************************
- * 3GP meta-data command line editor.
+ * Meta-data command line editor.
* Build-time configuration options.
*/
-// uncomment to use synchronous mode
-#define USE_SYNCHRONOUS_MODE 1
-
-// uncomment to test meta-editor's default processor
-//#define TEST_DEFAULT_META_EDITOR_PROCESSOR 1
-
// uncomment to force usage of legacy strings on Windows
// (only relevant for command-line argument transfer)
//#define FORCE_LEGACY_CHAR 1
/****************************************************************************
- * Operational mode
+ * Component operational modes
*/
-#ifdef USE_SYNCHRONOUS_MODE
-const BOOL g_bSynchronousMode = TRUE;
-#else
-const BOOL g_bSynchronousMode = FALSE;
-#endif
+HXBOOL g_bUseDefaultMetaEditorProcessor = FALSE;
+HXBOOL g_bUseDTDriverSynchronousMode = FALSE;
/****************************************************************************
* System character type macros
*/
#ifdef USE_WIDE_CHAR
#undef USE_WIDE_CHAR
#endif
#if defined(_WINDOWS) && !defined(FORCE_LEGACY_CHAR)
#define USE_WIDE_CHAR 1
#endif
#ifdef _T
#undef _T
#endif
#ifdef TCHAR
#undef TCHAR
#endif
#ifdef TMAIN
#undef TMAIN
#endif
#ifdef USE_WIDE_CHAR
#define _T(Val) L##Val
#define TCHAR wchar_t
#define TMAIN wmain
@@ -119,440 +110,498 @@
#define TStringLength ::StringLengthW
#define TStringEqual ::StringEqualW
#define TStringAppend ::StringAppendW
#define TConvertToCCPString(Val) EncStrUtils::Duplicate((const char*)CCPFromWCharT(Val), \
HX_TEXT_ENCODING_TYPE_UNKNOWN, EncStrUtils::ALLOC_FLAG_NEW)
#define ENCODED_STRING_VAR(VarName, Val) EncodedString VarName((const char*)::UTF8FromWCharT(Val), HX_TEXT_ENCODING_TYPE_UTF8)
#define ENCODED_STRING_CTOR(Val) EncodedString((const char*)::UTF8FromWCharT(Val), HX_TEXT_ENCODING_TYPE_UTF8)
#else //USE_WIDE_CHAR
#define _T(Val) Val
#define TCHAR char
#define TMAIN main
#define TPrintf printf
#define TStringLength ::StringLengthA
#define TStringEqual ::StringEqualA
#define TStringAppend ::StringAppendA
#define TConvertToCCPString(Val) EncStrUtils::Duplicate(Val, \
HX_TEXT_ENCODING_TYPE_UNKNOWN, EncStrUtils::ALLOC_FLAG_NEW)
#define ENCODED_STRING_VAR(VarName, Val) EncodedString VarName((const char*)::UTF8FromCCP(Val), HX_TEXT_ENCODING_TYPE_UTF8)
#define ENCODED_STRING_CTOR(Val) EncodedString((const char*)::UTF8FromCCP(Val), HX_TEXT_ENCODING_TYPE_UTF8)
#endif //USE_WIDE_CHAR
/****************************************************************************
* Build-time messages
*/
#ifdef _WINDOWS
-#ifdef USE_SYNCHRONOUS_MODE
-# pragma message("Using synchronous mode")
-#else
-# pragma message("Using asynchronous mode")
-#endif
-
-#ifdef TEST_DEFAULT_META_EDITOR_PROCESSOR
-# pragma message("Using default meta-data processor")
-#else
-# pragma message("Using custom meta-data processor")
-#endif
-
#ifdef USE_WIDE_CHAR
# pragma message("Using wide-string command-line arguments")
#else
# pragma message("Using legacy-string command-line arguments")
#endif
#endif //_WINDOWS
/****************************************************************************
* DLLAccessPath Variable
*/
ENABLE_DLLACCESS_PATHS(g_Meta3GPAccessPath);
/****************************************************************************
* Defines
*/
-#define PROGRAM_NAME_STRING _T("RealNetworks 3GP meta-data editor")
-#define PROGRAM_COPYRIGHT_STRING _T("Copyright (c) RealNetworks 2007")
-#define PROGRAM_VERSION_STRING _T("1.0.11")
+#define PROGRAM_NAME_STRING _T("RealNetworks meta-data editor")
+#define PROGRAM_COPYRIGHT_STRING _T("Copyright (c) RealNetworks 2009")
+#define PROGRAM_VERSION_STRING _T("2.0.0")
-#define OPTION_STRING_HELP _T("h")
+// input/output control
+#define PARAM_STRING_SYNCMODE _T("dev-syncmode")
+#define PARAM_STRING_DEFMETAPROC _T("dev-defmetaproc")
+#define PARAM_STRING_INPUTFILE _T("if")
+#define PARAM_STRING_OUTPUTFILE _T("of")
+#define PARAM_STRING_XMLINPUTFILE _T("xmlin")
+#define PARAM_STRING_XMLOUTPUTFILE _T("xmlout")
+#define PARAM_STRING_CLEARMETADATA _T("metaclear")
+#define PARAM_STRING_METASTYLE _T("metastyle")
+#define PARAM_STRING_UTF16OUTPUT _T("utf16")
+#define PARAM_STRING_OVERWRITEFILE _T("overwrite")
+#define PARAM_STRING_PRINTMETADATA _T("print")
+#define PARAM_STRING_HELP _T("help")
-#define OPTION_STRING_INPUTFILE _T("i")
-#define OPTION_STRING_OUTPUTFILE _T("o")
-#define OPTION_STRING_OVERWRITEFILE _T("w")
-#define OPTION_STRING_CLEARMETADATA _T("c")
-#define OPTION_STRING_PRINTMETADATA _T("p")
-#define OPTION_STRING_UTF16OUTPUT _T("utf16")
+// common metadata
+#define PARAM_STRING_TITLE _T("title")
+#define PARAM_STRING_ARTIST _T("artist")
+#define PARAM_STRING_ALBUM _T("album")
+#define PARAM_STRING_GENRE _T("genre")
+#define PARAM_STRING_COMPOSER _T("composer")
+#define PARAM_STRING_COMMENT _T("comment")
+#define PARAM_STRING_COVERART _T("cover")
+#define PARAM_STRING_TRACKNUMBER _T("track")
+#define PARAM_STRING_YEAR _T("year")
-#define OPTION_STRING_LANGUAGE_CODE _T("lang")
+// iTunes specific metadata
+#define PARAM_STRING_SOFTWARE _T("software")
+#define PARAM_STRING_GROUPING _T("grouping")
+#define PARAM_STRING_ALBUMARTIST _T("albumartist")
+#define PARAM_STRING_LYRICS _T("lyrics")
+#define PARAM_STRING_SUBTITLE _T("subtitle")
+#define PARAM_STRING_BPM _T("bpm")
+#define PARAM_STRING_PARTOFCOMP _T("partofcompilation")
+#define PARAM_STRING_EXPLICIT _T("explicitcontent")
+#define PARAM_STRING_TRACKSTOTAL _T("trackstotal")
+#define PARAM_STRING_DISKNUMBER _T("disk")
+#define PARAM_STRING_DISKSTOTAL _T("diskstotal")
-#define OPTION_STRING_TITLE _T("title")
-#define OPTION_STRING_DESCRIPTION _T("description")
-#define OPTION_STRING_COPYRIGHT _T("copyright")
-#define OPTION_STRING_PERFORMER _T("performer")
-#define OPTION_STRING_AUTHOR _T("author")
-#define OPTION_STRING_GENRE _T("genre")
-#define OPTION_STRING_ALBUM _T("album")
-#define OPTION_STRING_TRACK _T("track")
-#define OPTION_STRING_YEAR _T("year")
+// 3GPP specific metadata
+#define PARAM_STRING_LANGUAGE_CODE _T("lang")
+#define PARAM_STRING_COPYRIGHT _T("copyright")
-#define OPTION_STRING_RATING_ENTITY _T("rtgent")
-#define OPTION_STRING_RATING_CRITERIA _T("rtgcrit")
-#define OPTION_STRING_RATING_INFO _T("rtginfo")
+#define PARAM_STRING_RATING_ENTITY _T("rtngent")
+#define PARAM_STRING_RATING_CRITERIA _T("rtngcrit")
+#define PARAM_STRING_RATING_INFO _T("rtnginfo")
-#define OPTION_STRING_CLASSIFICATION_ENTITY _T("clsent")
-#define OPTION_STRING_CLASSIFICATION_TABLE _T("clstbl")
-#define OPTION_STRING_CLASSIFICATION_INFO _T("clsinfo")
+#define PARAM_STRING_CLASSIFICATION_ENTITY _T("clsent")
+#define PARAM_STRING_CLASSIFICATION_TABLE _T("clstbl")
+#define PARAM_STRING_CLASSIFICATION_INFO _T("clsinfo")
-#define OPTION_STRING_KEYWORD_ADD _T("kwadd")
-#define OPTION_STRING_KEYWORD_REMOVE _T("kwrem")
-#define OPTION_STRING_KEYWORD_CLEAR _T("kwclr")
+#define PARAM_STRING_KEYWORD_ADD _T("kwdadd")
+#define PARAM_STRING_KEYWORD_REMOVE _T("kwdrem")
+#define PARAM_STRING_KEYWORD_CLEAR _T("kwdclr")
-#define OPTION_STRING_LOCATION_NAME _T("locname")
-#define OPTION_STRING_LOCATION_ASTRONOMICAL_BODY _T("locastro")
-#define OPTION_STRING_LOCATION_ADDITIONAL_NOTES _T("locnotes")
-#define OPTION_STRING_LOCATION_ROLE _T("locrole")
-#define OPTION_STRING_LOCATION_LONGITUDE _T("loclong")
-#define OPTION_STRING_LOCATION_LATITUDE _T("loclat")
-#define OPTION_STRING_LOCATION_ALTITUDE _T("localt")
+#define PARAM_STRING_LOCATION_NAME _T("locname")
+#define PARAM_STRING_LOCATION_ASTRONOMICAL_BODY _T("locastro")
+#define PARAM_STRING_LOCATION_ADDITIONAL_NOTES _T("locnotes")
+#define PARAM_STRING_LOCATION_ROLE _T("locrole")
+#define PARAM_STRING_LOCATION_LONGITUDE _T("loclong")
+#define PARAM_STRING_LOCATION_LATITUDE _T("loclat")
+#define PARAM_STRING_LOCATION_ALTITUDE _T("localt")
/****************************************************************************
* Help display utilities
*/
-class CommandDesc
+class ParameterDesc
{
public:
- CommandDesc(const TCHAR* cmd_, const TCHAR* cmd_suffix_, const TCHAR* desc_)
+ ParameterDesc(const TCHAR* cmd_ = 0, const TCHAR* cmd_suffix_ = 0, const TCHAR* desc_ = 0)
{
cmd = cmd_;
cmd_suffix = cmd_suffix_;
desc = desc_;
}
- UINT32 GetLeftColumnWidth()
+ ULONG32 GetLeftColumnWidth()
{
- UINT32 len = 0;
+ ULONG32 len = 0;
if(cmd)
{
- len += 3 + TStringLength(cmd); //3 for prefix
+ len += 2 + TStringLength(cmd); //leading whitespace and parameter prefix
if(cmd_suffix)
{
- len += 1 + TStringLength(cmd_suffix); //1 for whitespace separator
+ len += 1 + TStringLength(cmd_suffix); //whitespace separator
}
}
return len;
}
- TCHAR* BuildLine(UINT32 leftColumnWidth)
+ TCHAR* BuildLine(ULONG32 leftColumnWidth)
{
TCHAR* out = TStringAppend(0, _T(""));
if(cmd)
{
- out = TStringAppend(out, _T(" -"));
+ out = TStringAppend(out, _T(" -")); //leading whitespace and parameter prefix
out = TStringAppend(out, cmd);
if(cmd_suffix)
{
- out = TStringAppend(out, _T(" "));
+ out = TStringAppend(out, _T(" ")); //whitespace separator
out = TStringAppend(out, cmd_suffix);
}
if(desc)
{
INT32 diff = leftColumnWidth - TStringLength(out);
for(int d = 0; d < diff; d++)
{
out = TStringAppend(out, _T(" "));
}
out = TStringAppend(out, desc);
}
}
return out;
}
private:
const TCHAR* cmd;
const TCHAR* cmd_suffix;
const TCHAR* desc;
};
-class CommandDescPrinter
+class ParameterDescPrinter
{
public:
- void Add(CommandDesc* cd)
+ void Add(ParameterDesc* cd)
{
descs.Add(cd);
}
int CalcLeftColumnWidth()
{
int leftColumnWidth = 0;
for(int i = 0; i < descs.GetSize(); i++)
{
- CommandDesc* cd = (CommandDesc*)descs.GetAt(i);
+ ParameterDesc* cd = (ParameterDesc*)descs.GetAt(i);
int width = cd->GetLeftColumnWidth();
if(width > leftColumnWidth)
{
leftColumnWidth = width;
}
}
return leftColumnWidth;
}
void PrintColumns(int columnSpacing = 1)
{
int leftColumnWidth = CalcLeftColumnWidth() + columnSpacing;
for(int i = 0; i < descs.GetSize(); i++)
{
- CommandDesc* cd = (CommandDesc*)descs.GetAt(i);
+ ParameterDesc* cd = (ParameterDesc*)descs.GetAt(i);
TCHAR* line = cd->BuildLine(leftColumnWidth);
if(line)
{
TPrintf(_T("%s\n"), line);
}
delete [] line;
}
}
private:
CHXPtrArray descs;
};
void DisplayUsage(const TCHAR* argv0)
{
const TCHAR* pszDbg = _T("");
- const TCHAR* pszSyncMode = _T("");
#if defined(DEBUG) || defined(_DEBUG)
pszDbg = _T(".debug");
- if(g_bSynchronousMode)
- {
- pszSyncMode = _T(".sync");
- }
- else
- {
- pszSyncMode = _T(".async");
- }
#endif
- TPrintf(_T("\n--- %s ---\n %s\n Version %s%s%s\n\n"), PROGRAM_NAME_STRING, PROGRAM_COPYRIGHT_STRING, PROGRAM_VERSION_STRING, pszDbg, pszSyncMode);
- TPrintf(_T("usage: %s [ -command [value]... ]...\n"), argv0);
- TPrintf(_T("with commands:\n"));
-
- CommandDescPrinter cdp;
-
- cdp.Add(new CommandDesc(OPTION_STRING_INPUTFILE, _T("<string>"), _T("input file")));
- cdp.Add(new CommandDesc(OPTION_STRING_OUTPUTFILE, _T("<string>"), _T("3GP output file")));
- cdp.Add(new CommandDesc(OPTION_STRING_OVERWRITEFILE, 0, _T("overwrite output file if it exists")));
- cdp.Add(new CommandDesc(OPTION_STRING_CLEARMETADATA, 0, _T("clear all meta-data")));
- cdp.Add(new CommandDesc(OPTION_STRING_PRINTMETADATA, 0, _T("print extracted/updated meta-data")));
-
- cdp.Add(new CommandDesc(OPTION_STRING_UTF16OUTPUT, 0, _T("store meta-data strings in UTF16 format")));
- cdp.Add(new CommandDesc(OPTION_STRING_LANGUAGE_CODE, _T("<3-character string>"), _T("ISO639.2/T language code of meta-data text")));
-
- cdp.Add(new CommandDesc(OPTION_STRING_TITLE, _T("<string>"), _T("update meta-data: title")));
- cdp.Add(new CommandDesc(OPTION_STRING_DESCRIPTION, _T("<string>"), _T("update meta-data: description")));
- cdp.Add(new CommandDesc(OPTION_STRING_COPYRIGHT, _T("<string>"), _T("update meta-data: copyright")));
- cdp.Add(new CommandDesc(OPTION_STRING_PERFORMER, _T("<string>"), _T("update meta-data: performer")));
- cdp.Add(new CommandDesc(OPTION_STRING_AUTHOR, _T("<string>"), _T("update meta-data: author")));
- cdp.Add(new CommandDesc(OPTION_STRING_GENRE, _T("<string>"), _T("update meta-data: genre")));
- cdp.Add(new CommandDesc(OPTION_STRING_ALBUM, _T("<string>"), _T("update meta-data: album title")));
- cdp.Add(new CommandDesc(OPTION_STRING_TRACK, _T("<integer 0..255>"), _T("update meta-data: track number")));
- cdp.Add(new CommandDesc(OPTION_STRING_YEAR, _T("<integer 0..65536>"), _T("update meta-data: recording year")));
-
- cdp.Add(new CommandDesc(OPTION_STRING_RATING_ENTITY, _T("<4-character string>"), _T("update meta-data: rating entity")));
- cdp.Add(new CommandDesc(OPTION_STRING_RATING_CRITERIA, _T("<4-character string>"), _T("update meta-data: rating criteria")));
- cdp.Add(new CommandDesc(OPTION_STRING_RATING_INFO, _T("<string>"), _T("update meta-data: rating info")));
-
- cdp.Add(new CommandDesc(OPTION_STRING_CLASSIFICATION_ENTITY, _T("<4-character string>"), _T("update meta-data: classification entity")));
- cdp.Add(new CommandDesc(OPTION_STRING_CLASSIFICATION_TABLE, _T("<integer 0..65535>"), _T("update meta-data: classification table")));
- cdp.Add(new CommandDesc(OPTION_STRING_CLASSIFICATION_INFO, _T("<string>"), _T("update meta-data: classification info")));
-
- cdp.Add(new CommandDesc(OPTION_STRING_KEYWORD_ADD, _T("<string>"), _T("update meta-data: add keyword")));
- cdp.Add(new CommandDesc(OPTION_STRING_KEYWORD_REMOVE, _T("<string>"), _T("update meta-data: remove keyword")));
- cdp.Add(new CommandDesc(OPTION_STRING_KEYWORD_CLEAR, 0, _T("update meta-data: clear all keywords")));
+ TPrintf(_T("\n--- %s ---\n %s\n Version %s%s\n\n"), PROGRAM_NAME_STRING, PROGRAM_COPYRIGHT_STRING, PROGRAM_VERSION_STRING, pszDbg);
+ TPrintf(_T("usage: %s [ -parameter [value]... ]...\n"), argv0);
+ TPrintf(_T("with parameters:\n"));
- cdp.Add(new CommandDesc(OPTION_STRING_LOCATION_NAME, _T("<string>"), _T("update meta-data: location name")));
- cdp.Add(new CommandDesc(OPTION_STRING_LOCATION_ASTRONOMICAL_BODY, _T("<string>"), _T("update meta-data: location astronomical body")));
- cdp.Add(new CommandDesc(OPTION_STRING_LOCATION_ADDITIONAL_NOTES, _T("<string>"), _T("update meta-data: location notes")));
- cdp.Add(new CommandDesc(OPTION_STRING_LOCATION_ROLE, _T("<integer 0..255>"), _T("update meta-data: location role")));
- cdp.Add(new CommandDesc(OPTION_STRING_LOCATION_LONGITUDE, _T("<decimal number>"), _T("update meta-data: location longitude")));
- cdp.Add(new CommandDesc(OPTION_STRING_LOCATION_LATITUDE, _T("<decimal number>"), _T("update meta-data: location latitude")));
- cdp.Add(new CommandDesc(OPTION_STRING_LOCATION_ALTITUDE, _T("<decimal number>"), _T("update meta-data: location altitude")));
+ ParameterDescPrinter pdp;
- cdp.Add(new CommandDesc(OPTION_STRING_HELP, 0, _T("display help text")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_INPUTFILE, _T("<string>"), _T("input file")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_OUTPUTFILE, _T("<string>"), _T("output file")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_OVERWRITEFILE, 0, _T("overwrite output file if it exists")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_CLEARMETADATA, 0, _T("clear all extracted metadata before injection")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_METASTYLE, _T("<3GPP | iTunes>"), _T("flavor of injected metadata, default=all")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_UTF16OUTPUT, 0, _T("inject metadata strings in UTF16 format")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_PRINTMETADATA, 0, _T("print updated metadata")));
+ pdp.Add(new ParameterDesc());
+ pdp.Add(new ParameterDesc(PARAM_STRING_TITLE, _T("<string>"), _T("update title")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_ARTIST, _T("<string>"), _T("update 3GPP performer, iTunes artist")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_ALBUM, _T("<string>"), _T("update album")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_GENRE, _T("<string>"), _T("update genre")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_COMPOSER, _T("<string>"), _T("update 3GPP author, iTunes composer")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_COMMENT, _T("<string>"), _T("update 3GPP description, iTunes comment")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_COPYRIGHT, _T("<string>"), _T("update copyright")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_TRACKNUMBER, _T("<integer 0..255>"), _T("update track number")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_YEAR, _T("<integer 0..65536>"), _T("update 3GPP recording year, iTunes release date")));
+ pdp.Add(new ParameterDesc());
+ pdp.Add(new ParameterDesc(PARAM_STRING_SOFTWARE, _T("<string>"), _T("update iTunes generator tool")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_GROUPING, _T("<string>"), _T("update iTunes grouping")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_ALBUMARTIST, _T("<string>"), _T("update iTunes album artist")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_LYRICS, _T("<string>"), _T("update iTunes lyrics")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_SUBTITLE, _T("<string>"), _T("update iTunes track subtitle")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_BPM, _T("<integer>"), _T("update iTunes beats per minute")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_PARTOFCOMP, _T("<0 | 1>"), _T("update iTunes part of compilation")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_EXPLICIT, _T("<0 | 1>"), _T("update iTunes content rating")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_TRACKSTOTAL, _T("<integer>"), _T("update iTunes track count")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_DISKNUMBER, _T("<integer>"), _T("update iTunes disc number")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_DISKSTOTAL, _T("<integer>"), _T("update iTunes disc count")));
+ pdp.Add(new ParameterDesc());
+ pdp.Add(new ParameterDesc(PARAM_STRING_RATING_ENTITY, _T("<4 character code>"), _T("update 3GPP rating entity")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_RATING_CRITERIA, _T("<4 character code>"), _T("update 3GPP rating criteria")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_RATING_INFO, _T("<string>"), _T("update 3GPP rating info")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_CLASSIFICATION_ENTITY, _T("<4 character code>"), _T("update 3GPP classification entity")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_CLASSIFICATION_TABLE, _T("<integer 0..65535>"), _T("update 3GPP classification table")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_CLASSIFICATION_INFO, _T("<string>"), _T("update 3GPP classification info")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_KEYWORD_ADD, _T("<string>"), _T("update 3GPP add keyword")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_KEYWORD_REMOVE, _T("<string>"), _T("update 3GPP remove keyword")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_KEYWORD_CLEAR, 0, _T("update 3GPP clear all keywords")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_LOCATION_NAME, _T("<string>"), _T("update 3GPP location name")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_LOCATION_ASTRONOMICAL_BODY, _T("<string>"), _T("update 3GPP location astronomical body")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_LOCATION_ADDITIONAL_NOTES, _T("<string>"), _T("update 3GPP location notes")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_LOCATION_ROLE, _T("<integer 0..255>"), _T("update 3GPP location role")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_LOCATION_LONGITUDE, _T("<decimal number>"), _T("update 3GPP location longitude")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_LOCATION_LATITUDE, _T("<decimal number>"), _T("update 3GPP location latitude")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_LOCATION_ALTITUDE, _T("<decimal number>"), _T("update 3GPP location altitude")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_LANGUAGE_CODE, _T("<3 character code>"), _T("ISO639.2/T language code of 3GPP metadata text")));
+ pdp.Add(new ParameterDesc());
+ pdp.Add(new ParameterDesc(PARAM_STRING_SYNCMODE, 0, _T("dtdriver sync mode (developer option)")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_DEFMETAPROC, 0, _T("default meta processor (developer option)")));
+ pdp.Add(new ParameterDesc(PARAM_STRING_HELP, 0, _T("display help text")));
- cdp.PrintColumns(3);
+ pdp.PrintColumns(2);
}
/****************************************************************************
-* Option extractors
+* Param extractors
*/
-const TCHAR* NextArg(HX_RESULT& retVal, int& argIndex, int argc, TCHAR* argv[], const TCHAR* optionName = 0)
+const TCHAR* NextArg(HX_RESULT& retVal, int& argIndex, int argc, TCHAR* argv[], const TCHAR* paramName)
{
if(FAILED(retVal))
{
return 0;
}
+
argIndex++;
if(argIndex < argc)
{
retVal = HXR_OK;
return argv[argIndex];
}
- if(optionName)
+
+ if(paramName)
{
- TPrintf(_T("Missing value for option: -%s\n"), optionName);
+ TPrintf(_T("Missing value for param: -%s\n"), paramName);
}
+
retVal = HXR_PARSE_ERROR;
return 0;
}
-BOOL ExtractStringOption(HX_RESULT& retVal, int& argIndex, int argc, TCHAR* argv[],
- MetaInfo3GP& metainfo, MetaInfo3GP::FnStringSetter setter,
- const TCHAR* optionName, const TCHAR** ppOutArg = 0)
+void ReportUnsupportedMetaStyleParam(const TCHAR* paramName)
+{
+ TPrintf(_T("Parameter -%s not supported in combination with specified metastyle(s)\n"), paramName);
+}
+
+void ReportInvalidValueForParameter(const TCHAR* paramName, const TCHAR* paramValue)
+{
+ TPrintf(_T("Invalid value for parameter -%s: %s\n"), paramName, paramValue);
+}
+
+HXBOOL ExtractStringParam(HX_RESULT& retVal, bool bSkipArgOnly, int& argIndex, int argc, TCHAR* argv[],
+ MetaInfo& metainfo, MetaInfo::eStringMetaItem itemName, ULONG32 metaFlavorFlags,
+ const TCHAR* paramName, const TCHAR** ppOutArg = 0)
{
if(FAILED(retVal))
{
return FALSE;
}
- const TCHAR* pVal = NextArg(retVal, argIndex, argc, argv, optionName);
+
+ const TCHAR* pVal = NextArg(retVal, argIndex, argc, argv, paramName);
+ if(bSkipArgOnly)
+ {
+ return SUCCEEDED(retVal) ? TRUE : FALSE;
+ }
+
if(SUCCEEDED(retVal) && pVal)
{
if(ppOutArg)
{
*ppOutArg = pVal;
}
+
+ if(MetaInfo::IsItemSupportedByAnyFlavor(itemName, metaFlavorFlags))
+ {
ENCODED_STRING_VAR(sVal, pVal);
- if((metainfo.*setter)(sVal))
+
+ if(MetaInfo::IsItemValueValidForFlavors(itemName, sVal, metaFlavorFlags))
+ {
+ retVal = metainfo.SetStringItem(itemName, sVal);
+ if(SUCCEEDED(retVal))
{
return TRUE;
}
- TPrintf(_T("Invalid value for option -%s: %s\n"), optionName, pVal);
+ }
+
+ ReportInvalidValueForParameter(paramName, pVal);
retVal = HXR_PARSE_ERROR;
}
+ else
+ {
+ ReportUnsupportedMetaStyleParam(paramName);
+ retVal = HXR_PARSE_ERROR;
+ }
+ }
return FALSE;
}
-BOOL ExtractKeywordStringOption(HX_RESULT& retVal, int& argIndex, int argc, TCHAR* argv[],
- CHXPtrArray& aKeywords,
- const TCHAR* optionName, const TCHAR** ppOutArg = 0)
+HXBOOL ExtractULONG32Param(HX_RESULT& retVal, bool bSkipArgOnly, int& argIndex, int argc, TCHAR* argv[],
+ MetaInfo& metainfo, MetaInfo::eUlongMetaItem itemName, ULONG32 metaFlavorFlags,
+ const TCHAR* paramName, const TCHAR** ppOutArg = 0)
{
if(FAILED(retVal))
{
return FALSE;
}
- const TCHAR* pVal = NextArg(retVal, argIndex, argc, argv, optionName);
+
+ const TCHAR* pVal = NextArg(retVal, argIndex, argc, argv, paramName);
+ if(bSkipArgOnly)
+ {
+ return SUCCEEDED(retVal) ? TRUE : FALSE;
+ }
+
if(SUCCEEDED(retVal) && pVal)
{
if(ppOutArg)
{
*ppOutArg = pVal;
}
- EncodedString* s = new ENCODED_STRING_CTOR(pVal);
- if(s->GetByteLength(TRUE) > 255)
+
+ if(MetaInfo::IsItemSupportedByAnyFlavor(itemName, metaFlavorFlags))
{
- TPrintf(_T("Invalid value for option -%s: %s\n"), optionName, pVal);
- delete s;
- retVal = HXR_PARSE_ERROR;
- }
- else
+ ENCODED_STRING_VAR(sVal, pVal);
+
+ UINT32 uVal = 0;
+ if(PropTools::ExtractUInt32(uVal, sVal))
+ {
+ if(MetaInfo::IsItemValueValidForFlavors(itemName, uVal, metaFlavorFlags))
+ {
+ retVal = metainfo.SetUlongItem(itemName, uVal, TRUE);
+ if(SUCCEEDED(retVal))
{
- aKeywords.Add(s);
return TRUE;
}
}
- return FALSE;
}
-void ClearPropertyStringArray(CHXPtrArray& a)
-{
- for(INT32 i = 0; i < a.GetSize(); i++)
+ ReportInvalidValueForParameter(paramName, pVal);
+ retVal = HXR_PARSE_ERROR;
+ }
+ else
{
- delete (EncodedString*)a[i];
+ ReportUnsupportedMetaStyleParam(paramName);
+ retVal = HXR_PARSE_ERROR;
}
- a.RemoveAll();
+ }
+ return FALSE;
}
-BOOL ExtractUINT16Option(HX_RESULT& retVal, int& argIndex, int argc, TCHAR* argv[],
- MetaInfo3GP& metainfo, MetaInfo3GP::FnUINT16Setter setter,
- const TCHAR* optionName, const TCHAR** ppOutArg = 0)
+HXBOOL ExtractKeywordStringParam(HX_RESULT& retVal, bool bSkipArgOnly, int& argIndex, int argc, TCHAR* argv[],
+ CHXPtrArray& aKeywords, ULONG32 metaFlavorFlags,
+ const TCHAR* paramName, const TCHAR** ppOutArg = 0)
{
if(FAILED(retVal))
{
return FALSE;
}
- const TCHAR* pVal = NextArg(retVal, argIndex, argc, argv, optionName);
+
+ const TCHAR* pVal = NextArg(retVal, argIndex, argc, argv, paramName);
+ if(bSkipArgOnly)
+ {
+ return SUCCEEDED(retVal) ? TRUE : FALSE;
+ }
+
if(SUCCEEDED(retVal) && pVal)
{
if(ppOutArg)
{
*ppOutArg = pVal;
}
- ENCODED_STRING_VAR(sVal, pVal);
- UINT16 uVal = 0;
- if(PropTools::ExtractUInt16(uVal, sVal))
+
+ if(MetaInfo::IsItemSupportedByAnyFlavor(MetaInfo::StringMetaItem_Keywords, metaFlavorFlags))
{
- if((metainfo.*setter)(uVal, TRUE)) return TRUE;
+ EncodedString* pEncStr = new ENCODED_STRING_CTOR(pVal);
+
+ if(pEncStr && MetaInfo::IsItemValueValidForFlavors(MetaInfo::StringMetaItem_Keywords, *pEncStr, metaFlavorFlags))
+ {
+ aKeywords.Add(pEncStr);
+ return TRUE;
}
- TPrintf(_T("Invalid value for option -%s: %s\n"), optionName, pVal);
+ else
+ {
+ ReportInvalidValueForParameter(paramName, pVal);
retVal = HXR_PARSE_ERROR;
+ delete pEncStr;
}
- return FALSE;
}
-
-BOOL ExtractUINT8Option(HX_RESULT& retVal, int& argIndex, int argc, TCHAR* argv[],
- MetaInfo3GP& metainfo, MetaInfo3GP::FnUINT8Setter setter,
- const TCHAR* optionName, const TCHAR** ppOutArg = 0)
-{
- if(FAILED(retVal))
+ else
{
+ ReportUnsupportedMetaStyleParam(paramName);
+ retVal = HXR_PARSE_ERROR;
+ }
+ }
return FALSE;
}
- const TCHAR* pVal = NextArg(retVal, argIndex, argc, argv, optionName);
- if(SUCCEEDED(retVal) && pVal)
- {
- if(ppOutArg)
+
+void ClearPropertyStringArray(CHXPtrArray& a)
{
- *ppOutArg = pVal;
- }
- ENCODED_STRING_VAR(sVal, pVal);
- UINT8 uVal = 0;
- if(PropTools::ExtractUInt8(uVal, sVal))
+ for(INT32 i = 0; i < a.GetSize(); i++)
{
- if((metainfo.*setter)(uVal, TRUE)) return TRUE;
- }
- TPrintf(_T("Invalid value for option -%s: %s\n"), optionName, pVal);
- retVal = HXR_PARSE_ERROR;
+ delete (EncodedString*)a[i];
}
- return FALSE;
+ a.RemoveAll();
}
/****************************************************************************
* Asynchronous mode helpers
*/
void SignalAsyncDriveEnd()
{
#ifdef _WINDOWS
::PostMessage(0, (WM_USER + 202), 0, 0);
#else
printf("ERROR: SignalAsyncDriveEnd not implemented.\n");
#endif
}
void WaitAsyncDriveEnd()
{
#ifdef _WINDOWS
MSG msg;
while(GetMessage(&msg, 0, 0, 0))
{
if(msg.message == (WM_USER + 202))
{
break;
}
DispatchMessage(&msg);
}
#else
printf("ERROR: WaitAsyncDriveEnd not implemented.\n");
#endif
@@ -580,241 +629,273 @@
AddRef();
*ppvObj = (IUnknown*)(IHXMetaDataEditorResponse*)this;
return HXR_OK;
}
if(IsEqualIID(riid, IID_IHXMetaDataEditorResponse))
{
AddRef();
*ppvObj = (IHXMetaDataEditorResponse*)this;
return HXR_OK;
}
*ppvObj = 0;
return HXR_NOINTERFACE;
}
STDMETHOD_(ULONG32, AddRef)()
{
return InterlockedIncrement(&m_lRefCount);
}
STDMETHOD_(ULONG32, Release)()
{
if(InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
STDMETHOD(InitMetaDataEditorResponse)(IUnknown* pContext, IHXValues* pOptions)
{
return HXR_OK;
}
- STDMETHOD(OnProgress)(UINT32 progress)
+ STDMETHOD(OnProgress)(ULONG32 progress)
{
return HXR_OK;
}
- STDMETHOD(OnTerminate)(HX_RESULT result, BOOL bWritingFile)
+ STDMETHOD(OnTerminate)(HX_RESULT result, HXBOOL bWritingFile)
{
m_TerminationStatus = result;
- if(!g_bSynchronousMode)
+ if(!g_bUseDTDriverSynchronousMode)
{
SignalAsyncDriveEnd();
}
return HXR_OK;
}
HX_RESULT GetTerminationStatus()
{
return m_TerminationStatus;
}
private:
LONG32 m_lRefCount;
HX_RESULT m_TerminationStatus;
};
/****************************************************************************
+* MetaProcessorVars
+*/
+struct MetaProcessorVars
+{
+ MetaProcessorVars()
+ : ClearMetaData(FALSE)
+ , ClearKeywords(FALSE)
+ , InjectedMetaFlavors(0)
+ {
+ }
+
+ ~MetaProcessorVars()
+ {
+ ClearPropertyStringArray(AddedKeywords);
+ ClearPropertyStringArray(RemovedKeywords);
+ }
+
+ HX_RESULT CopyAddedKeywordsToInjected()
+ {
+ for(INT32 i = 0; i < AddedKeywords.GetSize(); i++)
+ {
+ if(!InjectedMetaInfo.AddKeyword(*((EncodedString*)AddedKeywords[i])))
+ {
+ return HXR_FAILED;
+ }
+ }
+ return HXR_OK;
+ }
+
+ // meta-data input params
+ HXBOOL ClearMetaData;
+ HXBOOL ClearKeywords;
+ ULONG32 InjectedMetaFlavors;
+ MetaInfo InjectedMetaInfo;
+ CHXPtrArray AddedKeywords;
+ CHXPtrArray RemovedKeywords;
+
+ // meta-data output storage
+ MetaInfo ExtractedMetaInfo;
+ MetaInfo OutboundMetaInfo;
+};
+
+
+/****************************************************************************
* Meta-data processor
*/
class CProcessor : public IHXMetaDataProcessor
{
public:
- CProcessor()
+ CProcessor(MetaProcessorVars& vars)
: m_lRefCount(0)
- , m_bClearMetaData(FALSE)
- , m_bClearKeywords(FALSE)
- {
- }
- virtual ~CProcessor()
+ , m_vars(vars)
{
- ClearPropertyStringArray(m_aAddedKeywords);
- ClearPropertyStringArray(m_aRemovedKeywords);
}
STDMETHOD(QueryInterface)(REFIID riid, void** ppvObj)
{
if(IsEqualIID(riid, IID_IUnknown))
{
AddRef();
*ppvObj = (IUnknown*)(IHXMetaDataProcessor*)this;
return HXR_OK;
}
if(IsEqualIID(riid, IID_IHXMetaDataProcessor))
{
AddRef();
*ppvObj = (IHXMetaDataProcessor*)this;
return HXR_OK;
}
*ppvObj = 0;
return HXR_NOINTERFACE;
}
STDMETHOD_(ULONG32, AddRef)()
{
return InterlockedIncrement(&m_lRefCount);
}
STDMETHOD_(ULONG32, Release)()
{
if(InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
STDMETHOD(InitMetaDataProcessor)(IUnknown* pContext, IHXValues* pOptions)
{
return HXR_OK;
}
STDMETHOD(OnInboundMetaData)(IHXValues* pExtracted, IHXValues* pInjectSink)
{
// keep extracted
- m_miExtracted.Clear();
- m_miExtracted.CopyFromValues(pExtracted);
+ m_vars.ExtractedMetaInfo.Clear();
+ m_vars.ExtractedMetaInfo.CopyFromValues(pExtracted, FALSE, METAINFO_SET_ALL);
- // modify meta-data
- MetaInfo3GP mi;
- if(!m_bClearMetaData)
+ // find out which sets of metadata should be passed through
+ MetaInfo mi;
+ ULONG32 injectedMetaInfoSets = MetaInfo::GetSetsFromFlavors(m_vars.InjectedMetaFlavors);
+
+ // check if the extracted metadata should be blocked or passed through
+ if(!m_vars.ClearMetaData)
{
- mi.Update(m_miExtracted);
+ mi.UpdateItems(m_vars.ExtractedMetaInfo, injectedMetaInfoSets);
}
- if(m_bClearKeywords)
+
+ // clear existing keywords if specified
+ if(m_vars.ClearKeywords)
{
mi.ClearKeywords();
}
- mi.Update(m_miInjected);
- for(INT32 iAdd = 0; iAdd < m_aAddedKeywords.GetSize(); iAdd++)
+ // inject new items / update extracted items
+ mi.UpdateItems(m_vars.InjectedMetaInfo, injectedMetaInfoSets);
+
+ // inject specified keywords
+ for(INT32 iAdd = 0; iAdd < m_vars.AddedKeywords.GetSize(); iAdd++)
{
- mi.AddKeyword(*((EncodedString*)m_aAddedKeywords[iAdd]));
+ mi.AddKeyword(*((EncodedString*)m_vars.AddedKeywords[iAdd]));
}
- for(INT32 iRem = 0; iRem < m_aRemovedKeywords.GetSize(); iRem++)
+
+ // remove specified keywords
+ for(INT32 iRem = 0; iRem < m_vars.RemovedKeywords.GetSize(); iRem++)
{
- mi.RemoveKeyword(*((EncodedString*)m_aRemovedKeywords[iRem]));
+ mi.RemoveKeyword(*((EncodedString*)m_vars.RemovedKeywords[iRem]));
}
- // transfer to inject sink
- mi.CopyToValues(pInjectSink);
+ // transfer final item set to the inject sink
+ mi.CopyToValues(pInjectSink, FALSE, METAINFO_SET_ALL);
return HXR_OK;
}
STDMETHOD(OnOutboundMetaData)(IHXValues* pValues)
{
// keep outbound
- m_miOutbound.Clear();
- m_miOutbound.CopyFromValues(pValues);
- return HXR_OK;
- }
-
- HX_RESULT CopyAddedKeywordsToInjected()
- {
- for(INT32 i = 0; i < m_aAddedKeywords.GetSize(); i++)
- {
- if(!m_miInjected.AddKeyword(*((EncodedString*)m_aAddedKeywords[i])))
- {
- return HXR_FAILED;
- }
- }
+ m_vars.OutboundMetaInfo.Clear();
+ m_vars.OutboundMetaInfo.CopyFromValues(pValues, FALSE, METAINFO_SET_ALL);
return HXR_OK;
}
-public:
- // meta-data input params
- MetaInfo3GP m_miInjected;
- BOOL m_bClearMetaData;
- BOOL m_bClearKeywords;
- CHXPtrArray m_aAddedKeywords;
- CHXPtrArray m_aRemovedKeywords;
-
- // meta-data output params
- MetaInfo3GP m_miExtracted;
- MetaInfo3GP m_miOutbound;
-
private:
LONG32 m_lRefCount;
+ MetaProcessorVars& m_vars;
};
/****************************************************************************
* Main entry point
*/
int TMAIN(int argc, TCHAR* argv[])
{
// separate shell command from output
TPrintf(_T("\n"));
// initialize variables
+ HXBOOL testDefaultMetaEditorProcessor = FALSE;
+ HXBOOL useDTDriverSynchronousMode = FALSE;
+
CHXFileSpecifier exeFileSpec;
- UINT32 startTime = 0;
+ ULONG32 startTime = 0;
DLLAccess* pDLLAccess = 0;
FPHXMEDIAPLATFORMOPEN fpHXMediaPlatformOpen = 0;
FPHXCREATEMEDIAPLATFORM fpHXCreateMediaPlatform = 0;
FPHXMEDIAPLATFORMCLOSE fpHXMediaPlatformClose = 0;
IHXMediaPlatform* pMediaPlatform = 0;
IHXCommonClassFactory* pCommonClassFactory = 0;
IHXMetaDataEditor* pEditor = 0;
CResponse* pResponse = 0;
CProcessor* pProcessor = 0;
IHXValues* pOptions = 0;
char pDllPath[_MAX_PATH] = {0};
char pDllFile[_MAX_PATH] = {0};
const char* pszHelixLibs = 0;
const TCHAR* ptInputFileName = 0;
char* pInputFileName = 0;
const TCHAR* ptOutputFileName = 0;
char* pOutputFileName = 0;
+ const TCHAR* ptMetaStyleName = 0;
+ char* pMetaStyleName = 0;
- BOOL bOverwriteFile = FALSE;
- BOOL bDisplayHelp = FALSE;
- BOOL bPrintMetaData = FALSE;
- BOOL bUTF16Output = FALSE;
+ HXBOOL bDisplayHelp = FALSE;
+ HXBOOL bOverwriteFile = FALSE;
+ HXBOOL bPrintMetaData = FALSE;
+ HXBOOL bUTF16Output = FALSE;
+
+ MetaProcessorVars metaProcessorVars;
// initialize Helix DNA client media-platform
HX_RESULT retVal = HXR_OK;
// load Helix media-platform library
pDLLAccess = new DLLAccess();
if(!pDLLAccess)
{
retVal = HXR_OUTOFMEMORY;
goto cleanup;
}
// extract plugin directory
#ifdef _WINDOWS
exeFileSpec = CHXFileSpecUtils::GetCurrentApplication();
strncpy(pDllPath, (const char*)exeFileSpec.GetParentDirectory().GetPathName(), _MAX_PATH);
snprintf(pDllFile, _MAX_PATH, "%s\\%s", pDllPath, "hxmedpltfm.dll");
#else
pszHelixLibs = getenv("HELIX_LIBS");
if(pszHelixLibs)
{
strncpy(pDllPath, pszHelixLibs, _MAX_PATH);
snprintf(pDllFile, _MAX_PATH, "%s/%s", pDllPath, "hxmedpltfm.so");
}
else
{
printf("Missing HELIX_LIBS environment variable\n");
goto cleanup;
}
@@ -811,477 +892,726 @@
if(pszHelixLibs)
{
strncpy(pDllPath, pszHelixLibs, _MAX_PATH);
snprintf(pDllFile, _MAX_PATH, "%s/%s", pDllPath, "hxmedpltfm.so");
}
else
{
printf("Missing HELIX_LIBS environment variable\n");
goto cleanup;
}
#endif
pDllPath[_MAX_PATH - 1] = '\0';
pDllFile[_MAX_PATH - 1] = '\0';
if(pDLLAccess->open(pDllFile) != DLLAccess::DLL_OK)
{
printf("Failed to access Helix DNA client media-platform library file: %s\n", pDllFile);
goto cleanup;
}
// initialize Helix media-platform
fpHXMediaPlatformOpen = (FPHXMEDIAPLATFORMOPEN) pDLLAccess->getSymbol("HXMediaPlatformOpen");
fpHXCreateMediaPlatform = (FPHXCREATEMEDIAPLATFORM) pDLLAccess->getSymbol("HXCreateMediaPlatform");
fpHXMediaPlatformClose = (FPHXMEDIAPLATFORMCLOSE) pDLLAccess->getSymbol("HXMediaPlatformClose");
if(!fpHXMediaPlatformOpen || !fpHXCreateMediaPlatform || !fpHXMediaPlatformClose)
{
retVal = HXR_FAILED;
}
+
if(SUCCEEDED(retVal))
{
retVal = fpHXMediaPlatformOpen();
}
+
if(SUCCEEDED(retVal))
{
retVal = fpHXCreateMediaPlatform((IHXMediaPlatform**)&pMediaPlatform);
}
+
if(SUCCEEDED(retVal))
{
retVal = pMediaPlatform->AddPluginPath("Meta3GP", pDllPath);
}
+
if(SUCCEEDED(retVal))
{
retVal = pMediaPlatform->Init(0);
}
+
if(SUCCEEDED(retVal))
{
retVal = pMediaPlatform->QueryInterface(IID_IHXCommonClassFactory, (void**)&pCommonClassFactory);
}
+
if(FAILED(retVal))
{
printf("Failed to initialize Helix DNA client media-platform.\n");
goto cleanup;
}
// initialize meta-data editor response object
pResponse = new CResponse();
HX_ADDREF(pResponse);
if(!pResponse)
{
retVal = HXR_OUTOFMEMORY;
}
+
if(FAILED(retVal))
{
printf("Failed to initialize Helix meta-data editor response object.\n");
goto cleanup;
}
// initialize meta-data processor object
- pProcessor = new CProcessor();
+ pProcessor = new CProcessor(metaProcessorVars);
HX_ADDREF(pProcessor);
if(!pProcessor)
{
retVal = HXR_OUTOFMEMORY;
}
+
if(FAILED(retVal))
{
printf("Failed to initialize Helix meta-data processor object.\n");
goto cleanup;
}
// initialize meta-data editor plugin
retVal = CreateInstanceCCF_QI(CLSID_IHXMetaDataEditor, IID_IHXMetaDataEditor,
(void**)&pEditor, pCommonClassFactory);
if(SUCCEEDED(retVal))
{
retVal = pEditor->InitMetaDataEditor(pCommonClassFactory);
}
+
if(FAILED(retVal))
{
printf("Failed to initialize Helix meta-data editor plugin.\n");
goto cleanup;
}
- // process commands
+ // The first phase seeks for independent arguments, the second phase seeks for dependent arguments.
+ enum eCommandLineProcessorPhase
+ {
+ CommandLineProcessorPhase_IndependentArgs = 0,
+ CommandLineProcessorPhase_DependentArgs,
+ CommandLineProcessorPhase_Done
+ };
+ eCommandLineProcessorPhase clProcessorPhase = CommandLineProcessorPhase_IndependentArgs;
+
+ while(SUCCEEDED(retVal) && (clProcessorPhase != CommandLineProcessorPhase_Done))
+ {
for(int argIndex = 1; (argIndex < argc) && SUCCEEDED(retVal); argIndex++)
{
- // accept option format only
+ // accept parameter format only
if(*argv[argIndex] != _T('-'))
{
- TPrintf(_T("Found non option command-line argument: %s\n"), argv[argIndex]);
+ TPrintf(_T("Found non-parameter command-line argument: %s\n"), argv[argIndex]);
retVal = HXR_PARSE_ERROR;
continue;
}
- TCHAR* pOption = argv[argIndex] + 1;
+ TCHAR* pParam = argv[argIndex] + 1;
- if(TStringEqual(pOption, OPTION_STRING_INPUTFILE))
+ if(TStringEqual(pParam, PARAM_STRING_HELP))
{
- ptInputFileName = NextArg(retVal, argIndex, argc, argv);
+ bDisplayHelp = TRUE;
+ }
+ else if(TStringEqual(pParam, PARAM_STRING_SYNCMODE))
+ {
+ g_bUseDTDriverSynchronousMode = TRUE;
+ }
+ else if(TStringEqual(pParam, PARAM_STRING_DEFMETAPROC))
+ {
+ g_bUseDefaultMetaEditorProcessor = TRUE;
+ }
+ else if(TStringEqual(pParam, PARAM_STRING_INPUTFILE))
+ {
+ if(clProcessorPhase == CommandLineProcessorPhase_IndependentArgs)
+ {
+ ptInputFileName = NextArg(retVal, argIndex, argc, argv, PARAM_STRING_INPUTFILE);
pInputFileName = TConvertToCCPString(ptInputFileName);
}
- else if(TStringEqual(pOption, OPTION_STRING_OUTPUTFILE))
+ else
{
- ptOutputFileName = NextArg(retVal, argIndex, argc, argv);
+ // already processed, just the argument
+ argIndex++;
+ }
+ }
+ else if(TStringEqual(pParam, PARAM_STRING_OUTPUTFILE))
+ {
+ if(clProcessorPhase == CommandLineProcessorPhase_IndependentArgs)
+ {
+ ptOutputFileName = NextArg(retVal, argIndex, argc, argv, PARAM_STRING_OUTPUTFILE);
pOutputFileName = TConvertToCCPString(ptOutputFileName);
}
- else if(TStringEqual(pOption, OPTION_STRING_OVERWRITEFILE))
+ else
+ {
+ // already processed, just the argument
+ argIndex++;
+ }
+ }
+ else if(TStringEqual(pParam, PARAM_STRING_OVERWRITEFILE))
{
bOverwriteFile = TRUE;
}
- else if(TStringEqual(pOption, OPTION_STRING_CLEARMETADATA))
+ else if(TStringEqual(pParam, PARAM_STRING_CLEARMETADATA))
{
- pProcessor->m_bClearMetaData = TRUE;
+ metaProcessorVars.ClearMetaData = TRUE;
}
- else if(TStringEqual(pOption, OPTION_STRING_PRINTMETADATA))
+ else if(TStringEqual(pParam, PARAM_STRING_PRINTMETADATA))
{
bPrintMetaData = TRUE;
}
- else if(TStringEqual(pOption, OPTION_STRING_UTF16OUTPUT))
+ else if(TStringEqual(pParam, PARAM_STRING_METASTYLE))
+ {
+ if(clProcessorPhase == CommandLineProcessorPhase_IndependentArgs)
+ {
+ ptMetaStyleName = NextArg(retVal, argIndex, argc, argv, PARAM_STRING_METASTYLE);
+ pMetaStyleName = TConvertToCCPString(ptMetaStyleName);
+
+ if(SUCCEEDED(retVal))
+ {
+ if(!strcmpi(pMetaStyleName, "3gpp"))
+ {
+ metaProcessorVars.InjectedMetaFlavors |= METADATA_FLAVOR_3GPP;
+ }
+ else if(!strcmpi(pMetaStyleName, "itunes"))
+ {
+ metaProcessorVars.InjectedMetaFlavors |= METADATA_FLAVOR_ITUNES;
+ }
+ else
+ {
+ retVal = HXR_PARSE_ERROR;
+ ReportInvalidValueForParameter(PARAM_STRING_METASTYLE, ptMetaStyleName);
+ }
+ }
+ }
+ else
+ {
+ // already processed, just the argument
+ argIndex++;
+ }
+ }
+ else if(TStringEqual(pParam, PARAM_STRING_UTF16OUTPUT))
{
bUTF16Output = TRUE;
}
- else if(TStringEqual(pOption, OPTION_STRING_HELP))
+ else if(TStringEqual(pParam, PARAM_STRING_TITLE))
{
- bDisplayHelp = TRUE;
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_Title,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_TITLE);
}
- else if(TStringEqual(pOption, OPTION_STRING_LANGUAGE_CODE))
+ else if(TStringEqual(pParam, PARAM_STRING_ARTIST))
{
- ExtractStringOption(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetGlobalLanguageEncoding, OPTION_STRING_LANGUAGE_CODE);
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_Artist,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_ARTIST);
}
- else if(TStringEqual(pOption, OPTION_STRING_TITLE))
+ else if(TStringEqual(pParam, PARAM_STRING_ALBUM))
{
- ExtractStringOption(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetTitle, OPTION_STRING_TITLE);
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_Album,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_ALBUM);
}
- else if(TStringEqual(pOption, OPTION_STRING_AUTHOR))
+ else if(TStringEqual(pParam, PARAM_STRING_GENRE))
{
- ExtractStringOption(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetAuthor, OPTION_STRING_AUTHOR);
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_Genre,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_GENRE);
}
- else if(TStringEqual(pOption, OPTION_STRING_COPYRIGHT))
+ else if(TStringEqual(pParam, PARAM_STRING_COMPOSER))
{
- ExtractStringOption(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetCopyright, OPTION_STRING_COPYRIGHT);
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_Composer,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_COMPOSER);
}
- else if(TStringEqual(pOption, OPTION_STRING_DESCRIPTION))
+ else if(TStringEqual(pParam, PARAM_STRING_COMMENT))
{
- ExtractStringOption(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetDescription, OPTION_STRING_DESCRIPTION);
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_Comment,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_COMMENT);
}
- else if(TStringEqual(pOption, OPTION_STRING_PERFORMER))
+ else if(TStringEqual(pParam, PARAM_STRING_COPYRIGHT))
{
- ExtractStringOption(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetPerformer, OPTION_STRING_PERFORMER);
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_Copyright,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_COPYRIGHT);
}
- else if(TStringEqual(pOption, OPTION_STRING_GENRE))
+ else if(TStringEqual(pParam, PARAM_STRING_TRACKNUMBER))
{
- ExtractStringOption(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetGenre, OPTION_STRING_GENRE);
+ ExtractULONG32Param(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::UlongMetaItem_TrackNumber,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_TRACKNUMBER);
}
- else if(TStringEqual(pOption, OPTION_STRING_RATING_ENTITY))
+ else if(TStringEqual(pParam, PARAM_STRING_YEAR))
{
- ExtractStringOption(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetRatingEntity, OPTION_STRING_RATING_ENTITY);
+ ExtractULONG32Param(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::UlongMetaItem_RecordingYear,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_YEAR);
}
- else if(TStringEqual(pOption, OPTION_STRING_RATING_CRITERIA))
+ else if(TStringEqual(pParam, PARAM_STRING_SOFTWARE))
{
- ExtractStringOption(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetRatingCriteria, OPTION_STRING_RATING_CRITERIA);
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_GeneratorTool,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_SOFTWARE);
}
- else if(TStringEqual(pOption, OPTION_STRING_RATING_INFO))
+ else if(TStringEqual(pParam, PARAM_STRING_GROUPING))
{
- ExtractStringOption(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetRatingInfo, OPTION_STRING_RATING_INFO);
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_Grouping,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_GROUPING);
}
- else if(TStringEqual(pOption, OPTION_STRING_CLASSIFICATION_ENTITY))
+ else if(TStringEqual(pParam, PARAM_STRING_ALBUMARTIST))
{
- ExtractStringOption(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetClassificationEntity, OPTION_STRING_CLASSIFICATION_ENTITY);
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_AlbumArtist,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_ALBUMARTIST);
}
-
- else if(TStringEqual(pOption, OPTION_STRING_CLASSIFICATION_TABLE))
+ else if(TStringEqual(pParam, PARAM_STRING_LYRICS))
{
- ExtractUINT16Option(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetClassificationTable, OPTION_STRING_CLASSIFICATION_TABLE);
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_Lyrics,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_LYRICS);
}
- else if(TStringEqual(pOption, OPTION_STRING_CLASSIFICATION_INFO))
+ else if(TStringEqual(pParam, PARAM_STRING_SUBTITLE))
{
- ExtractStringOption(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetClassificationInfo, OPTION_STRING_CLASSIFICATION_INFO);
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_TrackSubtitle,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_SUBTITLE);
}
- else if(TStringEqual(pOption, OPTION_STRING_KEYWORD_ADD))
+ else if(TStringEqual(pParam, PARAM_STRING_BPM))
{
- ExtractKeywordStringOption(retVal, argIndex, argc, argv,
- pProcessor->m_aAddedKeywords, OPTION_STRING_KEYWORD_ADD);
+ ExtractULONG32Param(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::UlongMetaItem_BeatsPerMinute,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_BPM);
}
- else if(TStringEqual(pOption, OPTION_STRING_KEYWORD_REMOVE))
+ else if(TStringEqual(pParam, PARAM_STRING_PARTOFCOMP))
{
- ExtractKeywordStringOption(retVal, argIndex, argc, argv,
- pProcessor->m_aRemovedKeywords, OPTION_STRING_KEYWORD_REMOVE);
+ ExtractULONG32Param(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::UlongMetaItem_PartOfCompilation,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_PARTOFCOMP);
}
- else if(TStringEqual(pOption, OPTION_STRING_KEYWORD_CLEAR))
+ else if(TStringEqual(pParam, PARAM_STRING_EXPLICIT))
{
- pProcessor->m_bClearKeywords = TRUE;
+ ExtractULONG32Param(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::UlongMetaItem_ExplicitContent,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_EXPLICIT);
}
- else if(TStringEqual(pOption, OPTION_STRING_LOCATION_NAME))
+ else if(TStringEqual(pParam, PARAM_STRING_TRACKSTOTAL))
{
- ExtractStringOption(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetLocationName, OPTION_STRING_LOCATION_NAME);
+ ExtractULONG32Param(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::UlongMetaItem_TrackCount,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_TRACKSTOTAL);
}
- else if(TStringEqual(pOption, OPTION_STRING_LOCATION_ASTRONOMICAL_BODY))
+ else if(TStringEqual(pParam, PARAM_STRING_DISKNUMBER))
{
- ExtractStringOption(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetLocationAstronomicalBody, OPTION_STRING_LOCATION_ASTRONOMICAL_BODY);
+ ExtractULONG32Param(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::UlongMetaItem_DiscNumber,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_DISKNUMBER);
}
- else if(TStringEqual(pOption, OPTION_STRING_LOCATION_ADDITIONAL_NOTES))
+ else if(TStringEqual(pParam, PARAM_STRING_DISKSTOTAL))
{
- ExtractStringOption(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetLocationAdditionalNotes, OPTION_STRING_LOCATION_ADDITIONAL_NOTES);
+ ExtractULONG32Param(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::UlongMetaItem_DiscCount,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_DISKSTOTAL);
}
- else if(TStringEqual(pOption, OPTION_STRING_LOCATION_ROLE))
+ else if(TStringEqual(pParam, PARAM_STRING_LANGUAGE_CODE))
{
- ExtractUINT8Option(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetLocationRole, OPTION_STRING_LOCATION_ROLE);
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_GlobalLanguageEncoding,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_LANGUAGE_CODE);
}
- else if(TStringEqual(pOption, OPTION_STRING_LOCATION_LONGITUDE))
+ else if(TStringEqual(pParam, PARAM_STRING_RATING_ENTITY))
{
- ExtractStringOption(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetLocationLongitude, OPTION_STRING_LOCATION_LONGITUDE);
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_RatingEntity,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_RATING_ENTITY);
}
- else if(TStringEqual(pOption, OPTION_STRING_LOCATION_LATITUDE))
+ else if(TStringEqual(pParam, PARAM_STRING_RATING_CRITERIA))
{
- ExtractStringOption(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetLocationLatitude, OPTION_STRING_LOCATION_LATITUDE);
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_RatingCriteria,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_RATING_CRITERIA);
}
- else if(TStringEqual(pOption, OPTION_STRING_LOCATION_ALTITUDE))
+ else if(TStringEqual(pParam, PARAM_STRING_RATING_INFO))
{
- ExtractStringOption(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetLocationAltitude, OPTION_STRING_LOCATION_ALTITUDE);
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_RatingInfo,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_RATING_INFO);
}
- else if(TStringEqual(pOption, OPTION_STRING_ALBUM))
+ else if(TStringEqual(pParam, PARAM_STRING_CLASSIFICATION_ENTITY))
{
- ExtractStringOption(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetAlbumTitle, OPTION_STRING_ALBUM);
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_ClassificationEntity,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_CLASSIFICATION_ENTITY);
}
- else if(TStringEqual(pOption, OPTION_STRING_TRACK))
+ else if(TStringEqual(pParam, PARAM_STRING_CLASSIFICATION_TABLE))
{
- ExtractUINT8Option(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetAlbumTrackNumber, OPTION_STRING_TRACK);
+ ExtractULONG32Param(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::UlongMetaItem_ClassificationTable,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_CLASSIFICATION_TABLE);
}
- else if(TStringEqual(pOption, OPTION_STRING_YEAR))
+ else if(TStringEqual(pParam, PARAM_STRING_CLASSIFICATION_INFO))
{
- ExtractUINT16Option(retVal, argIndex, argc, argv, pProcessor->m_miInjected,
- &MetaInfo3GP::SetRecordingYear, OPTION_STRING_YEAR);
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_ClassificationInfo,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_CLASSIFICATION_INFO);
+ }
+ else if(TStringEqual(pParam, PARAM_STRING_LOCATION_NAME))
+ {
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_LocationName,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_LOCATION_NAME);
+ }
+ else if(TStringEqual(pParam, PARAM_STRING_LOCATION_ASTRONOMICAL_BODY))
+ {
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_LocationAstronomicalBody,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_LOCATION_ASTRONOMICAL_BODY);
+ }
+ else if(TStringEqual(pParam, PARAM_STRING_LOCATION_ADDITIONAL_NOTES))
+ {
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_LocationAdditionalNotes,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_LOCATION_ADDITIONAL_NOTES);
+ }
+ else if(TStringEqual(pParam, PARAM_STRING_LOCATION_ROLE))
+ {
+ ExtractULONG32Param(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::UlongMetaItem_LocationRole,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_LOCATION_ROLE);
+ }
+ else if(TStringEqual(pParam, PARAM_STRING_LOCATION_LONGITUDE))
+ {
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_LocationLongitude,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_LOCATION_LONGITUDE);
+ }
+ else if(TStringEqual(pParam, PARAM_STRING_LOCATION_LATITUDE))
+ {
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_LocationLatitude,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_LOCATION_LATITUDE);
+ }
+ else if(TStringEqual(pParam, PARAM_STRING_LOCATION_ALTITUDE))
+ {
+ ExtractStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.InjectedMetaInfo, MetaInfo::StringMetaItem_LocationAltitude,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_LOCATION_ALTITUDE);
+ }
+ else if(TStringEqual(pParam, PARAM_STRING_KEYWORD_ADD))
+ {
+ ExtractKeywordStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.AddedKeywords,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_KEYWORD_ADD);
+ }
+ else if(TStringEqual(pParam, PARAM_STRING_KEYWORD_REMOVE))
+ {
+ ExtractKeywordStringParam(retVal, (clProcessorPhase != CommandLineProcessorPhase_DependentArgs),
+ argIndex, argc, argv, metaProcessorVars.RemovedKeywords,
+ metaProcessorVars.InjectedMetaFlavors, PARAM_STRING_KEYWORD_REMOVE);
+ }
+ else if(TStringEqual(pParam, PARAM_STRING_KEYWORD_CLEAR))
+ {
+ metaProcessorVars.ClearKeywords = TRUE;
+
+ if((clProcessorPhase == CommandLineProcessorPhase_DependentArgs) &&
+ !MetaInfo::IsItemSupportedByAnyFlavor(MetaInfo::StringMetaItem_Keywords, metaProcessorVars.InjectedMetaFlavors))
+ {
+ ReportUnsupportedMetaStyleParam(PARAM_STRING_KEYWORD_CLEAR);
+ retVal = HXR_PARSE_ERROR;
+ }
}
else
{
- TPrintf(_T("Unrecognized command: -%s\n"), pOption);
+ TPrintf(_T("Unrecognized parameter: -%s\n"), pParam);
retVal = HXR_PARSE_ERROR;
}
}
- // check for semantic errors
- if(SUCCEEDED(retVal) && !bDisplayHelp)
+ // update metastylese
+ if(clProcessorPhase == CommandLineProcessorPhase_IndependentArgs)
{
- if(!pInputFileName)
+ // unless metastyles are explicitly specified, assume defaults according to file extension
+ if((metaProcessorVars.InjectedMetaFlavors == 0) && pOutputFileName)
{
- TPrintf(_T("Input file not specified.\n"));
- retVal = HXR_PARSE_ERROR;
+ CHXString sFileExt = "";
+ CHXString sFileName = pOutputFileName;
+ INT32 dotPos = sFileName.ReverseFind('.');
+
+ if(dotPos >= 0)
+ {
+ ULONG32 extLen = sFileName.GetLength() - dotPos - 1;
+ if(extLen > 0)
+ {
+ sFileExt = sFileName.Right(extLen);
}
}
- if(retVal == HXR_PARSE_ERROR)
+
+ if(!sFileExt.CompareNoCase("3gp"))
{
- bDisplayHelp = TRUE;
+ metaProcessorVars.InjectedMetaFlavors |= METADATA_FLAVOR_3GPP;
+ }
+ else if(!sFileExt.CompareNoCase("m4a"))
+ {
+ metaProcessorVars.InjectedMetaFlavors |= METADATA_FLAVOR_ITUNES;
+ }
+ }
+ }
+
+ // next phase
+ clProcessorPhase = (eCommandLineProcessorPhase)(int(clProcessorPhase) + 1);
}
// display usage
+ if(argc == 1)
+ {
+ // auto help display if started without parameters
+ bDisplayHelp = TRUE;
+ }
+
if(bDisplayHelp)
{
DisplayUsage(argv[0]);
goto cleanup;
}
+ // check for semantic errors
+ if(SUCCEEDED(retVal) && !bDisplayHelp)
+ {
+ if(!pInputFileName)
+ {
+ TPrintf(_T("Input file not specified.\n"));
+ retVal = HXR_PARSE_ERROR;
+ }
+ }
+
+ // cleanup on command-line errors
+ if(FAILED(retVal))
+ {
+ goto cleanup;
+ }
+
// input file must exist
if(SUCCEEDED(retVal) && !CHXFileSpecUtils::FileExists(CHXFileSpecifier(pInputFileName)))
{
TPrintf(_T("Input file '%s' not found.\n"), ptInputFileName);
retVal = HXR_FAIL;
}
+
if(SUCCEEDED(retVal) && pOutputFileName)
{
// writing to input file is not allowed
if(SUCCEEDED(retVal) && !strcmp(pInputFileName, pOutputFileName))
{
TPrintf(_T("File '%s' cannot be used for both input and output.\n"), ptOutputFileName);
retVal = HXR_FAIL;
}
// output file must not exist or overwrite must be specified
if(SUCCEEDED(retVal) && CHXFileSpecUtils::FileExists(CHXFileSpecifier(pOutputFileName)) && !bOverwriteFile)
{
- TPrintf(_T("Output file '%s' already exists. Use -%s command to force overwrite.\n"),
- ptOutputFileName, OPTION_STRING_OVERWRITEFILE);
+ TPrintf(_T("Output file '%s' already exists. Use -%s parameter to force overwrite.\n"),
+ ptOutputFileName, PARAM_STRING_OVERWRITEFILE);
retVal = HXR_FAIL;
}
}
+
if(FAILED(retVal))
{
goto cleanup;
}
// initialize options
retVal = CreateInstanceCCF_QI(CLSID_IHXValues, IID_IHXValues,
(void**)&pOptions, pCommonClassFactory);
if(SUCCEEDED(retVal))
{
- retVal = pOptions->SetPropertyULONG32(SYNCHRONOUS_OPTION_NAME, g_bSynchronousMode ? 1 : 0);
+ retVal = pOptions->SetPropertyULONG32(SYNCHRONOUS_OPTION_NAME, g_bUseDTDriverSynchronousMode ? 1 : 0);
}
+
if(SUCCEEDED(retVal))
{
retVal = pOptions->SetPropertyULONG32(BLASTFILE_OPTION_NAME, bOverwriteFile ? 1 : 0);
}
+
if(SUCCEEDED(retVal))
{
retVal = pOptions->SetPropertyULONG32(UTF16OUTPUT_OPTION_NAME, bUTF16Output ? 1 : 0);
}
+
if(SUCCEEDED(retVal))
{
- // Notify meta-editor that it's dealing with 3GP meta-data.
- retVal = pOptions->SetPropertyULONG32(METADATAFLAVOR_OPTION_NAME, ULONG32(METADATA_FLAVOR_3GP));
+ // Notify meta-editor about the flavor of meta-data it should process.
+ retVal = pOptions->SetPropertyULONG32(METADATAFLAVOR_OPTION_NAME, metaProcessorVars.InjectedMetaFlavors);
}
+
if(SUCCEEDED(retVal))
{
-#ifdef TEST_DEFAULT_META_EDITOR_PROCESSOR
- retVal = pOptions->SetPropertyULONG32(BLASTMETADATA_OPTION_NAME,
- pProcessor->m_bClearMetaData ? 1 : 0);
-#else
+ if(g_bUseDefaultMetaEditorProcessor)
+ {
+ retVal = pOptions->SetPropertyULONG32(BLASTMETADATA_OPTION_NAME, metaProcessorVars.ClearMetaData ? 1 : 0);
+ }
+ else
+ {
// Notify meta-editor that we do not want it to perform any default internal meta-data merging.
// Custom processor in this application performs special merging of extracted and injected meta-data.
retVal = pOptions->SetPropertyULONG32(BLASTMETADATA_OPTION_NAME, 1);
-#endif
}
+ }
+
if(FAILED(retVal))
{
printf("Failed to initialize options.\n");
goto cleanup;
}
+ // display metasyle info
+ {
+ CHXString sStyles = MetaInfo::GetFlavorNames(metaProcessorVars.InjectedMetaFlavors);
+ printf("%s metastyles: %s\n\n",
+ pOutputFileName ? "Injecting" : "Extracting",
+ sStyles.IsEmpty() ? "[None]" : (const char*)sStyles);
+ }
+
// start file processing
startTime = HX_GET_BETTERTICKCOUNT();
-#ifdef TEST_DEFAULT_META_EDITOR_PROCESSOR
- printf("WARNING: Testing default meta-data processor.\n"
- "The following commands will not work: kwrem, kwclr.\n\n");
+ if(g_bUseDefaultMetaEditorProcessor)
+ {
+ TPrintf(_T("WARNING: Using default meta-data processor.\n")
+ _T("Some features will not work correctly: %s, %s.\n\n"),
+ PARAM_STRING_KEYWORD_REMOVE, PARAM_STRING_KEYWORD_CLEAR);
// read meta-info by using meta-editor's default meta-data processor
IHXValues* pExtractedMetaData = 0;
if(SUCCEEDED(retVal))
{
retVal = pEditor->Read(pInputFileName, pExtractedMetaData,
pOptions, (IHXMetaDataEditorResponse*)pResponse);
}
- if(SUCCEEDED(retVal) && !g_bSynchronousMode)
+
+ if(SUCCEEDED(retVal) && !g_bUseDTDriverSynchronousMode)
{
WaitAsyncDriveEnd();
retVal = pResponse->GetTerminationStatus();
}
+
if(SUCCEEDED(retVal))
{
- pProcessor->m_miExtracted.Clear();
- pProcessor->m_miExtracted.CopyFromValues(pExtractedMetaData);
+ metaProcessorVars.ExtractedMetaInfo.Clear();
+ metaProcessorVars.ExtractedMetaInfo.CopyFromValues(pExtractedMetaData, FALSE, METAINFO_SET_ALL);
}
+
HX_RELEASE(pExtractedMetaData);
// write meta-info by using meta-editor's default meta-data processor
if(SUCCEEDED(retVal) && pOutputFileName)
{
IHXValues* pInjectedMetaData = 0;
retVal = CreateInstanceCCF_QI(CLSID_IHXValues, IID_IHXValues,
(void**)&pInjectedMetaData, pCommonClassFactory);
if(SUCCEEDED(retVal))
{
- retVal = pProcessor->CopyAddedKeywordsToInjected();
+ retVal = metaProcessorVars.CopyAddedKeywordsToInjected();
}
+
if(SUCCEEDED(retVal))
{
- pProcessor->m_miInjected.CopyToValues(pInjectedMetaData);
+ metaProcessorVars.InjectedMetaInfo.CopyToValues(pInjectedMetaData, FALSE, METAINFO_SET_ALL);
retVal = pEditor->Write(pInputFileName, pOutputFileName, pInjectedMetaData,
pOptions, (IHXMetaDataEditorResponse*)pResponse);
}
+
HX_RELEASE(pInjectedMetaData);
- if(SUCCEEDED(retVal) && !g_bSynchronousMode)
+ if(SUCCEEDED(retVal) && !g_bUseDTDriverSynchronousMode)
{
WaitAsyncDriveEnd();
retVal = pResponse->GetTerminationStatus();
}
}
-#else //TEST_DEFAULT_META_EDITOR_PROCESSOR
-
+ }
+ else
+ {
// drive meta-info through meta-editor by using custom meta-data processor
if(SUCCEEDED(retVal))
{
retVal = pEditor->Drive(pInputFileName,
pOutputFileName,
(IHXMetaDataProcessor*)pProcessor,
pOptions,
(IHXMetaDataEditorResponse*)pResponse);
- if(SUCCEEDED(retVal) && !g_bSynchronousMode)
+ if(SUCCEEDED(retVal) && !g_bUseDTDriverSynchronousMode)
{
WaitAsyncDriveEnd();
retVal = pResponse->GetTerminationStatus();
}
}
-#endif //TEST_DEFAULT_META_EDITOR_PROCESSOR
+ }
if(FAILED(retVal))
{
TPrintf(_T("Failed to process input file '%s'.\n"), ptInputFileName);
}
+
+ // auto dump meta-data if extracting only
+ if(!pOutputFileName)
+ {
+ bPrintMetaData = TRUE;
+ }
+
if(SUCCEEDED(retVal) && bPrintMetaData)
{
TPrintf(_T("--- Extracted meta-data ---\n"));
- pProcessor->m_miExtracted.Dump();
+ metaProcessorVars.ExtractedMetaInfo.Dump();
TPrintf(_T("\n"));
-#ifndef TEST_DEFAULT_META_EDITOR_PROCESSOR
+ if(!g_bUseDefaultMetaEditorProcessor)
+ {
if(pOutputFileName)
{
TPrintf(_T("--- Injected meta-data ---\n"));
- pProcessor->m_miOutbound.Dump();
+ metaProcessorVars.OutboundMetaInfo.Dump();
TPrintf(_T("\n"));
}
-#endif //!TEST_DEFAULT_META_EDITOR_PROCESSOR
}
+ }
+
if(SUCCEEDED(retVal))
{
- UINT32 endTime = HX_GET_BETTERTICKCOUNT();
+ ULONG32 endTime = HX_GET_BETTERTICKCOUNT();
TPrintf(_T("Done. Processing time: %f seconds.\n"), (endTime - startTime) / 1000.0);
}
// cleanup objects
cleanup:
HX_RELEASE(pEditor);
HX_RELEASE(pProcessor);
HX_RELEASE(pResponse);
HX_RELEASE(pOptions);
HX_RELEASE(pCommonClassFactory);
if(pMediaPlatform)
{
pMediaPlatform->Close();
}
HX_RELEASE(pMediaPlatform);
+
if(fpHXMediaPlatformClose)
{
fpHXMediaPlatformClose();
}
HX_DELETE(pDLLAccess);
+
EncStrUtils::Deallocate(pInputFileName, EncStrUtils::ALLOC_FLAG_NEW);
EncStrUtils::Deallocate(pOutputFileName, EncStrUtils::ALLOC_FLAG_NEW);
+ EncStrUtils::Deallocate(pMetaStyleName, EncStrUtils::ALLOC_FLAG_NEW);
return retVal;
}
datatype_tools_dtdriver_common.diff
(text/x-patch, 1.9 KB)
Index: Umakefil
===================================================================
RCS file: /cvsroot/datatype/tools/dtdriver/common/Umakefil,v
retrieving revision 1.2
diff -d -H -w -U30 -r1.2 Umakefil
--- Umakefil 8 Dec 2005 17:58:16 -0000 1.2
+++ Umakefil 19 Oct 2009 12:51:22 -0000
@@ -12,38 +12,41 @@
# http://www.helixcommunity.org/content/rcsl, in which case the RCSL
# will apply. You may also obtain the license terms directly from
# RealNetworks. You may not use this file except in compliance with
# the RPSL or, if you have a valid RCSL with RealNetworks applicable
# to this file, the RCSL. Please see the applicable RPSL or RCSL for
# the rights, obligations and limitations governing use of the
# contents of the file.
#
# This file is part of the Helix DNA Technology. RealNetworks is the
# developer of the Original Code and owns the copyrights in the
# portions it created.
#
# This file, and the files included with this file, is distributed
# and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
# KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
# ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
# ENJOYMENT OR NON-INFRINGEMENT.
#
# Technology Compatibility Kit Test Suite(s) Location:
# http://www.helixcommunity.org/content/tck
#
# Contributor(s):
#
# ***** END LICENSE BLOCK *****
UmakefileVersion(2,0)
project.AddModuleIncludes("common/include",
+ "common/container/pub",
"common/runtime/pub",
- "common/dbgtool/pub")
+ "common/dbgtool/pub",
+ "common/util/pub",
+ "datatype/include")
project.AddSources("reporterror.cpp")
LibraryTarget('dtdrcomlib')
DependTarget()
datatype_tools_dtdriver_decoder.diff
(text/x-patch, 25.6 KB)
Index: audio/Umakefil
===================================================================
RCS file: /cvsroot/datatype/tools/dtdriver/decoder/audio/Umakefil,v
retrieving revision 1.4
diff -d -H -w -U30 -r1.4 Umakefil
--- audio/Umakefil 10 Jan 2005 19:08:46 -0000 1.4
+++ audio/Umakefil 19 Oct 2009 12:47:44 -0000
@@ -21,44 +21,46 @@
# developer of the Original Code and owns the copyrights in the portions
# it created.
#
# This file, and the files included with this file, is distributed and made
# available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
# EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
#
# Technology Compatibility Kit Test Suite(s) Location:
# http://www.helixcommunity.org/content/tck
#
# Contributor(s):
#
# ***** END LICENSE BLOCK *****
#
UmakefileVersion(2,0)
project.AddIncludes("../../common/pub",
"../../engine/pub",
"../common/pub")
project.AddModuleIncludes("common/include",
"common/runtime/pub",
"common/dbgtool/pub",
"common/util/pub",
"common/container/pub",
"common/system/pub",
"datatype/common/container/pub",
+ "datatype/include",
+ "datatype/common/util/pub",
"client/common/container/pub",
"client/audiosvc/pub",
"protocol/transport/rtp/include")
project.AddSources( 'adecoder.cpp',
'stubplay.cpp',
'stubastr.cpp')
if project.IsDefined("HELIX_FEATURE_DTDR_MIXER"):
project.AddSources('amixer.cpp')
LibraryTarget('dtdrauddec')
DependTarget()
Index: audio/adecoder.cpp
===================================================================
RCS file: /cvsroot/datatype/tools/dtdriver/decoder/audio/adecoder.cpp,v
retrieving revision 1.19
diff -d -H -w -U30 -r1.19 adecoder.cpp
--- audio/adecoder.cpp 24 Jan 2008 19:34:08 -0000 1.19
+++ audio/adecoder.cpp 19 Oct 2009 12:47:46 -0000
@@ -32,60 +32,61 @@
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "hxtypes.h"
#include "hxcom.h"
#include "hxplugn.h"
#include "ihxpckts.h"
#include "hxcore.h"
#include "hxrendr.h"
#include "hxausvc.h"
#include "hxrasyn.h"
#include "pckunpck.h" // SetCStringProperty
#include "plghand2.h"
#include "netbyte.h"
#include "hxtick.h"
#include "rtptypes.h"
#include "hxsrcin.h"
#include "csrchdlr.h"
#include "stubastr.h"
#include "stubplay.h"
#include "stubstrm.h"
#include "sdecmlog.h"
#include "adecoder.h"
#include "amixer.h"
#include "reporterror.h"
+#include "metautil.h"
#define _TRUNCATE_AUDIO_TO_ENDTIME
#define AUDIO_STREAM_TIME_TOLERANCE 3
// Maximum unmber of frames that can be handled at the time while
// ressampling before an overflow assuming 48KHz sampling rate.
#define MAX_FRAMES_TO_RESAMPLE_IN_SINGLE_STEP 89478
CAudioSourceHandler::CAudioSourceHandler(IUnknown* pContext) :
CSourceHandler(pContext)
{
MLOG_TRACE("%lu CON CAudioSourceHandler this=0x%08x\n",
HX_GET_BETTERTICKCOUNT(), this);
m_lRefCount = 0;
m_pFileHeaderIn = NULL;
m_pStreamHeaderIn = NULL;
m_pFileHeaderOut = NULL;
m_pStreamHeaderOut = NULL;
m_pMimeTypeStr = NULL;
m_pRenderer = NULL;
m_pAudioPlayer = NULL;
m_pStream = NULL;
m_pMixer = NULL;
m_pWriteQueue = NULL;
m_cFormat.uChannels = 0;
m_cFormat.uBitsPerSample = 0;
m_cFormat.ulSamplesPerSec = 0;
m_cFormat.uMaxBlockSize = 0;
@@ -1757,60 +1758,63 @@
{
pszMime = (ulBitsPerSample == 8 ? "audio/L8" : "audio/L16");
}
else
{
pszMime = (ulBitsPerSample == 8 ? "audio/L8" : "audio/X-RN-LE16");
}
SetCStringPropertyCCF(rpValues, "MimeType", pszMime, m_pContext);
}
// If we have been asked to provide source properties,
// then fill them in here
if (m_bSetSrcProperties)
{
// We attempt to recover each source property from
// the following sources in this order:
// 1) See if present in FILE header
// 2) See if present in STREAM header
// 3) See if renderer knows this property
// 4) See if present in stats (to be implemented later)
SetSourcePropertyCString(m_pStreamHeaderOut, "SrcCodec");
SetSourcePropertyCString(m_pStreamHeaderOut, "SrcInterleaver");
SetSourcePropertyULONG32(m_pStreamHeaderOut, "SrcBitRate");
SetSourcePropertyULONG32(m_pStreamHeaderOut, "SrcVBREnabled");
SetSourcePropertyULONG32(m_pStreamHeaderOut, "SrcVBRQuality");
// SetSourcePropertyCString(m_pStreamHeaderOut, "SrcInterleaved"); // not sure about this one
SetSourcePropertyULONG32(m_pStreamHeaderOut, "SrcSamplesPerSecond");
SetSourcePropertyULONG32(m_pStreamHeaderOut, "SrcBitsPerSample");
SetSourcePropertyULONG32(m_pStreamHeaderOut, "SrcNumChannels");
}
+
+ // Transfer metadata if present
+ MetaInfo::CopyAllProperties(rpValues, m_pStreamHeaderIn, METAINFO_SET_ALL, FALSE);
}
}
return retVal;
}
HXBOOL CAudioSourceHandler::GetBOOLOption(const char* pszStr, HXBOOL bDefault)
{
HXBOOL bRet = bDefault;
if (m_pOptions)
{
UINT32 ulValue = 0;
HX_RESULT rv = m_pOptions->GetPropertyULONG32(pszStr, ulValue);
if (SUCCEEDED(rv) && ulValue != 0)
{
bRet = TRUE;
}
else
{
bRet = FALSE;
}
}
return bRet;
}
ULONG32 CAudioSourceHandler::GetULONG32Option(const char* pszStr, ULONG32 ulDefault)
{
ULONG32 ulRet = ulDefault;
@@ -1931,67 +1935,65 @@
pValues->SetPropertyULONG32(pszProp, ulValue);
}
}
}
HX_RESULT CAudioSourceHandler::CallOnFileHeader()
{
HX_RESULT retVal = HXR_OK;
HX_RELEASE(m_pFileHeaderOut);
if (m_pFileHeaderIn)
{
if (m_bIsPassThru)
{
retVal = CopyValues(m_pFileHeaderIn, m_pFileHeaderOut);
}
else
{
// Create an IHXValues
retVal = CreateValuesCCF(m_pFileHeaderOut, m_pContext);
if (SUCCEEDED(retVal))
{
IHXBuffer* pBuffer = NULL;
// Set the stream count
m_pFileHeaderOut->SetPropertyULONG32("StreamCount", 1);
// Set the flag saying this is not a real datatype
m_pFileHeaderOut->SetPropertyULONG32("IsRealDataType", 0);
- // Transfer TAC if present
- CopyHdrBuffer("Title", m_pFileHeaderIn, m_pFileHeaderOut);
- CopyHdrBuffer("Author", m_pFileHeaderIn, m_pFileHeaderOut);
- CopyHdrBuffer("Copyright", m_pFileHeaderIn, m_pFileHeaderOut);
+ // Transfer metadata if present
+ MetaInfo::CopyAllProperties(m_pFileHeaderOut, m_pFileHeaderIn, METAINFO_SET_ALL, FALSE);
+
CopyHdrCString("AudioFormat", m_pFileHeaderIn,
m_pFileHeaderOut);
- CopyHdrCString("Abstract", m_pFileHeaderIn, m_pFileHeaderOut);
}
}
}
else
{
retVal = HXR_FAIL;
}
if (m_pSourceSink)
{
MLOG_TRACE(" sending file header to sink\n");
m_pSourceSink->OnFileHeader(retVal, m_pFileHeaderOut);
}
if (FAILED(retVal))
{
m_lLastError = retVal;
}
return retVal;
}
HXBOOL CAudioSourceHandler::ShouldBePassThru()
{
HXBOOL bRet = FALSE;
IHXBuffer* pSrcCodec = NULL;
IHXBuffer* pSrcIleave = NULL;
Index: video/Umakefil
===================================================================
RCS file: /cvsroot/datatype/tools/dtdriver/decoder/video/Umakefil,v
retrieving revision 1.7
diff -d -H -w -U30 -r1.7 Umakefil
--- video/Umakefil 17 Oct 2008 07:46:50 -0000 1.7
+++ video/Umakefil 19 Oct 2009 12:47:46 -0000
@@ -26,39 +26,40 @@
# EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
#
# Technology Compatibility Kit Test Suite(s) Location:
# http://www.helixcommunity.org/content/tck
#
# Contributor(s):
#
# ***** END LICENSE BLOCK *****
#
UmakefileVersion(2,0)
project.AddIncludes("../../common/pub",
"../../engine/pub",
"../common/pub")
project.AddModuleIncludes("common/include",
"common/runtime/pub",
"common/dbgtool/pub",
"common/util/pub",
"common/container/pub",
"common/system/pub",
"common/log/logutil/pub",
"client/include",
"video/include",
"video/colconverter/pub",
"client/common/container/pub",
"protocol/transport/rtp/include",
+ "datatype/include",
"datatype/common/util/pub")
project.AddModuleLibraries("datatype/common/util[dtutillib.lib]")
project.AddSources( 'vdecoder.cpp', 'vdepacker.cpp', 'stubvplay.cpp', 'stubsite.cpp' )
LibraryTarget('dtdrviddec')
DependTarget()
Index: video/vdecoder.cpp
===================================================================
RCS file: /cvsroot/datatype/tools/dtdriver/decoder/video/vdecoder.cpp,v
retrieving revision 1.32
diff -d -H -w -U30 -r1.32 vdecoder.cpp
--- video/vdecoder.cpp 26 May 2009 01:34:46 -0000 1.32
+++ video/vdecoder.cpp 19 Oct 2009 12:47:49 -0000
@@ -27,60 +27,61 @@
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "hxtypes.h"
#include "hxcom.h"
#include "hxplugn.h"
#include "ihxpckts.h"
#include "hxcore.h"
#include "hxrendr.h"
#include "hxausvc.h"
#include "hxrasyn.h"
#include "hxbuffer.h"
#include "multilog.h"
#include "pckunpck.h" // SetCStringProperty
#include "plghand2.h"
#include "netbyte.h"
#include "hxtick.h"
#include "rtptypes.h"
#include "hxcbobj.h"
#include "hxsrcin.h"
#include "reporterror.h"
+#include "metautil.h"
#include "csrchdlr.h"
#include "stubstrm.h"
#include "stubvplay.h"
#include "stubsite.h"
//#define HELIX_FEATURE_LOGLEVEL_NONE // uncomment to disable logging
#include "hxtlogutil.h"
#include "resize.h"
#include "coloracc.h"
#include "colormap.h"
#include "vdecoder.h"
#include "hlxclib/stdlib.h"
#define HX_VDECODER_CALLBACK_INTERVAL 10
#define HX_NO_COLOR_CONVERSION 0xFFFFFFFF
#define WIDTHBYTES(i) ((ULONG32)((i+31)&(~31))/8)
/*
#ifndef HELIX_FEATURE_VIDREND_UNTIMED_DECODE
#error "Somehow you are building video support in dtdriver without"
#error "HELIX_FEATURE_VIDREND_UNTIMED_DECODE defined. This is bad"
#error "because dtdrive can't simulate a real timeline and needs your"
#error "video renderer to be built with this option."
#endif // #ifndef HELIX_FEATURE_VIDREND_UNTIMED_DECODE
*/
#if defined(_DEBUG)
#define TRACE_TARGET_FILE 0
#define TRACE_TARGET_DEBUGGER 1
@@ -234,91 +235,69 @@
// on the options and has changed them since we
// were initialized
m_bProcessHeadersOnly = GetBOOLOption("ProcessHeadersOnly", m_bProcessHeadersOnly);
m_bMaxSpeed = GetBOOLOption("MaxSpeed", m_bMaxSpeed);
m_bSetSrcProperties = GetBOOLOption("SetSrcProperties", m_bSetSrcProperties);
m_ulStartTime = GetULONG32Option("StartTime", m_ulStartTime);
m_ulProcessTimeUnits = GetULONG32Option("ProcessTimeUnits", m_ulProcessTimeUnits);
if (SUCCEEDED(status) && pValues)
{
// Save the file header.
// XXXMEH - not sure that we'll need this,
// but go ahead and save it for now.
HX_RELEASE(m_pFileHeaderIn);
m_pFileHeaderIn = pValues;
m_pFileHeaderIn->AddRef();
// Create an IHXValues
HX_RELEASE(m_pFileHeaderOut);
retVal = CreateValuesCCF(m_pFileHeaderOut, m_pContext);
if (SUCCEEDED(retVal))
{
IHXBuffer* pBuffer = NULL;
// Set the stream count
m_pFileHeaderOut->SetPropertyULONG32("StreamCount", 1);
// TODO determine which inbound properties need to be propogated on
// Set the flag saying this is not a real datatype
m_pFileHeaderOut->SetPropertyULONG32("IsRealDataType", 0);
- // Transfer TAC if present
- m_pFileHeaderIn->GetPropertyBuffer("Title", pBuffer);
- if (pBuffer)
- {
- m_pFileHeaderOut->SetPropertyBuffer("Title", pBuffer);
- HX_RELEASE(pBuffer);
- }
- m_pFileHeaderIn->GetPropertyBuffer("Author", pBuffer);
- if (pBuffer)
- {
- m_pFileHeaderOut->SetPropertyBuffer("Author", pBuffer);
- HX_RELEASE(pBuffer);
- }
- m_pFileHeaderIn->GetPropertyBuffer("Copyright", pBuffer);
- if (pBuffer)
- {
- m_pFileHeaderOut->SetPropertyBuffer("Copyright", pBuffer);
- HX_RELEASE(pBuffer);
- }
+ // Transfer metadata if present
+ MetaInfo::CopyAllProperties(m_pFileHeaderOut, m_pFileHeaderIn, METAINFO_SET_ALL, FALSE);
+
m_pFileHeaderIn->GetPropertyCString("AudioFormat", pBuffer);
if (pBuffer)
{
m_pFileHeaderOut->SetPropertyCString("AudioFormat", pBuffer);
HX_RELEASE(pBuffer);
}
- m_pFileHeaderIn->GetPropertyCString("Abstract", pBuffer);
- if (pBuffer)
- {
- m_pFileHeaderOut->SetPropertyCString("Abstract", pBuffer);
- HX_RELEASE(pBuffer);
- }
// Pass this along to the sink
if (m_pSourceSink)
{
HXLOGL4(HXLOG_DTDR, "\tCVideoSourceHandler[%p]::OnFileHeader(status=0x%08x,) sending file header to sink", this, status);
m_pSourceSink->OnFileHeader(HXR_OK, m_pFileHeaderOut);
}
}
}
else
{
retVal = HXR_FAIL;
}
// If we failed, then still call to the sink
if (FAILED(retVal) && m_pSourceSink)
{
m_pSourceSink->OnFileHeader(retVal, NULL);
m_lLastError = retVal;
}
return retVal;
}
STDMETHODIMP CVideoSourceHandler::OnStreamHeader( HX_RESULT status, IHXValues* pValues)
{
HXLOGL4(HXLOG_DTDR, "CVideoSourceHandler[%p]::OnStreamHeader(status=0x%08x,)", this, status);
HX_RESULT retVal = HXR_FAIL;
if (SUCCEEDED(status) && pValues)
@@ -818,60 +797,63 @@
rpValues->SetPropertyULONG32("Width", nWidth);
rpValues->SetPropertyULONG32("Height", nHeight);
// add properties from input stream header
if (m_pStreamHeaderIn)
{
UINT32 ulTmp = 0;
if (SUCCEEDED(m_pStreamHeaderIn->GetPropertyULONG32("FramesPerMSecond", ulTmp)))
{
rpValues->SetPropertyULONG32("FramesPerMSecond", ulTmp);
}
}
// If we have been asked to provide source properties,
// then fill them in here
if (m_bSetSrcProperties)
{
// We attempt to recover each source property from
// the following sources in this order:
// 1) See if present in FILE header
// 2) See if present in STREAM header
// 3) See if renderer knows this property
// 4) See if present in stats (to be implemented later)
SetSourcePropertyCString(m_pStreamHeaderOut, "SrcCodec");
SetSourcePropertyULONG32(m_pStreamHeaderOut, "SrcBitRate");
SetSourcePropertyULONG32(m_pStreamHeaderOut, "SrcVBREnabled");
SetSourcePropertyULONG32(m_pStreamHeaderOut, "SrcVBRQuality");
SetSourcePropertyULONG32(m_pStreamHeaderOut, "SrcFramesPerMSecond");
SetSourcePropertyULONG32(m_pStreamHeaderOut, "SrcWidth");
SetSourcePropertyULONG32(m_pStreamHeaderOut, "SrcHeight");
}
+
+ // Transfer metadata if present
+ MetaInfo::CopyAllProperties(rpValues, m_pStreamHeaderIn, METAINFO_SET_ALL, FALSE);
}
return retVal;
}
STDMETHODIMP CVideoSourceHandler::OnVideoBlt( HXBitmapInfoHeader* pHeader, UCHAR* pData, REF(HXxRect) rSrcRect )
{
HXLOGL4(HXLOG_DTDR, "CVideoSourceHandler[%p]::OnVideoBlt()", this);
HX_RESULT retVal = HXR_FAIL;
UINT32 currentTime = 0;
m_pRenderTimeLine->GetTimeLineValue(currentTime);
if (m_bDoResizingVideo && !m_bValidResizingInputFormat)
{
return HXR_UNSUPPORTED_VIDEO;
}
if( HXxRect_IsEmpty(rSrcRect) )
{
HXxRect_Set(rSrcRect, 0, 0, pHeader->biWidth, pHeader->biHeight);
}
if (m_bFirstWrite)
{
// Set input and output width/height size for resizing
m_ulInputWidth = HXxRECT_WIDTH(rSrcRect);
m_ulInputHeight = HXxRECT_HEIGHT(rSrcRect);
if(rSrcRect.left != 0 || rSrcRect.top != 0 || rSrcRect.right != pHeader->biWidth || rSrcRect.bottom != pHeader->biHeight)
Index: video/vdepacker.cpp
===================================================================
RCS file: /cvsroot/datatype/tools/dtdriver/decoder/video/vdepacker.cpp,v
retrieving revision 1.3
diff -d -H -w -U30 -r1.3 vdepacker.cpp
--- video/vdepacker.cpp 30 Jan 2006 21:11:05 -0000 1.3
+++ video/vdepacker.cpp 19 Oct 2009 12:47:49 -0000
@@ -28,60 +28,61 @@
* ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "hxtypes.h"
#include "hlxclib/string.h"
#include "hxcom.h"
#include "hxplugn.h"
#include "ihxpckts.h"
#include "hxcore.h"
#include "hxformt.h"
#include "hxausvc.h"
#include "hxrasyn.h"
#include "hxbuffer.h"
#include "multilog.h"
#include "pckunpck.h" // SetCStringProperty
#include "plghand2.h"
#include "netbyte.h"
#include "hxtick.h"
#include "rtptypes.h"
#include "hxsrcin.h"
+#include "metautil.h"
#include "csrchdlr.h"
#include "stubstrm.h"
#include "vdepacker.h"
#if defined(_DEBUG)
#define TRACE_TARGET_FILE 0
#define TRACE_TARGET_DEBUGGER 1
#else
#define TRACE_TARGET_FILE 0
#define TRACE_TARGET_DEBUGGER 0
#endif
// Create an inline MLOG_TRACE() function
#ifndef MLOG_TRACE_COMPILED_OUT
INIT_MULTILOG_GROUP_NO_COREDEBUG(TRACE,
TRACE_TARGET_FILE,
TRACE_TARGET_DEBUGGER,
"sdepacker_trace.log");
#else
#define MLOG_TRACE if(0)
#endif
CVideoSourceDepacketizer::CVideoSourceDepacketizer(IUnknown* pContext) :
CSourceHandler(pContext)
{
MLOG_TRACE("%lu CON CVideoSourceDepacketizer this=0x%08x\n",
HX_GET_BETTERTICKCOUNT(), this);
m_lRefCount = 0;
@@ -182,91 +183,69 @@
// in case another object is also holding a ref
// on the options and has changed them since we
// were initialized
m_bProcessHeadersOnly = GetBOOLOption("ProcessHeadersOnly", m_bProcessHeadersOnly);
m_bMaxSpeed = GetBOOLOption("MaxSpeed", m_bMaxSpeed);
m_bSetSrcProperties = GetBOOLOption("SetSrcProperties", m_bSetSrcProperties);
m_ulStartTime = GetULONG32Option("StartTime", m_ulStartTime);
if (SUCCEEDED(status) && pValues)
{
// Save the file header.
// XXXMEH - not sure that we'll need this,
// but go ahead and save it for now.
HX_RELEASE(m_pFileHeaderIn);
m_pFileHeaderIn = pValues;
m_pFileHeaderIn->AddRef();
// Create an IHXValues
HX_RELEASE(m_pFileHeaderOut);
retVal = CreateValuesCCF(m_pFileHeaderOut, m_pContext);
if (SUCCEEDED(retVal))
{
IHXBuffer* pBuffer = NULL;
// Set the stream count
m_pFileHeaderOut->SetPropertyULONG32("StreamCount", 1);
// TODO determine which inbound properties need to be propogated on
// Set the flag saying this is not a real datatype
m_pFileHeaderOut->SetPropertyULONG32("IsRealDataType", 0);
- // Transfer TAC if present
- m_pFileHeaderIn->GetPropertyBuffer("Title", pBuffer);
- if (pBuffer)
- {
- m_pFileHeaderOut->SetPropertyBuffer("Title", pBuffer);
- HX_RELEASE(pBuffer);
- }
- m_pFileHeaderIn->GetPropertyBuffer("Author", pBuffer);
- if (pBuffer)
- {
- m_pFileHeaderOut->SetPropertyBuffer("Author", pBuffer);
- HX_RELEASE(pBuffer);
- }
- m_pFileHeaderIn->GetPropertyBuffer("Copyright", pBuffer);
- if (pBuffer)
- {
- m_pFileHeaderOut->SetPropertyBuffer("Copyright", pBuffer);
- HX_RELEASE(pBuffer);
- }
m_pFileHeaderIn->GetPropertyCString("AudioFormat", pBuffer);
if (pBuffer)
{
m_pFileHeaderOut->SetPropertyCString("AudioFormat", pBuffer);
HX_RELEASE(pBuffer);
}
- m_pFileHeaderIn->GetPropertyCString("Abstract", pBuffer);
- if (pBuffer)
- {
- m_pFileHeaderOut->SetPropertyCString("Abstract", pBuffer);
- HX_RELEASE(pBuffer);
- }
+
+ // Transfer metadata if present
+ MetaInfo::CopyAllProperties(m_pFileHeaderOut, m_pFileHeaderIn, METAINFO_SET_ALL, FALSE);
// Pass this along to the sink
if (m_pSourceSink)
{
MLOG_TRACE(" sending file header to sink\n");
m_pSourceSink->OnFileHeader(HXR_OK, m_pFileHeaderOut);
}
}
}
else
{
retVal = HXR_FAIL;
}
// If we failed, then still call to the sink
if (FAILED(retVal) && m_pSourceSink)
{
m_pSourceSink->OnFileHeader(retVal, NULL);
m_lLastError = retVal;
}
return retVal;
}
STDMETHODIMP CVideoSourceDepacketizer::OnStreamHeader( HX_RESULT status, IHXValues* pValues)
{
MLOG_TRACE("%lu CVideoSourceDepacketizer::OnStreamHeader(0x%08x,0x%08x)\n",
HX_GET_BETTERTICKCOUNT(), status, pValues);
HX_RESULT retVal = HXR_FAIL;
@@ -278,60 +257,65 @@
HX_RELEASE(m_pStreamHeaderIn);
m_pStreamHeaderIn = pValues;
m_pStreamHeaderIn->AddRef();
// Check our options. We check them again
// here (we also did in InitSourceHandler() and
// OnFileHeader()) in case another object is also
// holding a ref on the options and has changed them
// since we were initialized,
m_bProcessHeadersOnly = GetBOOLOption("ProcessHeadersOnly", m_bProcessHeadersOnly);
m_bMaxSpeed = GetBOOLOption("MaxSpeed", m_bMaxSpeed);
m_bSetSrcProperties = GetBOOLOption("SetSrcProperties", m_bSetSrcProperties);
m_ulStartTime = GetULONG32Option("StartTime", m_ulStartTime);
// Load the depacker
HX_RELEASE(m_pDepacker);
retVal = LoadDepackerForStreamHeader(m_pStreamHeaderIn, m_pDepacker);
if (SUCCEEDED(retVal))
{
// Init the depacker
retVal = InitDepacker(m_pDepacker, m_pStreamHeaderIn);
// Get output stream header from depacker
if (SUCCEEDED(retVal))
{
HX_RELEASE(m_pStreamHeaderOut);
retVal = CreateValuesCCF(m_pStreamHeaderOut, m_pContext);
}
if (SUCCEEDED(retVal))
{
retVal = m_pDepacker->GetStreamHeader(m_pStreamHeaderOut);
}
+ if (SUCCEEDED(retVal))
+ {
+ // Transfer metadata if present
+ MetaInfo::CopyAllProperties(m_pStreamHeaderOut, m_pStreamHeaderIn, METAINFO_SET_ALL, FALSE);
+ }
if (SUCCEEDED(retVal) && m_pSourceSink)
{
m_pSourceSink->OnStreamHeader(HXR_OK, m_pStreamHeaderOut);
}
}
}
if (FAILED(retVal) && m_pSourceSink)
{
m_pSourceSink->OnTermination(retVal);
m_lLastError = retVal;
}
return retVal;
}
STDMETHODIMP CVideoSourceDepacketizer::OnStreamDone( HX_RESULT status, UINT16 unStreamNumber )
{
HX_RESULT retVal = HXR_OK;
if (FAILED(status) || FAILED(m_lLastError))
{
retVal = HXR_FAIL;
}
if (m_pSourceSink)
{
retVal = m_pSourceSink->OnStreamDone(retVal, unStreamNumber);
}
return retVal;
}
datatype_tools_dtdriver_engine.diff
(text/x-patch, 25.8 KB)
Index: Umakefil
===================================================================
RCS file: /cvsroot/datatype/tools/dtdriver/engine/Umakefil,v
retrieving revision 1.26
diff -d -H -b -B -w -U30 -r1.26 Umakefil
--- Umakefil 16 Apr 2009 20:18:22 -0000 1.26
+++ Umakefil 19 Oct 2009 12:59:20 -0000
@@ -16,60 +16,62 @@
# applicable to this file, the RCSL. Please see the applicable RPSL or
# RCSL for the rights, obligations and limitations governing use of the
# contents of the file.
#
# This file is part of the Helix DNA Technology. RealNetworks is the
# developer of the Original Code and owns the copyrights in the portions
# it created.
#
# This file, and the files included with this file, is distributed and made
# available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
# EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
#
# Technology Compatibility Kit Test Suite(s) Location:
# http://www.helixcommunity.org/content/tck
#
# Contributor(s):
#
# ***** END LICENSE BLOCK *****
#
UmakefileVersion(2,0)
project.AddModuleIncludes("common/include",
"client/include",
"datatype/include",
"datatype/rm/include",
"common/log/logutil/pub",
"common/log/logobserverfile/pub",
+ "datatype/include",
+ "datatype/common/util/pub",
"datatype/common/filewriter/pub",
"video/include")
project.AddIncludes("../common/pub",
"../decoder/common/pub",
"../encoder/common/pub",
"../include",
"../../minicntx/pub")
project.AddModuleIncludes("common/runtime/pub",
"common/dbgtool/pub",
"common/util/pub",
"client/common/container/pub",
"common/container/pub",
"common/system/pub")
project.AddSources("ffdriver.cpp",
"csrchdlrstackfact.cpp",
"csrchdlr.cpp",
"callbackq.cpp",
"csrctrpt.cpp",
"csrcsplt.cpp",
"csrcsynchdlr.cpp",
"merge_sort_src_handler.cpp")
if project.IsDefined("HELIX_FEATURE_DTDR_MUXER"):
project.AddSources("cmuxsrchandler.cpp")
if project.IsDefined("HELIX_FEATURE_DTDR_MULTIWRITER"):
project.AddSources("cmultifwriter.cpp")
Index: ffdriver.cpp
===================================================================
RCS file: /cvsroot/datatype/tools/dtdriver/engine/ffdriver.cpp,v
retrieving revision 1.60
diff -d -H -b -B -w -U30 -r1.60 ffdriver.cpp
--- ffdriver.cpp 2 Oct 2009 12:45:21 -0000 1.60
+++ ffdriver.cpp 19 Oct 2009 12:59:26 -0000
@@ -119,60 +119,61 @@
#define CHAR_CR_INDICATOR "<CR>"
#define CHAR_LF_INDICATOR "<LF>"
#define DEFAULT_RATEMODE_INTERVAL 10000
#define DTDR_INVALID_TS 0xFFFFFFFF
#define DTDR_INVALID_STRM 0xFFFF
#define DTDR_MAX_TS_DIFF 0x00FFFFFF
/****************************************************************************
* Includes
*/
#include "hlxclib/stdio.h"
#include "hlxclib/stdarg.h"
#include "hlxclib/string.h"
#include "hlxclib/ctype.h"
#include "ffdriver.h"
#include "hxstrutl.h"
#include "hxtick.h"
#include "hxplugn.h"
#include "hxccf.h"
#include "hxasm.h"
#include "hxver.h"
#include "hxsmutil.h"
#include "hxvalues.h"
#include "reporterror.h"
+#include "metautil.h"
#include "chxpckts.h"
#include "pckunpck.h"
#include "csrchdlr.h"
#include "csrchdlrstackfact.h"
#include "stream_desc_hlpr.h"
#include "cmultifwriter.h"
#define HELIX_FEATURE_LOGLEVEL_NONE // uncomment to disable all logging in this file
#include "hxtlogutil.h"
#include "hxloghelper.h"
#include "metainfokeys.h"
#include "proptools.h"
//#include "ciddefs.h"
/****************************************************************************
* Locals
*/
// WARNING! This Array must be kept aligned with MemoryProbeCategories enum
static const char* const m_MemCategoryNameArray[] =
{
"+-------Context Create & Init",
"| File Sys.Create",
"| +-------------File Sys.Init",
"| | +--File Obj.Create & Init",
"| | | +-------File Fmt.Create",
"| | | | File Wrtr.Create",
@@ -253,60 +254,61 @@
, m_ulBwThresholdsSize(0)
, m_ulNumBwThresholds(0)
, m_lBwThresholdIdx(0)
, m_ulCurrentBw(0)
, m_ulLastThreasholdEventTime(0)
, m_state(State_Initializing)
, m_status(HXR_OK)
, m_pInputFileName(NULL)
, m_pInputURL(NULL)
, m_pWriteFileName(NULL)
, m_pTempDirName(NULL)
, m_pInputFileProtocol(NULL)
, m_pInputFileSysShortName(NULL)
, m_uOptionFlags(DFLT_OPTIONS)
, m_bUseNuggetFormat(FALSE)
, m_uBandwidth(0)
, m_ulRateMode(RATE_MODE_CONSTANT)
, m_ulRateModeInterval(0)
, m_ulMinBwThreshold(0)
, m_ulMaxBwThreshold(0)
, m_ulStartTime(0)
, m_ulProcessUntil(0)
, m_ulProcessTimeUnits(0)
, m_bBandwidthExplicitlySet(FALSE)
, m_bStartTimeExplicitlySet(FALSE)
, m_bParseSDP(FALSE)
, m_uServerMode(0)
, m_ulContextEvents(0)
, m_lTimerValue(-1)
, m_ulRotationSize(0)
+ , m_ulMetaDataFlavor(0)
, m_bStop(FALSE)
, m_bSoftStop(FALSE)
, m_bPacketReady(FALSE)
, m_pMemProbeArray(NULL)
, m_ulGetPacketEvents(0)
, m_bPadToSize(FALSE)
, m_ulTargetSize(0)
, m_ulMediaSize(0)
, m_pLastWrittenPacket(NULL)
, m_pLastWrittenFileHeader(NULL)
, m_pDupPacketTrackerList(NULL)
#if defined (HELIX_CONFIG_USE_EXTERNAL_CONTEXT)
, m_bPersistentContext(TRUE)
#else
, m_bPersistentContext(FALSE)
#endif
, m_ulStartTS(DTDR_INVALID_TS)
, m_ulStartTick(0)
, m_ulProcessingRate(0) // 0 = as fast as possible
#ifdef HELIX_FEATURE_DTDR_USE_RECOGNIZER
, m_pFileRecognizer(NULL)
#endif
, m_bUseFileRecognition(FALSE)
, m_bLiveSource(FALSE)
, m_bTerminated(FALSE)
{
#ifdef _WRITER_WRITE_SIZE_TEST
m_bPadToSize = TRUE;
m_ulTargetSize = WRITER_WRITE_SIZE_TEST_GOAL;
#endif // _WRITER_WRITE_SIZE_TEST
@@ -649,60 +651,64 @@
m_lTimerValue = (LONG32) uOptValue;
}
else if (strcmp(pOptName, JUMPSTART_OPTION_NAME) == 0)
{
m_ulStartTime = uOptValue;
m_bStartTimeExplicitlySet = TRUE;
}
else if (strcmp(pOptName, PROCESSUNTIL_OPTION_NAME) == 0)
{
m_ulProcessUntil = uOptValue;
}
else if (strcmp(pOptName, PROCESSTIMEUNITS_OPTION_NAME) == 0)
{
m_ulProcessTimeUnits = uOptValue;
}
else if (strcmp(pOptName, ROTATIONSIZE_OPTION_NAME) == 0)
{
m_ulRotationSize = uOptValue;
}
else if (strcmp(pOptName, PROCESSHEADERS_OPTION_NAME) == 0)
{
if (m_lTimerValue < 0)
{
m_lTimerValue = 0;
}
}
else if (strcmp(pOptName, FILERECOGNITION_OPTION_NAME) == 0 && uOptValue)
{
m_bUseFileRecognition = TRUE;
}
+ else if (strcmp(pOptName, METADATAFLAVOR_OPTION_NAME) == 0)
+ {
+ m_ulMetaDataFlavor = uOptValue;
+ }
}
Status = pOptions->GetNextPropertyULONG32(pOptName, uOptValue);
}
}
// If we are to process packets for 0 amount of time and
// PROCESSHEADERS_OPTION_NAME is not explicitly set, assume
// PROCESSHEADERS_OPTION_NAME is needed.
if ((m_lTimerValue == 0) && m_pOptions)
{
ULONG32 ulVal = 0;
if (FAILED(m_pOptions->GetPropertyULONG32(
PROCESSHEADERS_OPTION_NAME,
ulVal)))
{
m_pOptions->SetPropertyULONG32(
PROCESSHEADERS_OPTION_NAME,
1);
}
}
if (MEMORY_TRACKING_NEEDED)
{
m_pMemProbeArray = new CHXMemProbe [MEMPRB_MAX];
}
if (SUCCEEDED(RetVal) &&
(m_ulRateMode != RATE_MODE_CONSTANT))
{
m_ulBwThresholdsSize = 0;
@@ -2026,60 +2032,69 @@
retVal = pNewProps->SetPropertyULONG32("TrustGivenMediaProperties", 0);
}
}
if (SUCCEEDED(retVal))
{
if (m_uOptionFlags & PREROLL_OPTION)
{
retVal = pNewProps->SetPropertyULONG32("RecomputePreroll", 1);
}
}
if (SUCCEEDED(retVal))
{
if (m_uOptionFlags & BLASTFILE_OPTION)
{
retVal = pNewProps->SetPropertyULONG32("BlastFiles", 1);
}
}
if (SUCCEEDED(retVal))
{
if (m_uOptionFlags & UTF16OUTPUT_OPTION)
{
retVal = pNewProps->SetPropertyULONG32("UTF16Output", 1);
}
}
if (SUCCEEDED(retVal))
{
+ if (m_ulMetaDataFlavor != 0)
+ {
+ retVal = pNewProps->SetPropertyULONG32("MetaDataFlavor",
+ m_ulMetaDataFlavor);
+ }
+ }
+
+ if (SUCCEEDED(retVal))
+ {
if (m_uOptionFlags & RELATIVETS_OPTION)
{
retVal = pNewProps->SetPropertyULONG32("UseRelativeTS", 1);
}
}
if (SUCCEEDED(retVal))
{
if (m_ulRotationSize != 0)
{
retVal = pNewProps->SetPropertyULONG32("RotationSize",
m_ulRotationSize);
}
}
if (SUCCEEDED(retVal))
{
if (m_bBandwidthExplicitlySet ||
(m_uBandwidth != 0) ||
(m_ulRateMode != RATE_MODE_CONSTANT))
{
retVal = pNewProps->SetPropertyULONG32("ForceIntoSingleRate", 1);
}
}
if (SUCCEEDED(retVal))
{
ULONG32 ulUseTempFiles = 0;
if (SUCCEEDED(m_pOptions->GetPropertyULONG32(USETEMPFILES_OPTION_NAME, ulUseTempFiles)))
{
@@ -3977,186 +3992,65 @@
status = m_pFileWriter->SetFileHeader(pHeader);
HX_RELEASE(m_pLastWrittenFileHeader);
m_pLastWrittenFileHeader = pHeader;
pHeader->AddRef();
}
}
if (m_uProcessedStreamsCount == 0)
{
if (m_pSourceHandlerStack)
{
m_pSourceHandlerStack->OnTermination(HXR_CLOSED);
}
}
if (SUCCEEDED(m_status))
{
m_status = status;
}
return status;
}
HX_RESULT FFDriver::ApplyFileHeaderModifications(IHXValues* pHeader)
{
HX_RESULT retVal = HXR_INVALID_PARAMETER;
if (pHeader)
{
- IHXBuffer* pBuffValue = NULL;
- HX_RESULT status = HXR_OK;
- retVal = HXR_OK;
-
- // Check for Title/Author/Copyright
- if (SUCCEEDED(m_pOptions->GetPropertyBuffer(TITLE_OPTION_NAME, pBuffValue)))
- {
- status = pHeader->SetPropertyBuffer("Title", pBuffValue);
- if (SUCCEEDED(retVal))
- {
- retVal = status;
- }
- }
- HX_RELEASE(pBuffValue);
-
- if (SUCCEEDED(m_pOptions->GetPropertyBuffer(AUTHOR_OPTION_NAME, pBuffValue)))
- {
- status = pHeader->SetPropertyBuffer("Author", pBuffValue);
- if (SUCCEEDED(retVal))
- {
- retVal = status;
- }
- }
- HX_RELEASE(pBuffValue);
-
- if (SUCCEEDED(m_pOptions->GetPropertyBuffer(COPYRIGHT_OPTION_NAME, pBuffValue)))
- {
- status = pHeader->SetPropertyBuffer("Copyright", pBuffValue);
- if (SUCCEEDED(retVal))
- {
- retVal = status;
- }
- }
- HX_RELEASE(pBuffValue);
-
- // Check for Abstract/Keywords
- if (SUCCEEDED(m_pOptions->GetPropertyCString(ABSTRACT_OPTION_NAME, pBuffValue)))
- {
- status = pHeader->SetPropertyCString("Abstract", pBuffValue);
- if (SUCCEEDED(retVal))
- {
- retVal = status;
- }
- }
- HX_RELEASE(pBuffValue);
-
- if (SUCCEEDED(m_pOptions->GetPropertyCString(KEYWORDS_OPTION_NAME, pBuffValue)))
- {
- status = pHeader->SetPropertyCString("Keywords", pBuffValue);
- if (SUCCEEDED(retVal))
- {
- retVal = status;
- }
- }
- HX_RELEASE(pBuffValue);
-
- // 3GP meta-data
- Apply3GPFileHeaderModifications(retVal, pHeader);
+ retVal = MetaInfo::CopyAllProperties(pHeader, m_pOptions, METAINFO_SET_ALL, FALSE);
}
-
return retVal;
}
-void FFDriver::Apply3GPFileHeaderModifications(HX_RESULT& retVal, IHXValues* pHeader)
-{
-#if defined(HELIX_FEATURE_3GPP_METAINFO) || defined(HELIX_FEATURE_SERVER)
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, _3GPP_META_INFO_GLOBAL_LANGUAGE_ENCODING_KEY, FALSE);
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, _3GPP_META_INFO_TITLE_KEY, FALSE);
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, _3GPP_META_INFO_AUTHOR_KEY, FALSE);
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, _3GPP_META_INFO_COPYRIGHT_KEY, FALSE);
-#ifdef HELIX_FEATURE_3GPP_METAINFO
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, _3GPP_META_INFO_DESCRIPTION_KEY, FALSE);
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, _3GPP_META_INFO_PERFORMER_KEY, FALSE);
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, _3GPP_META_INFO_GENRE_KEY, FALSE);
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, _3GPP_META_INFO_RATING_ENTITY_KEY, FALSE);
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, _3GPP_META_INFO_RATING_CRITERIA_KEY, FALSE);
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, _3GPP_META_INFO_RATING_INFO_KEY, FALSE);
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, _3GPP_META_INFO_CLASSIFICATION_ENTITY_KEY, FALSE);
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, _3GPP_META_INFO_CLASSIFICATION_INFO_KEY, FALSE);
- PropTools::CopyPropertyULONG32(retVal, pHeader, m_pOptions, _3GPP_META_INFO_CLASSIFICATION_TABLE_KEY, FALSE);
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, _3GPP_META_INFO_LOCATION_NAME_KEY, FALSE);
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, _3GPP_META_INFO_LOCATION_ASTRONOMICAL_BODY_KEY, FALSE);
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, _3GPP_META_INFO_LOCATION_ADDITIONAL_NOTES_KEY, FALSE);
- PropTools::CopyPropertyULONG32(retVal, pHeader, m_pOptions, _3GPP_META_INFO_LOCATION_ROLE_KEY, FALSE);
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, _3GPP_META_INFO_LOCATION_LONGITUDE_KEY, FALSE);
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, _3GPP_META_INFO_LOCATION_LATITUDE_KEY, FALSE);
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, _3GPP_META_INFO_LOCATION_ALTITUDE_KEY, FALSE);
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, _3GPP_META_INFO_ALBUM_TITLE_KEY, FALSE);
- PropTools::CopyPropertyULONG32(retVal, pHeader, m_pOptions, _3GPP_META_INFO_TRACK_NUMBER_KEY, FALSE);
- PropTools::CopyPropertyULONG32(retVal, pHeader, m_pOptions, _3GPP_META_INFO_RECORDING_YEAR_KEY, FALSE);
-
- // keywords
- ULONG32 ulNewKeywordCount = 0;
- PropTools::CopyPropertyULONG32(ulNewKeywordCount, m_pOptions, _3GPP_META_INFO_KEYWORD_COUNT_KEY);
-
- if(ulNewKeywordCount)
- {
- // remove old keywords
- ULONG32 ulOldKeywordCount = 0;
- PropTools::CopyPropertyULONG32(ulOldKeywordCount, pHeader, _3GPP_META_INFO_KEYWORD_COUNT_KEY);
- PropTools::RemovePropertyULONG32(pHeader, _3GPP_META_INFO_KEYWORD_COUNT_KEY);
-
- for(ULONG32 i = 0; i < ulOldKeywordCount; i++)
- {
- char key[128];
- sprintf(key, _3GPP_META_INFO_KEYWORD_KEY, int(i));
- PropTools::RemovePropertyBuffer(pHeader, key);
- }
-
- // add new keywords
- PropTools::CopyPropertyULONG32(pHeader, TRUE, ulNewKeywordCount, _3GPP_META_INFO_KEYWORD_COUNT_KEY, TRUE);
-
- for(ULONG32 i = 0; i < ulNewKeywordCount; i++)
- {
- char key[128];
- sprintf(key, _3GPP_META_INFO_KEYWORD_KEY, int(i));
- if(SUCCEEDED(retVal))
- {
- PropTools::CopyPropertyBuffer(retVal, pHeader, m_pOptions, key, TRUE);
- }
- }
- }
-#endif // HELIX_FEATURE_3GPP_METAINFO
-#endif // HELIX_FEATURE_3GPP_METAINFO || HELIX_FEATURE_SERVER
-}
-
STDMETHODIMP FFDriver::StreamHeaderReady(HX_RESULT status, IHXValues* pHeader)
{
HXLOGL3(HXLOG_DTDR, "FFDriver::StreamHeaderReady(status=0x%08x,pHeader=%p)", status, pHeader);
UINT32 ulStreamNumber = 0;
if (pHeader)
{
pHeader->GetPropertyULONG32("StreamNumber", ulStreamNumber);
}
HXLOGL3(HXLOG_DTDR, "FFDriver::StreamHeaderReady(status=0x%08x,) strm=%lu", status, ulStreamNumber);
HX_RESULT retVal = HXR_OK;
++m_uStreamHeaders;
if (SUCCEEDED(status) && (m_uStreamHeaders <= m_uStreamCount))
{
// First Source header is reserved for file header.
// Subsequent entries contain stream headers,
HX_RELEASE(m_pSourceHeaders[m_uStreamHeaders]);
if (pHeader)
{
m_pSourceHeaders[m_uStreamHeaders] = pHeader;
pHeader->AddRef();
}
}
if (SUCCEEDED(status))
{
if (m_bParseSDP)
{
HX_RESULT sdpParseStatus;
Index: pub/ffdriver.h
===================================================================
RCS file: /cvsroot/datatype/tools/dtdriver/engine/pub/ffdriver.h,v
retrieving revision 1.44
diff -d -H -b -B -w -U30 -r1.44 ffdriver.h
--- pub/ffdriver.h 2 Oct 2009 12:45:22 -0000 1.44
+++ pub/ffdriver.h 19 Oct 2009 12:59:26 -0000
@@ -50,60 +50,61 @@
#define LOCALACCESSONLY_OPTION_NAME "LocalAccessOnly"
#define RATE_OPTION_NAME "Rate"
#define RATEMODE_OPTION_NAME "RateMode"
#define RATEMAX_OPTION_NAME "RateMax"
#define RATEMIN_OPTION_NAME "RateMin"
#define PACE_OPTION_NAME "Pace"
#define RATEMODEINTERVAL_OPTION_NAME "RateModeInterval"
#define TIMER_OPTION_NAME "Timer"
#define PASSSWOFFPKTS_OPTION_NAME "PassSwitchOffPackets"
#define USETEMPFILES_OPTION_NAME "UseTempFiles"
#define USENUGGETFORMAT_OPTION_NAME "UseNuggetFormat"
#define NUGGETEXPIRATION_OPTION_NAME "NuggetExpiration"
#define NUGGETCONNECTTIME_OPTION_NAME "NuggetConnectTime"
#define NUGGETREMOTESOURCEURL_OPTION_NAME "NuggetRemoteSourceURL"
#define QUIET_OPTION_NAME "Quiet"
#define JUMPSTART_OPTION_NAME "StartTime"
#define PROCESSUNTIL_OPTION_NAME "ProcessUntil"
#define PROCESSTIMEUNITS_OPTION_NAME "ProcessTimeUnits"
#define PROCESSDECODEDTIMEUNITS_OPTION_NAME "ProcessDecodedTimeUnits"
#define TIMING_OPTION_NAME "Timing"
#define EVENT_OPTION_NAME "Event"
#define DURATION_OPTION_NAME "Duration"
#define TITLE_OPTION_NAME "Title"
#define AUTHOR_OPTION_NAME "Author"
#define COPYRIGHT_OPTION_NAME "Copyright"
#define ABSTRACT_OPTION_NAME "Abstract"
#define KEYWORDS_OPTION_NAME "Keywords"
#define PREROLL_OPTION_NAME "RecomputePreroll"
#define BLASTFILE_OPTION_NAME "BlastFiles"
#define UTF16OUTPUT_OPTION_NAME "UTF16Output"
+#define METADATAFLAVOR_OPTION_NAME "MetaDataFlavor"
#define SYNCHRONOUS_OPTION_NAME "Synchronous"
#define RECORDASLIVE_OPTION_NAME "RecordAsLive"
#define ROTATIONSIZE_OPTION_NAME "RotationSize"
#define VIDEOOFFSET_OPTION_NAME "VideoTimeOffset"
#define SOURCEOFFSET_OPTION_NAME "SourceTimeOffset"
#define VIDEOTIMESCALE_OPTION_NAME "VideoTimeScale"
#define KEYFRAMESONLY_OPTION_NAME "KeyFramesOnly"
#define MAXFRAMERATE_OPTION_NAME "MaxFrameRate"
#define MINFRAMERATE_OPTION_NAME "MinFrameRate"
#define LOOKAHEAD_OPTION_NAME "LookAhead"
#define RELATIVETS_OPTION_NAME "RelativeTS"
#define DECRYPT_OPTION_NAME "DecryptSource"
#define DECODE_OPTION_NAME "DecodeSource"
#define DECODEAUDIO_OPTION_NAME "DecodeAudio"
#define DECODEVIDEO_OPTION_NAME "DecodeVideo"
#define DECODENONAV_OPTION_NAME "DecodeNonAV"
#define DECODESTREAM_OPTION_NAME "DecodeStream"
#define DECODESTREAMMODE_OPTION_NAME "DecodeStreamMode"
#define OUTPUTSAMPLESPERSECOND_OPTION_NAME "OutputSamplesPerSecond"
#define OUTPUTCHANNELS_OPTION_NAME "OutputChannels"
#define OUTPUTBITSPERSAMPLE_OPTION_NAME "OutputBitsPerSample"
#define MINOUTPUTBITSPERSAMPLE_OPTION_NAME "MinOutputBitsPerSample"
#define MAXOUTPUTBITSPERSAMPLE_OPTION_NAME "MaxOutputBitsPerSample"
#define ENCODE_OPTION_NAME "EncodeSource"
#define ENCODEAUDIO_OPTION_NAME "EncodeAudioFormat"
#define ENCODEVIDEO_OPTION_NAME "EncodeVideoFormat"
#define ENCODEAUDIORATE_OPTION_NAME "EncodeAudioRate"
#define ENCODEAUDIORATETOL_OPTION_NAME "EncodeAudioRateTol"
#define ENCODEAUDIORATEMAX_OPTION_NAME "EncodeAudioRateMax"
#define ENCODEAUDIORATECOMPFMTS_OPTION_NAME "EncodeAudioCompFormats"
@@ -498,61 +499,60 @@
State_InitFileFormatDone,
State_InitFileWriter,
State_GetFileHeader,
State_FileHeaderDonePending,
State_TryAnotherFormat,
State_FileHeaderDone,
State_InitGetPacketEngine,
State_GetStreamHeaders,
State_StreamHeadersDonePending,
State_StreamHeadersDone,
State_Seek,
State_SeekDonePending,
State_SeekDone,
State_PacketsReadyPending,
State_StartPackets,
State_GetPackets,
State_PacketsDone,
State_CleanUpReadyPending,
State_CleanUp,
State_RunReport,
State_EndFile,
State_DriveDone
};
HX_RESULT BuildStubFileHeader(IHXValues* &pHeader, UINT16 uStreamCount = 1);
HX_RESULT BuildStubStreamHeader(UINT16 uStream, IHXValues* &pHeader);
HX_RESULT InternalizeSource(char *pInputFileName);
HX_RESULT InternalizeSourceHandlerList(IHXSourceHandler** pSourceHandlerList);
HX_RESULT ApplyFileHeaderModifications(IHXValues* pHeader);
- void Apply3GPFileHeaderModifications(HX_RESULT& retVal, IHXValues* pHeader);
HX_RESULT CreateWriterProps(IHXValues* &pWriterProps);
HX_RESULT InitGetPacketEngine(UINT16 uStreamCount);
HX_RESULT ConfigureDecodePosition(void);
void CloseGetPacketEngine(HXBOOL bRetainContainer = FALSE);
void CloseSourceHeaders(HXBOOL bRetainContainer = FALSE);
HX_RESULT _FileHeaderReady(HX_RESULT status, IHXValues* pHeader);
HX_RESULT _StreamHeaderReady(HX_RESULT status, IHXValues* pHeader);
HX_RESULT _PacketReady(HX_RESULT status, IHXPacket* pPacket);
HX_RESULT StreamDone(HX_RESULT status, UINT16 uStreamNumber);
HX_RESULT _StreamDone(HX_RESULT status, UINT16 uStreamNumber);
HXBOOL IsMemSpanArrayMember(MemoryProbeCategory MemProbeId);
HX_RESULT EstablishBwThresholds(void);
HX_RESULT ProcessBwControl(IHXPacket* pPacket);
HX_RESULT Subscribe(HXBOOL bSubscribe = TRUE);
HX_RESULT SubscribeBandwidth(UINT32 ulBandwidth, HXBOOL bSubcribe = TRUE);
HX_RESULT SubscribeAll(HXBOOL bSubscribe = TRUE);
HX_RESULT SubscribeAllInStream(IHXValues* pHeader, HXBOOL bSubscribe = TRUE);
HX_RESULT StartPackets(void);
HX_RESULT SelectNextStream(void);
HX_RESULT GetNextPacket(UINT16 uStream, UINT32 ulDelay = 0);
#ifndef HELIX_CONFIG_DTDR_DISABLE_LOGGING
void ReportError(HX_RESULT errVal, const char *format, ...);
@@ -623,60 +623,61 @@
INT32 m_lBwThresholdIdx;
INT32 m_lNextBwThresholdIdx;
UINT32 m_ulCurrentBw;
UINT32 m_ulLastThreasholdEventTime;
ProcState m_state;
HX_RESULT m_status;
char* m_pInputFileName;
char* m_pInputURL;
char* m_pWriteFileName;
char* m_pTempDirName;
char* m_pInputFileProtocol;
char* m_pInputFileSysShortName;
ULONG32 m_uOptionFlags;
ULONG32 m_uBandwidth;
ULONG32 m_ulRateMode;
ULONG32 m_ulRateModeInterval;
ULONG32 m_ulMinBwThreshold;
ULONG32 m_ulMaxBwThreshold;
ULONG32 m_ulStartTime;
ULONG32 m_ulProcessUntil;
ULONG32 m_ulProcessTimeUnits;
HXBOOL m_bUseNuggetFormat;
HXBOOL m_bBandwidthExplicitlySet;
HXBOOL m_bStartTimeExplicitlySet;
HXBOOL m_bParseSDP;
ULONG32 m_uServerMode;
ULONG32 m_ulContextEvents;
ULONG32 m_ulGetPacketEvents;
LONG32 m_lTimerValue;
ULONG32 m_ulRotationSize;
+ ULONG32 m_ulMetaDataFlavor;
HXBOOL m_bStop;
HXBOOL m_bSoftStop;
HXBOOL m_bAwaitingFirstNonLostPacket;
HXBOOL m_bPacketReady;
HXBOOL m_bPadToSize;
ULONG32 m_ulTargetSize;
ULONG32 m_ulMediaSize;
IHXPacket* m_pLastWrittenPacket;
IHXValues* m_pLastWrittenFileHeader;
IHXPacket** m_pDupPacketTrackerList;
HXBOOL m_bPersistentContext;
UINT32 m_ulStartTS;
UINT32 m_ulStartTick;
UINT32 m_ulProcessingRate;
HXBOOL m_bLiveSource;
HXBOOL m_bTerminated;
CHXMemProbe *m_pMemProbeArray;
#ifdef HELIX_FEATURE_DTDR_USE_RECOGNIZER
public:
STDMETHOD(GetMimeTypeDone)(THIS_ HX_RESULT status, IHXBuffer* pMimeType);
private:
IHXFileRecognizer* m_pFileRecognizer;
CHXString m_strMimeType;
#endif
HXBOOL m_bUseFileRecognition;
datatype_tools_metaeditor.diff
(text/x-patch, 61.6 KB)
Index: Umakefil
===================================================================
RCS file: /cvsroot/datatype/tools/metaeditor/Umakefil,v
retrieving revision 1.1
diff -d -H -b -B -w -U30 -r1.1 Umakefil
--- Umakefil 5 Nov 2007 22:29:46 -0000 1.1
+++ Umakefil 19 Oct 2009 13:04:53 -0000
@@ -1,54 +1,89 @@
#
# ***** BEGIN LICENSE BLOCK *****
-# Source last modified: $Id: Umakefil,v 1.1 2007/11/05 22:29:46 pbasic Exp $
+# Source last modified: $Id: Umakefil_dll,v 1.2 2007/11/06 11:15:54 pbasic Exp $
#
# Portions Copyright (c) 1995-2007 RealNetworks, Inc. All Rights Reserved.
#
# The contents of this file, and the files included with this file,
# are subject to the current version of the RealNetworks Public
# Source License (the "RPSL") available at
# http://www.helixcommunity.org/content/rpsl unless you have licensed
# the file under the current version of the RealNetworks Community
# Source License (the "RCSL") available at
# http://www.helixcommunity.org/content/rcsl, in which case the RCSL
# will apply. You may also obtain the license terms directly from
# RealNetworks. You may not use this file except in compliance with
# the RPSL or, if you have a valid RCSL with RealNetworks applicable
# to this file, the RCSL. Please see the applicable RPSL or RCSL for
# the rights, obligations and limitations governing use of the
# contents of the file.
#
# Alternatively, the contents of this file may be used under the
# terms of the GNU General Public License Version 2 (the
# "GPL") in which case the provisions of the GPL are applicable
# instead of those above. If you wish to allow use of your version of
# this file only under the terms of the GPL, and not to allow others
# to use your version of this file under the terms of either the RPSL
# or RCSL, indicate your decision by deleting the provisions above
# and replace them with the notice and other provisions required by
# the GPL. 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
# RPSL, the RCSL or the GPL.
#
# This file is part of the Helix DNA Technology. RealNetworks is the
# developer of the Original Code and owns the copyrights in the
# portions it created.
#
# This file, and the files included with this file, is distributed
# and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
# KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
# ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
# ENJOYMENT OR NON-INFRINGEMENT.
#
# Technology Compatibility Kit Test Suite(s) Location:
# http://www.helixcommunity.org/content/tck
#
# Contributor(s):
#
# ***** END LICENSE BLOCK *****
#
UmakefileVersion(2,2)
-MultiTargetMake("Umakefil_3gp_lib", "Umakefil_dll")
+project.AddModuleIncludes("common/include",
+ "datatype/tools/dtdriver/engine/pub",
+ "datatype/tools/minicntx/pub",
+ "common/system/pub",
+ "common/container/pub",
+ "common/dbgtool/pub",
+ "common/util/pub",
+ "common/fileio/pub",
+ "datatype/include",
+ "datatype/common/util/pub",
+ "client/common/system/pub",
+ "client/core",
+ "client/core/pub")
+
+project.AddModuleLibraries( "client/common/container[contclntlib]",
+ "client/common/system[sysclntlib]",
+ "client/common/util[utlclntlib]",
+ "common/runtime[runtlib]",
+ "common/dbgtool[debuglib]",
+ "common/util[utillib]",
+ "common/container[contlib]",
+ "common/system[syslib]",
+ "common/fileio[fileiolib]",
+ "common/log/logutil[logutillib]",
+ "datatype/common/util[dtutillib]")
+
+project.AddSources('srchandler.cpp',
+ 'editor.cpp',
+ 'hxdll.cpp',
+ 'dlliids.cpp')
+
+project.ExportFunction("RMACreateInstance", "IUnknown** ppObj", "common/include", "hxcom.h")
+project.ExportFunction("CanUnload2", "void")
+
+DLLTarget('metaeditor')
+DependTarget()
Index: Umakefil_3gp_lib
===================================================================
RCS file: Umakefil_3gp_lib
diff -N Umakefil_3gp_lib
--- Umakefil_3gp_lib 6 Nov 2007 11:15:54 -0000 1.2
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,57 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# Version: RCSL 1.0/RPSL 1.0
-#
-# Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
-#
-# The contents of this file, and the files included with this file, are
-# subject to the current version of the RealNetworks Public Source License
-# Version 1.0 (the "RPSL") available at
-# http://www.helixcommunity.org/content/rpsl unless you have licensed
-# the file under the RealNetworks Community Source License Version 1.0
-# (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
-# in which case the RCSL will apply. You may also obtain the license terms
-# directly from RealNetworks. You may not use this file except in
-# compliance with the RPSL or, if you have a valid RCSL with RealNetworks
-# applicable to this file, the RCSL. Please see the applicable RPSL or
-# RCSL for the rights, obligations and limitations governing use of the
-# contents of the file.
-#
-# This file is part of the Helix DNA Technology. RealNetworks is the
-# developer of the Original Code and owns the copyrights in the portions
-# it created.
-#
-# This file, and the files included with this file, is distributed and made
-# available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
-# EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
-# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
-# FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
-#
-# Technology Compatibility Kit Test Suite(s) Location:
-# http://www.helixcommunity.org/content/tck
-#
-# Contributor(s):
-#
-# ***** END LICENSE BLOCK *****
-#
-
-UmakefileVersion(2,0)
-
-project.AddModuleIncludes("common/include",
- "datatype/include")
-
-project.AddModuleLibraries( "client/common/container[contclntlib]",
- "client/common/system[sysclntlib]",
- "client/common/util[utlclntlib]",
- "common/runtime[runtlib]",
- "common/dbgtool[debuglib]",
- "common/util[utillib]",
- "common/container[contlib]",
- "common/system[syslib]",
- "common/log/logutil[logutillib]")
-
-project.AddSources("metautil3gp.cpp")
-
-LibraryTarget("metautil3gplib")
-
-DependTarget()
Index: Umakefil_dll
===================================================================
RCS file: Umakefil_dll
diff -N Umakefil_dll
--- Umakefil_dll 6 Nov 2007 11:15:54 -0000 1.2
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,89 +0,0 @@
-#
-# ***** BEGIN LICENSE BLOCK *****
-# Source last modified: $Id: Umakefil_dll,v 1.2 2007/11/06 11:15:54 pbasic Exp $
-#
-# Portions Copyright (c) 1995-2007 RealNetworks, Inc. All Rights Reserved.
-#
-# The contents of this file, and the files included with this file,
-# are subject to the current version of the RealNetworks Public
-# Source License (the "RPSL") available at
-# http://www.helixcommunity.org/content/rpsl unless you have licensed
-# the file under the current version of the RealNetworks Community
-# Source License (the "RCSL") available at
-# http://www.helixcommunity.org/content/rcsl, in which case the RCSL
-# will apply. You may also obtain the license terms directly from
-# RealNetworks. You may not use this file except in compliance with
-# the RPSL or, if you have a valid RCSL with RealNetworks applicable
-# to this file, the RCSL. Please see the applicable RPSL or RCSL for
-# the rights, obligations and limitations governing use of the
-# contents of the file.
-#
-# Alternatively, the contents of this file may be used under the
-# terms of the GNU General Public License Version 2 (the
-# "GPL") in which case the provisions of the GPL are applicable
-# instead of those above. If you wish to allow use of your version of
-# this file only under the terms of the GPL, and not to allow others
-# to use your version of this file under the terms of either the RPSL
-# or RCSL, indicate your decision by deleting the provisions above
-# and replace them with the notice and other provisions required by
-# the GPL. 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
-# RPSL, the RCSL or the GPL.
-#
-# This file is part of the Helix DNA Technology. RealNetworks is the
-# developer of the Original Code and owns the copyrights in the
-# portions it created.
-#
-# This file, and the files included with this file, is distributed
-# and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
-# KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
-# ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
-# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
-# ENJOYMENT OR NON-INFRINGEMENT.
-#
-# Technology Compatibility Kit Test Suite(s) Location:
-# http://www.helixcommunity.org/content/tck
-#
-# Contributor(s):
-#
-# ***** END LICENSE BLOCK *****
-#
-
-UmakefileVersion(2,2)
-
-project.AddModuleIncludes("common/include",
- "datatype/tools/dtdriver/engine/pub",
- "datatype/tools/minicntx/pub",
- "common/system/pub",
- "common/container/pub",
- "common/dbgtool/pub",
- "common/util/pub",
- "common/fileio/pub",
- "datatype/include",
- "client/common/system/pub",
- "client/core",
- "client/core/pub")
-
-project.AddModuleLibraries( "client/common/container[contclntlib]",
- "client/common/system[sysclntlib]",
- "client/common/util[utlclntlib]",
- "common/runtime[runtlib]",
- "common/dbgtool[debuglib]",
- "common/util[utillib]",
- "common/container[contlib]",
- "common/system[syslib]",
- "common/fileio[fileiolib]",
- "common/log/logutil[logutillib]")
-
-project.AddModuleLibraries("datatype/tools/metaeditor[metautil3gplib]")
-
-project.AddSources('srchandler.cpp',
- 'editor.cpp',
- 'hxdll.cpp',
- 'dlliids.cpp')
-
-project.ExportFunction("RMACreateInstance", "IUnknown** ppObj", "common/include", "hxcom.h")
-project.ExportFunction("CanUnload2", "void")
-
-DLLTarget('metaeditor')
-DependTarget()
Index: metautil3gp.cpp
===================================================================
RCS file: metautil3gp.cpp
diff -N metautil3gp.cpp
--- metautil3gp.cpp 5 Nov 2007 22:29:46 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,878 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: RCSL 1.0/RPSL 1.0
- *
- * Portions Copyright (c) 1995-2007 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file, are
- * subject to the current version of the RealNetworks Public Source License
- * Version 1.0 (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the RealNetworks Community Source License Version 1.0
- * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
- * in which case the RCSL will apply. You may also obtain the license terms
- * directly from RealNetworks. You may not use this file except in
- * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
- * applicable to this file, the RCSL. Please see the applicable RPSL or
- * RCSL for the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the portions
- * it created.
- *
- * This file, and the files included with this file, is distributed and made
- * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "hxsrcin.h"
-#include "hlxclib/time.h"
-#include "hxtypes.h"
-#include "hxmemprb.h"
-#include "hxtick.h"
-#include "chxpckts.h"
-#include "pckunpck.h"
-#include "metainfokeys.h"
-#include "iso639.h"
-#include "encstr.h"
-#include "proptools.h"
-
-#include "metautil3gp.h"
-
-
-HX_RESULT RemoveKeywordProperties_MetaInfo3GP(IHXValues* pValues)
-{
- HX_RESULT retVal = HXR_OK;
-
- UINT32 ulKeywordCount = 0;
- if(PropTools::CopyPropertyULONG32(ulKeywordCount, pValues, _3GPP_META_INFO_KEYWORD_COUNT_KEY))
- {
- PropTools::RemovePropertyULONG32(retVal, pValues, _3GPP_META_INFO_KEYWORD_COUNT_KEY);
-
- for(UINT32 i = 0; i < ulKeywordCount; i++)
- {
- char key[128];
- sprintf(key, _3GPP_META_INFO_KEYWORD_KEY, int(i));
- PropTools::RemovePropertyBuffer(retVal, pValues, key);
- }
- }
- return retVal;
-}
-
-HX_RESULT RemoveAllProperties_MetaInfo3GP(IHXValues* pValues)
-{
- HX_RESULT retVal = HXR_OK;
-
- PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_GLOBAL_LANGUAGE_ENCODING_KEY);
- PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_TITLE_KEY);
- PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_AUTHOR_KEY);
- PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_COPYRIGHT_KEY);
- PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_DESCRIPTION_KEY);
- PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_PERFORMER_KEY);
- PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_GENRE_KEY);
- PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_RATING_ENTITY_KEY);
- PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_RATING_CRITERIA_KEY);
- PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_RATING_INFO_KEY);
- PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_CLASSIFICATION_ENTITY_KEY);
- PropTools::RemovePropertyULONG32(retVal, pValues, _3GPP_META_INFO_CLASSIFICATION_TABLE_KEY);
- PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_CLASSIFICATION_INFO_KEY);
- PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_LOCATION_NAME_KEY);
- PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_LOCATION_ASTRONOMICAL_BODY_KEY);
- PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_LOCATION_ADDITIONAL_NOTES_KEY);
- PropTools::RemovePropertyULONG32(retVal, pValues, _3GPP_META_INFO_LOCATION_ROLE_KEY);
- PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_LOCATION_LONGITUDE_KEY);
- PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_LOCATION_LATITUDE_KEY);
- PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_LOCATION_ALTITUDE_KEY);
- PropTools::RemovePropertyBuffer(retVal, pValues, _3GPP_META_INFO_ALBUM_TITLE_KEY);
- PropTools::RemovePropertyULONG32(retVal, pValues, _3GPP_META_INFO_TRACK_NUMBER_KEY);
- PropTools::RemovePropertyULONG32(retVal, pValues, _3GPP_META_INFO_RECORDING_YEAR_KEY);
-
- if(SUCCEEDED(retVal))
- {
- retVal = RemoveKeywordProperties_MetaInfo3GP(pValues);
- }
- return retVal;
-}
-
-HX_RESULT CopyKeywordProperties_MetaInfo3GP(IHXValues* dst, IHXValues* src, BOOL bBlast)
-{
- HX_RESULT retVal = HXR_OK;
-
- UINT32 ulKeywordCount = 0;
- if(PropTools::CopyPropertyULONG32(ulKeywordCount, src, _3GPP_META_INFO_KEYWORD_COUNT_KEY))
- {
- retVal = RemoveKeywordProperties_MetaInfo3GP(dst);
-
- PropTools::CopyPropertyULONG32(retVal, dst, src, _3GPP_META_INFO_KEYWORD_COUNT_KEY, TRUE);
- for(UINT32 i = 0; i < ulKeywordCount; i++)
- {
- if(SUCCEEDED(retVal))
- {
- char key[128];
- sprintf(key, _3GPP_META_INFO_KEYWORD_KEY, int(i));
- PropTools::CopyPropertyBuffer(retVal, dst, src, key, TRUE);
- }
- }
- }
- else if(bBlast)
- {
- retVal = RemoveKeywordProperties_MetaInfo3GP(dst);
- }
- return retVal;
-}
-
-HX_RESULT CopyAllProperties_MetaInfo3GP(IHXValues* dst, IHXValues* src, BOOL bBlast)
-{
- HX_RESULT retVal = HXR_OK;
-
- PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_GLOBAL_LANGUAGE_ENCODING_KEY, bBlast);
- PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_TITLE_KEY, bBlast);
- PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_AUTHOR_KEY, bBlast);
- PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_COPYRIGHT_KEY, bBlast);
- PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_DESCRIPTION_KEY, bBlast);
- PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_PERFORMER_KEY, bBlast);
- PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_GENRE_KEY, bBlast);
- PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_RATING_ENTITY_KEY, bBlast);
- PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_RATING_CRITERIA_KEY, bBlast);
- PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_RATING_INFO_KEY, bBlast);
- PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_CLASSIFICATION_ENTITY_KEY, bBlast);
- PropTools::CopyPropertyULONG32(retVal, dst, src, _3GPP_META_INFO_CLASSIFICATION_TABLE_KEY, bBlast);
- PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_CLASSIFICATION_INFO_KEY, bBlast);
- PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_LOCATION_NAME_KEY, bBlast);
- PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_LOCATION_ASTRONOMICAL_BODY_KEY, bBlast);
- PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_LOCATION_ADDITIONAL_NOTES_KEY, bBlast);
- PropTools::CopyPropertyULONG32(retVal, dst, src, _3GPP_META_INFO_LOCATION_ROLE_KEY, bBlast);
- PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_LOCATION_LONGITUDE_KEY, bBlast);
- PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_LOCATION_LATITUDE_KEY, bBlast);
- PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_LOCATION_ALTITUDE_KEY, bBlast);
- PropTools::CopyPropertyBuffer(retVal, dst, src, _3GPP_META_INFO_ALBUM_TITLE_KEY, bBlast);
- PropTools::CopyPropertyULONG32(retVal, dst, src, _3GPP_META_INFO_TRACK_NUMBER_KEY, bBlast);
- PropTools::CopyPropertyULONG32(retVal, dst, src, _3GPP_META_INFO_RECORDING_YEAR_KEY, bBlast);
-
- if(SUCCEEDED(retVal))
- {
- retVal = CopyKeywordProperties_MetaInfo3GP(dst, src, bBlast);
- }
- return retVal;
-}
-
-MetaInfo3GP::MetaInfo3GP()
-{
- Clear();
-}
-
-MetaInfo3GP::~MetaInfo3GP()
-{
- ClearKeywords();
-}
-
-MetaInfo3GP::MetaInfo3GP(const MetaInfo3GP& rhs)
-{
- *this = rhs;
-}
-
-MetaInfo3GP& MetaInfo3GP::operator=(const MetaInfo3GP& rhs)
-{
- Clear();
- Update(rhs);
- return *this;
-}
-
-void MetaInfo3GP::Dump()
-{
- Dump("GlobalLanguageEncoding", m_sGlobalLanguageEncoding);
- Dump("Title", m_sTitle);
- Dump("Author", m_sAuthor);
- Dump("Copyright", m_sCopyright);
- Dump("Description", m_sDescription);
- Dump("Performer", m_sPerformer);
- Dump("Genre", m_sGenre);
- Dump("RatingEntity", m_sRatingEntity);
- Dump("RatingCriteria", m_sRatingCriteria);
- Dump("RatingInfo", m_sRatingInfo);
- Dump("ClassificationEntity", m_sClassificationEntity);
- Dump("ClassificationTable", m_uClassificationTable, m_bValidClassificationTable);
- Dump("ClassificationInfo", m_sClassificationInfo);
-
- for(UINT32 i = 0; i < GetKeywordCount(); i++)
- {
- printf("Keyword%d: ", int(i));
- EncodedString kwd;
- GetKeyword(i, kwd);
- kwd.Dump();
- printf("\n");
- }
- Dump("LocationName", m_sLocationName);
- Dump("LocationAstronomicalBody", m_sLocationAstronomicalBody);
- Dump("LocationAdditionalNotes", m_sLocationAdditionalNotes);
- Dump("LocationRole", m_uLocationRole, m_bValidLocationRole);
- Dump("LocationLongitude", m_sLocationLongitude);
- Dump("LocationLatitude", m_sLocationLatitude);
- Dump("LocationAltitude", m_sLocationAltitude);
- Dump("AlbumTitle", m_sAlbumTitle);
- Dump("AlbumTrackNumber", m_uAlbumTrackNumber, m_bValidAlbumTrackNumber);
- Dump("RecordingYear", m_uRecordingYear, m_bValidRecordingYear);
-}
-
-void MetaInfo3GP::Clear()
-{
- m_sGlobalLanguageEncoding.Clear();
- m_sTitle.Clear();
- m_sAuthor.Clear();
- m_sCopyright.Clear();
- m_sDescription.Clear();
- m_sPerformer.Clear();
- m_sGenre.Clear();
- m_sRatingEntity.Clear();
- m_sRatingCriteria.Clear();
- m_sRatingInfo.Clear();
- m_sClassificationEntity.Clear();
- m_bValidClassificationTable = FALSE;
- m_uClassificationTable = 0;
- m_sClassificationInfo.Clear();
- ClearKeywords();
- m_sLocationName.Clear();
- m_sLocationAstronomicalBody.Clear();
- m_sLocationAdditionalNotes.Clear();
- m_bValidLocationRole = FALSE;
- m_uLocationRole = 0;
- m_sLocationLongitude.Clear();
- m_sLocationLatitude.Clear();
- m_sLocationAltitude.Clear();
- m_sAlbumTitle.Clear();
- m_bValidAlbumTrackNumber = FALSE;
- m_uAlbumTrackNumber = 0;
- m_bValidRecordingYear = FALSE;
- m_uRecordingYear = 0;
-}
-
-void MetaInfo3GP::Update(const MetaInfo3GP& src)
-{
- Update(m_sGlobalLanguageEncoding, src.m_sGlobalLanguageEncoding);
- Update(m_sTitle, src.m_sTitle);
- Update(m_sAuthor, src.m_sAuthor);
- Update(m_sCopyright, src.m_sCopyright);
- Update(m_sDescription, src.m_sDescription);
- Update(m_sPerformer, src.m_sPerformer);
- Update(m_sGenre, src.m_sGenre);
- Update(m_sRatingEntity, src.m_sRatingEntity);
- Update(m_sRatingCriteria, src.m_sRatingCriteria);
- Update(m_sRatingInfo, src.m_sRatingInfo);
- Update(m_sClassificationEntity, src.m_sClassificationEntity);
- Update(m_uClassificationTable, m_bValidClassificationTable, src.m_uClassificationTable, src.m_bValidClassificationTable);
- Update(m_sClassificationInfo, src.m_sClassificationInfo);
- Update(m_sLocationName, src.m_sLocationName);
- Update(m_sLocationAstronomicalBody, src.m_sLocationAstronomicalBody);
- Update(m_sLocationAdditionalNotes, src.m_sLocationAdditionalNotes);
- Update(m_uLocationRole, m_bValidLocationRole, src.m_uLocationRole, src.m_bValidLocationRole);
- Update(m_sLocationLongitude, src.m_sLocationLongitude);
- Update(m_sLocationLatitude, src.m_sLocationLatitude);
- Update(m_sLocationAltitude, src.m_sLocationAltitude);
- Update(m_sAlbumTitle, src.m_sAlbumTitle);
- Update(m_uAlbumTrackNumber, m_bValidAlbumTrackNumber, src.m_uAlbumTrackNumber, src.m_bValidAlbumTrackNumber);
- Update(m_uRecordingYear, m_bValidRecordingYear, src.m_uRecordingYear, src.m_bValidRecordingYear);
-
- for(UINT32 i = 0; i < src.GetKeywordCount(); i++)
- {
- EncodedString sTmp;
- src.GetKeyword(i, sTmp);
- AddKeyword(sTmp);
- }
-}
-
-void MetaInfo3GP::CopyToValues(IHXValues* pValues) const
-{
- if(!pValues)
- {
- return;
- }
- CopyString(pValues, _3GPP_META_INFO_GLOBAL_LANGUAGE_ENCODING_KEY, &MetaInfo3GP::GetGlobalLanguageEncoding);
- CopyString(pValues, _3GPP_META_INFO_TITLE_KEY, &MetaInfo3GP::GetTitle);
- CopyString(pValues, _3GPP_META_INFO_AUTHOR_KEY, &MetaInfo3GP::GetAuthor);
- CopyString(pValues, _3GPP_META_INFO_COPYRIGHT_KEY, &MetaInfo3GP::GetCopyright);
- CopyString(pValues, _3GPP_META_INFO_DESCRIPTION_KEY, &MetaInfo3GP::GetDescription);
- CopyString(pValues, _3GPP_META_INFO_PERFORMER_KEY, &MetaInfo3GP::GetPerformer);
- CopyString(pValues, _3GPP_META_INFO_GENRE_KEY, &MetaInfo3GP::GetGenre);
- CopyString(pValues, _3GPP_META_INFO_RATING_ENTITY_KEY, &MetaInfo3GP::GetRatingEntity);
- CopyString(pValues, _3GPP_META_INFO_RATING_CRITERIA_KEY, &MetaInfo3GP::GetRatingCriteria);
- CopyString(pValues, _3GPP_META_INFO_RATING_INFO_KEY, &MetaInfo3GP::GetRatingInfo);
- CopyString(pValues, _3GPP_META_INFO_CLASSIFICATION_ENTITY_KEY, &MetaInfo3GP::GetClassificationEntity);
- CopyULONG32(pValues, _3GPP_META_INFO_CLASSIFICATION_TABLE_KEY, &MetaInfo3GP::GetClassificationTable);
- CopyString(pValues, _3GPP_META_INFO_CLASSIFICATION_INFO_KEY, &MetaInfo3GP::GetClassificationInfo);
- CopyString(pValues, _3GPP_META_INFO_LOCATION_NAME_KEY, &MetaInfo3GP::GetLocationName);
- CopyString(pValues, _3GPP_META_INFO_LOCATION_ASTRONOMICAL_BODY_KEY, &MetaInfo3GP::GetLocationAstronomicalBody);
- CopyString(pValues, _3GPP_META_INFO_LOCATION_ADDITIONAL_NOTES_KEY, &MetaInfo3GP::GetLocationAdditionalNotes);
- CopyULONG32(pValues, _3GPP_META_INFO_LOCATION_ROLE_KEY, &MetaInfo3GP::GetLocationRole);
- CopyString(pValues, _3GPP_META_INFO_LOCATION_LONGITUDE_KEY, &MetaInfo3GP::GetLocationLongitude);
- CopyString(pValues, _3GPP_META_INFO_LOCATION_LATITUDE_KEY, &MetaInfo3GP::GetLocationLatitude);
- CopyString(pValues, _3GPP_META_INFO_LOCATION_ALTITUDE_KEY, &MetaInfo3GP::GetLocationAltitude);
- CopyString(pValues, _3GPP_META_INFO_ALBUM_TITLE_KEY, &MetaInfo3GP::GetAlbumTitle);
- CopyULONG32(pValues, _3GPP_META_INFO_TRACK_NUMBER_KEY, &MetaInfo3GP::GetAlbumTrackNumber);
- CopyULONG32(pValues, _3GPP_META_INFO_RECORDING_YEAR_KEY, &MetaInfo3GP::GetRecordingYear);
-
- // keyword section
- EncodedString sTmp;
- UINT32 ulKeywordCount = GetKeywordCount();
- if(ulKeywordCount)
- {
- PropTools::CopyPropertyULONG32(pValues, TRUE, ULONG32(ulKeywordCount),
- _3GPP_META_INFO_KEYWORD_COUNT_KEY, TRUE);
- for(UINT32 i = 0; i < ulKeywordCount; i++)
- {
- char key[128];
- sprintf(key, _3GPP_META_INFO_KEYWORD_KEY, int(i));
- GetKeyword(i, sTmp);
- PropTools::CopyPropertyBuffer(pValues, sTmp, key, TRUE);
- }
- }
-}
-
-void MetaInfo3GP::CopyFromValues(IHXValues* pValues)
-{
- if(! pValues)
- {
- return;
- }
- CopyString(&MetaInfo3GP::SetGlobalLanguageEncoding, pValues, _3GPP_META_INFO_GLOBAL_LANGUAGE_ENCODING_KEY);
- CopyString(&MetaInfo3GP::SetTitle, pValues, _3GPP_META_INFO_TITLE_KEY);
- CopyString(&MetaInfo3GP::SetAuthor, pValues, _3GPP_META_INFO_AUTHOR_KEY);
- CopyString(&MetaInfo3GP::SetCopyright, pValues, _3GPP_META_INFO_COPYRIGHT_KEY);
- CopyString(&MetaInfo3GP::SetDescription, pValues, _3GPP_META_INFO_DESCRIPTION_KEY);
- CopyString(&MetaInfo3GP::SetPerformer, pValues, _3GPP_META_INFO_PERFORMER_KEY);
- CopyString(&MetaInfo3GP::SetGenre, pValues, _3GPP_META_INFO_GENRE_KEY);
- CopyString(&MetaInfo3GP::SetRatingEntity, pValues, _3GPP_META_INFO_RATING_ENTITY_KEY);
- CopyString(&MetaInfo3GP::SetRatingCriteria, pValues, _3GPP_META_INFO_RATING_CRITERIA_KEY);
- CopyString(&MetaInfo3GP::SetRatingInfo, pValues, _3GPP_META_INFO_RATING_INFO_KEY);
- CopyString(&MetaInfo3GP::SetClassificationEntity, pValues, _3GPP_META_INFO_CLASSIFICATION_ENTITY_KEY);
- CopyULONG32(&MetaInfo3GP::SetClassificationTable, pValues, _3GPP_META_INFO_CLASSIFICATION_TABLE_KEY);
- CopyString(&MetaInfo3GP::SetClassificationInfo, pValues, _3GPP_META_INFO_CLASSIFICATION_INFO_KEY);
- CopyString(&MetaInfo3GP::SetLocationName, pValues, _3GPP_META_INFO_LOCATION_NAME_KEY);
- CopyString(&MetaInfo3GP::SetLocationAstronomicalBody, pValues, _3GPP_META_INFO_LOCATION_ASTRONOMICAL_BODY_KEY);
- CopyString(&MetaInfo3GP::SetLocationAdditionalNotes, pValues, _3GPP_META_INFO_LOCATION_ADDITIONAL_NOTES_KEY);
- CopyULONG32(&MetaInfo3GP::SetLocationRole, pValues, _3GPP_META_INFO_LOCATION_ROLE_KEY);
- CopyString(&MetaInfo3GP::SetLocationLongitude, pValues, _3GPP_META_INFO_LOCATION_LONGITUDE_KEY);
- CopyString(&MetaInfo3GP::SetLocationLatitude, pValues, _3GPP_META_INFO_LOCATION_LATITUDE_KEY);
- CopyString(&MetaInfo3GP::SetLocationAltitude, pValues, _3GPP_META_INFO_LOCATION_ALTITUDE_KEY);
- CopyString(&MetaInfo3GP::SetAlbumTitle, pValues, _3GPP_META_INFO_ALBUM_TITLE_KEY);
- CopyULONG32(&MetaInfo3GP::SetAlbumTrackNumber, pValues, _3GPP_META_INFO_TRACK_NUMBER_KEY);
- CopyULONG32(&MetaInfo3GP::SetRecordingYear, pValues, _3GPP_META_INFO_RECORDING_YEAR_KEY);
-
- // keyword section
- EncodedString sTmp;
- ULONG32 ulKeywordCount = 0;
- if(PropTools::CopyPropertyULONG32(ulKeywordCount, pValues, _3GPP_META_INFO_KEYWORD_COUNT_KEY))
- {
- for(UINT32 i = 0; i < ulKeywordCount; i++)
- {
- char key[128];
- sprintf(key, _3GPP_META_INFO_KEYWORD_KEY, int(i));
- if(PropTools::CopyPropertyBuffer(sTmp, pValues, key))
- {
- AddKeyword(sTmp);
- }
- }
- }
- RemoveKeywordDuplicates();
-}
-
-BOOL MetaInfo3GP::GetGlobalLanguageEncoding(EncodedString& out) const
-{
- return GetString(m_sGlobalLanguageEncoding, out);
-}
-
-BOOL MetaInfo3GP::SetGlobalLanguageEncoding(const EncodedString& val)
-{
- if(!val.IsAsciiOnly() || (val.GetCodeUnitLength(FALSE, FALSE) != 3))
- {
- return FALSE;
- }
- EncodedString valConv;
- val.ConvertToUTF8(valConv);
- if(!val.GetData())
- {
- return FALSE;
- }
- CHXISO639LangCodeRegistry lcreg;
- if(!lcreg.IsValidLangCode(valConv.GetData()))
- {
- return FALSE;
- }
- return SetString(m_sGlobalLanguageEncoding, valConv);
-}
-
-BOOL MetaInfo3GP::GetTitle(EncodedString& out) const
-{
- return GetString(m_sTitle, out);
-}
-
-BOOL MetaInfo3GP::SetTitle(const EncodedString& val)
-{
- return SetString(m_sTitle, val);
-}
-
-BOOL MetaInfo3GP::GetAuthor(EncodedString& out) const
-{
- return GetString(m_sAuthor, out);
-}
-
-BOOL MetaInfo3GP::SetAuthor(const EncodedString& val)
-{
- return SetString(m_sAuthor, val);
-}
-
-BOOL MetaInfo3GP::GetCopyright(EncodedString& out) const
-{
- return GetString(m_sCopyright, out);
-}
-
-BOOL MetaInfo3GP::SetCopyright(const EncodedString& val)
-{
- return SetString(m_sCopyright, val);
-}
-
-BOOL MetaInfo3GP::GetDescription(EncodedString& out) const
-{
- return GetString(m_sDescription, out);
-}
-
-BOOL MetaInfo3GP::SetDescription(const EncodedString& val)
-{
- return SetString(m_sDescription, val);
-}
-
-BOOL MetaInfo3GP::GetPerformer(EncodedString& out) const
-{
- return GetString(m_sPerformer, out);
-}
-
-BOOL MetaInfo3GP::SetPerformer(const EncodedString& val)
-{
- return SetString(m_sPerformer, val);
-}
-
-BOOL MetaInfo3GP::GetGenre(EncodedString& out) const
-{
- return GetString(m_sGenre, out);
-}
-
-BOOL MetaInfo3GP::SetGenre(const EncodedString& val)
-{
- return SetString(m_sGenre, val);
-}
-
-BOOL MetaInfo3GP::GetRatingEntity(EncodedString& out) const
-{
- return GetString(m_sRatingEntity, out);
-}
-
-BOOL MetaInfo3GP::SetRatingEntity(const EncodedString& val)
-{
- return MetaInfo3GP::SetStringAsciiMaxLen(m_sRatingEntity, val, 4);
-}
-
-BOOL MetaInfo3GP::GetRatingCriteria(EncodedString& out) const
-{
- return GetString(m_sRatingCriteria, out);
-}
-
-BOOL MetaInfo3GP::SetRatingCriteria(const EncodedString& val)
-{
- return MetaInfo3GP::SetStringAsciiMaxLen(m_sRatingCriteria, val, 4);
-}
-
-BOOL MetaInfo3GP::GetRatingInfo(EncodedString& out) const
-{
- return GetString(m_sRatingInfo, out);
-}
-
-BOOL MetaInfo3GP::SetRatingInfo(const EncodedString& val)
-{
- return SetString(m_sRatingInfo, val);
-}
-
-BOOL MetaInfo3GP::GetClassificationEntity(EncodedString& out) const
-{
- return GetString(m_sClassificationEntity, out);
-}
-
-BOOL MetaInfo3GP::SetClassificationEntity(const EncodedString& val)
-{
- return MetaInfo3GP::SetStringAsciiMaxLen(m_sClassificationEntity, val, 4);
-}
-
-BOOL MetaInfo3GP::GetClassificationTable(UINT16& out) const
-{
- return GetUINT16(m_uClassificationTable, m_bValidClassificationTable, out);
-}
-
-BOOL MetaInfo3GP::SetClassificationTable(UINT16 val, BOOL bValid)
-{
- return SetUINT16(m_uClassificationTable, m_bValidClassificationTable, val, bValid);
-}
-
-BOOL MetaInfo3GP::GetClassificationInfo(EncodedString& out) const
-{
- return GetString(m_sClassificationInfo, out);
-}
-
-BOOL MetaInfo3GP::SetClassificationInfo(const EncodedString& val)
-{
- return SetString(m_sClassificationInfo, val);
-}
-
-UINT32 MetaInfo3GP::GetKeywordCount() const
-{
- return (UINT32)m_aKeywords.GetSize();
-}
-
-BOOL MetaInfo3GP::GetKeyword(UINT32 index, EncodedString& out) const
-{
- INT32 idx = INT32(index);
- if(idx < m_aKeywords.GetSize())
- {
- out = *((EncodedString*)m_aKeywords[idx]);
- return TRUE;
- }
- return FALSE;
-}
-
-void MetaInfo3GP::ClearKeywords()
-{
- ClearPropertyStringArray(m_aKeywords);
-}
-
-BOOL MetaInfo3GP::AddKeyword(const EncodedString& val)
-{
- if(val.GetByteLength() > 255)
- {
- return FALSE;
- }
- for(INT32 i = 0; i < m_aKeywords.GetSize(); i++)
- {
- if(*((EncodedString*)m_aKeywords[i]) == val)
- {
- return TRUE;
- }
- }
- m_aKeywords.Add(new EncodedString(val));
- return TRUE;
-}
-
-void MetaInfo3GP::RemoveKeyword(const EncodedString& val)
-{
- for(INT32 i = 0; i < m_aKeywords.GetSize(); i++)
- {
- EncodedString* s = (EncodedString*)m_aKeywords[i];
- if(*s == val)
- {
- delete s;
- // Remaining keywords are shifted to fill the hole,
- // search index must stay the same for new iteration.
- m_aKeywords.RemoveAt(i--, 1);
- }
- }
-}
-
-void MetaInfo3GP::RemoveKeywordDuplicates()
-{
- CHXPtrArray aTmpKeywords;
- for(INT32 i = 0; i < m_aKeywords.GetSize(); i++)
- {
- aTmpKeywords.Add(new EncodedString(*((EncodedString*)m_aKeywords[i])));
- }
- ClearPropertyStringArray(m_aKeywords);
- for(INT32 i = 0; i < aTmpKeywords.GetSize(); i++)
- {
- AddKeyword(*((EncodedString*)aTmpKeywords[i]));
- }
- ClearPropertyStringArray(aTmpKeywords);
-}
-
-BOOL MetaInfo3GP::GetLocationName(EncodedString& out) const
-{
- return GetString(m_sLocationName, out);
-}
-
-BOOL MetaInfo3GP::SetLocationName(const EncodedString& val)
-{
- return SetString(m_sLocationName, val);
-}
-
-BOOL MetaInfo3GP::GetLocationAstronomicalBody(EncodedString& out) const
-{
- return GetString(m_sLocationAstronomicalBody, out);
-}
-
-BOOL MetaInfo3GP::SetLocationAstronomicalBody(const EncodedString& val)
-{
- return SetString(m_sLocationAstronomicalBody, val);
-}
-
-BOOL MetaInfo3GP::GetLocationAdditionalNotes(EncodedString& out) const
-{
- return GetString(m_sLocationAdditionalNotes, out);
-}
-
-BOOL MetaInfo3GP::SetLocationAdditionalNotes(const EncodedString& val)
-{
- return SetString(m_sLocationAdditionalNotes, val);
-}
-
-BOOL MetaInfo3GP::GetLocationRole(UINT8& out) const
-{
- return GetUINT8(m_uLocationRole, m_bValidLocationRole, out);
-}
-
-BOOL MetaInfo3GP::SetLocationRole(UINT8 val, BOOL bValid)
-{
- return SetUINT8(m_uLocationRole, m_bValidLocationRole, val, bValid);
-}
-
-BOOL MetaInfo3GP::GetLocationLongitude(EncodedString& out) const
-{
- return GetString(m_sLocationLongitude, out);
-}
-
-BOOL MetaInfo3GP::SetLocationLongitude(const EncodedString& val)
-{
- return SetStringFixedPointNum(m_sLocationLongitude, val);
-}
-
-BOOL MetaInfo3GP::GetLocationLatitude(EncodedString& out) const
-{
- return GetString(m_sLocationLatitude, out);
-}
-
-BOOL MetaInfo3GP::SetLocationLatitude(const EncodedString& val)
-{
- return SetStringFixedPointNum(m_sLocationLatitude, val);
-}
-
-BOOL MetaInfo3GP::GetLocationAltitude(EncodedString& out) const
-{
- return GetString(m_sLocationAltitude, out);
-}
-
-BOOL MetaInfo3GP::SetLocationAltitude(const EncodedString& val)
-{
- return SetStringFixedPointNum(m_sLocationAltitude, val);
-}
-
-BOOL MetaInfo3GP::GetAlbumTitle(EncodedString& out) const
-{
- return GetString(m_sAlbumTitle, out);
-}
-
-BOOL MetaInfo3GP::SetAlbumTitle(const EncodedString& val)
-{
- return SetString(m_sAlbumTitle, val);
-}
-
-BOOL MetaInfo3GP::GetAlbumTrackNumber(UINT8& out) const
-{
- return GetUINT8(m_uAlbumTrackNumber, m_bValidAlbumTrackNumber, out);
-}
-
-BOOL MetaInfo3GP::SetAlbumTrackNumber(UINT8 val, BOOL bValid)
-{
- return SetUINT8(m_uAlbumTrackNumber, m_bValidAlbumTrackNumber, val, bValid);
-}
-
-BOOL MetaInfo3GP::GetRecordingYear(UINT16& out) const
-{
- return GetUINT16(m_uRecordingYear, m_bValidRecordingYear, out);
-}
-
-BOOL MetaInfo3GP::SetRecordingYear(UINT16 val, BOOL bValid)
-{
- return SetUINT16(m_uRecordingYear, m_bValidRecordingYear, val, bValid);
-}
-
-BOOL MetaInfo3GP::GetString(const EncodedString& src, EncodedString& out)
-{
- out = src;
- return !out.IsEmpty();
-}
-
-BOOL MetaInfo3GP::SetString(EncodedString& dst, const EncodedString& val)
-{
- dst = val;
- return TRUE;
-}
-
-BOOL MetaInfo3GP::SetStringAsciiMaxLen(EncodedString& dst, const EncodedString& val, UINT32 maxLen)
-{
- if(!val.IsAsciiOnly() || (val.GetCodeUnitLength(FALSE, FALSE) > maxLen))
- {
- return FALSE;
- }
- dst = val;
- return TRUE;
-}
-
-BOOL MetaInfo3GP::SetStringFixedPointNum(EncodedString& dst, const EncodedString& val)
-{
- EncodedString normVal = val;
- if(!PropTools::IsFixedPointNumber(normVal, TRUE))
- {
- return FALSE;
- }
- dst = normVal;
- return TRUE;
-}
-
-BOOL MetaInfo3GP::GetUINT16(const UINT16& src, const BOOL& srcValid, UINT16& out)
-{
- out = src;
- return srcValid;
-}
-
-BOOL MetaInfo3GP::SetUINT16(UINT16& dst, BOOL& dstValid, UINT16 val, BOOL bValid)
-{
- dst = val;
- dstValid = bValid;
- return TRUE;
-}
-
-BOOL MetaInfo3GP::GetUINT8(const UINT8& src, const BOOL& srcValid, UINT8& out)
-{
- out = src;
- return srcValid;
-}
-
-BOOL MetaInfo3GP::SetUINT8(UINT8& dst, BOOL& dstValid, UINT8 val, BOOL bValid)
-{
- dst = val;
- dstValid = bValid;
- return TRUE;
-}
-
-void MetaInfo3GP::Update(EncodedString& dst, const EncodedString& src)
-{
- if(!src.IsEmpty())
- {
- dst = src;
- }
-}
-
-void MetaInfo3GP::Update(UINT16& dst, BOOL& dstValid, const UINT16& src, const BOOL& srcValid)
-{
- if(srcValid)
- {
- dstValid = srcValid;
- dst = src;
- }
-}
-
-void MetaInfo3GP::Update(UINT8& dst, BOOL& dstValid, const UINT8& src, const BOOL& srcValid)
-{
- if(srcValid)
- {
- dstValid = srcValid;
- dst = src;
- }
-}
-
-void MetaInfo3GP::Dump(const char* propName, const EncodedString& val)
-{
- if(!val.IsEmpty())
- {
- printf("%s: ", propName);
- val.Dump();
- printf("\n");
- }
-}
-
-void MetaInfo3GP::Dump(const char* propName, const UINT16& val, const BOOL& bValid)
-{
- if(bValid)
- {
- printf("%s: %d\n", propName, int(val));
- }
-}
-
-void MetaInfo3GP::Dump(const char* propName, const UINT8& val, const BOOL& bValid)
-{
- if(bValid)
- {
- printf("%s: %d\n", propName, int(val));
- }
-}
-
-void MetaInfo3GP::ClearPropertyStringArray(CHXPtrArray& aStrings)
-{
- for(INT32 i = 0; i < aStrings.GetSize(); i++)
- {
- delete (EncodedString*)aStrings[i];
- }
- aStrings.RemoveAll();
-}
-
-void MetaInfo3GP::CopyString(MetaInfo3GP::FnStringSetter setter,
- IHXValues* pValues, const char* enginePropName)
-{
- EncodedString sTmp;
- if(PropTools::CopyPropertyBuffer(sTmp, pValues, enginePropName))
- {
- (this->*setter)(sTmp);
- }
-}
-
-void MetaInfo3GP::CopyULONG32(MetaInfo3GP::FnUINT16Setter setter,
- IHXValues* pValues, const char* enginePropName)
-{
- ULONG32 uTmp;
- if(PropTools::CopyPropertyULONG32(uTmp, pValues, enginePropName))
- {
- (this->*setter)(UINT16(uTmp), TRUE);
- }
-}
-
-void MetaInfo3GP::CopyULONG32(MetaInfo3GP::FnUINT8Setter setter,
- IHXValues* pValues, const char* enginePropName)
-{
- ULONG32 uTmp;
- if(PropTools::CopyPropertyULONG32(uTmp, pValues, enginePropName))
- {
- (this->*setter)(UINT8(uTmp), TRUE);
- }
-}
-
-void MetaInfo3GP::CopyString(IHXValues* pValues, const char* enginePropName,
- MetaInfo3GP::FnStringGetter getter) const
-{
- EncodedString sTmp;
- (this->*getter)(sTmp);
- PropTools::CopyPropertyBuffer(pValues, sTmp, enginePropName, TRUE);
-}
-
-void MetaInfo3GP::CopyULONG32(IHXValues* pValues, const char* enginePropName,
- MetaInfo3GP::FnUINT16Getter getter) const
-{
- UINT16 uVal = 0;
- BOOL bValid = (this->*getter)(uVal);
- PropTools::CopyPropertyULONG32(pValues, bValid, ULONG32(uVal), enginePropName, TRUE);
-}
-
-void MetaInfo3GP::CopyULONG32(IHXValues* pValues, const char* enginePropName,
- MetaInfo3GP::FnUINT8Getter getter) const
-{
- UINT8 uVal = 0;
- BOOL bValid = (this->*getter)(uVal);
- PropTools::CopyPropertyULONG32(pValues, bValid, ULONG32(uVal), enginePropName, TRUE);
-}
-
Index: srchandler.cpp
===================================================================
RCS file: /cvsroot/datatype/tools/metaeditor/srchandler.cpp,v
retrieving revision 1.1
diff -d -H -b -B -w -U30 -r1.1 srchandler.cpp
--- srchandler.cpp 5 Nov 2007 22:29:46 -0000 1.1
+++ srchandler.cpp 19 Oct 2009 13:04:53 -0000
@@ -26,75 +26,74 @@
* or RCSL, indicate your decision by deleting the provisions above
* and replace them with the notice and other provisions required by
* the GPL. 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
* RPSL, the RCSL or the GPL.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the
* portions it created.
*
* This file, and the files included with this file, is distributed
* and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
* ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "hxtypes.h"
#include "hxcom.h"
#include "hxdtdr.h"
#include "pckunpck.h"
#include "proptools.h"
+#include "metautil.h"
#include "srchandler.h"
-#include "metautil3gp.h"
CSourceHandler::CSourceHandler()
: m_lRefCount(0)
, m_pContext(0)
, m_pSourceSink(0)
, m_pProcessor(0)
, m_pExtractedMetaData(0)
, m_pInjectedMetaData(0)
, m_pTmpValues(0)
, m_ulDiscardExtracted(0)
- , m_eMetaDataFlavor(METADATA_FLAVOR_UNKNOWN)
{
}
CSourceHandler::~CSourceHandler()
{
HX_RELEASE(m_pContext);
HX_RELEASE(m_pSourceSink);
HX_RELEASE(m_pProcessor);
HX_RELEASE(m_pExtractedMetaData);
HX_RELEASE(m_pInjectedMetaData);
HX_RELEASE(m_pTmpValues);
}
STDMETHODIMP
CSourceHandler::QueryInterface(REFIID riid, void** ppvObj)
{
if(IsEqualIID(riid, IID_IUnknown))
{
AddRef();
*ppvObj = (IUnknown*)this;
return HXR_OK;
}
if(IsEqualIID(riid, IID_IHXSourceInput))
{
AddRef();
*ppvObj = (IHXSourceInput*)(IHXSourceHandler*)this;
return HXR_OK;
}
if(IsEqualIID(riid, IID_IHXSourceHandler))
{
@@ -120,86 +119,87 @@
STDMETHODIMP_(ULONG32)
CSourceHandler::Release()
{
if(InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
STDMETHODIMP
CSourceHandler::OnFileHeader(HX_RESULT status, IHXValues* pValues)
{
if(!m_pContext)
{
return HXR_FAILED;
}
HX_RESULT retVal = HXR_OK;
// cleanup storage
PropTools::RemoveAllProperties(retVal, m_pExtractedMetaData);
PropTools::RemoveAllProperties(retVal, m_pInjectedMetaData);
PropTools::RemoveAllProperties(retVal, m_pTmpValues);
// collect inbound meta-data
if(SUCCEEDED(retVal))
{
- retVal = ExtractMetaData(m_pExtractedMetaData, pValues);
+ retVal = MetaInfo::CopyAllProperties(m_pExtractedMetaData, pValues, METAINFO_SET_ALL, FALSE);
}
// collect new meta-data
if(SUCCEEDED(retVal) && m_pProcessor)
{
retVal = m_pProcessor->OnInboundMetaData(m_pExtractedMetaData, m_pTmpValues);
}
if(SUCCEEDED(retVal))
{
- // filter-out non meta-data
- retVal = ExtractMetaData(m_pInjectedMetaData, m_pTmpValues);
+ // filter-out non meta-data from injected values
+ retVal = MetaInfo::CopyAllProperties(m_pInjectedMetaData, m_pTmpValues, METAINFO_SET_ALL, FALSE);
}
- // merge extracted and injected values
+ // merge extracted and injected values into the original storage
if(m_ulDiscardExtracted)
{
- retVal = RemoveMetaData(pValues);
+ retVal = MetaInfo::RemoveAllProperties(pValues, METAINFO_SET_ALL);
}
PropTools::CopyAllProperties(retVal, pValues, m_pInjectedMetaData);
// construct copy of outbound meta-data
PropTools::RemoveAllProperties(retVal, m_pTmpValues);
+
if(SUCCEEDED(retVal))
{
- retVal = ExtractMetaData(m_pTmpValues, pValues);
+ retVal = MetaInfo::CopyAllProperties(m_pTmpValues, pValues, METAINFO_SET_ALL, FALSE);
}
if(SUCCEEDED(retVal) && m_pProcessor)
{
retVal = m_pProcessor->OnOutboundMetaData(m_pTmpValues);
}
// call next source handler
if(SUCCEEDED(retVal) && m_pSourceSink)
{
retVal = m_pSourceSink->OnFileHeader(status, pValues);
}
return retVal;
}
STDMETHODIMP
CSourceHandler::OnStreamHeader(HX_RESULT status, IHXValues* pValues)
{
HX_RESULT retVal = HXR_OK;
if(m_pSourceSink)
{
retVal = m_pSourceSink->OnStreamHeader(status, pValues);
}
return retVal;
}
STDMETHODIMP
CSourceHandler::OnStreamDone(HX_RESULT status, UINT16 unStreamNumber)
{
HX_RESULT retVal = HXR_OK;
if(m_pSourceSink)
@@ -219,110 +219,75 @@
}
return retVal;
}
STDMETHODIMP
CSourceHandler::OnTermination(HX_RESULT status)
{
HX_RESULT retVal = HXR_OK;
if(m_pSourceSink)
{
retVal = m_pSourceSink->OnTermination(status);
}
return retVal;
}
STDMETHODIMP
CSourceHandler::InitSourceHandler(IHXSourceInput* pSourceSink, IHXValues* pOptions)
{
HX_RELEASE(m_pSourceSink);
m_pSourceSink = pSourceSink;
HX_ADDREF(m_pSourceSink);
// extract options
if(pOptions)
{
ULONG32 ulBlastMetaData = 0;
if(SUCCEEDED(pOptions->GetPropertyULONG32(BLASTMETADATA_OPTION_NAME, ulBlastMetaData)))
{
m_ulDiscardExtracted = ulBlastMetaData ? 1 : 0;
}
- ULONG32 ulMetaDataFlavor = 0;
- if(SUCCEEDED(pOptions->GetPropertyULONG32(METADATAFLAVOR_OPTION_NAME, ulMetaDataFlavor)))
- {
- m_eMetaDataFlavor = (METADATA_FLAVOR)ulMetaDataFlavor;
- }
}
return HXR_OK;
}
STDMETHODIMP
CSourceHandler::Close()
{
HX_RELEASE(m_pSourceSink);
return HXR_OK;
}
STDMETHODIMP
CSourceHandler::InitMetaDataSourceHandler(IUnknown* pContext)
{
if(pContext)
{
m_pContext = pContext;
HX_ADDREF(m_pContext);
// create property stores
HX_RESULT retVal = HXR_OK;
retVal = CreateInstanceCCF_QI(CLSID_IHXValues, IID_IHXValues, (void**)&m_pExtractedMetaData, m_pContext);
if(SUCCEEDED(retVal))
{
retVal = CreateInstanceCCF_QI(CLSID_IHXValues, IID_IHXValues, (void**)&m_pInjectedMetaData, m_pContext);
}
if(SUCCEEDED(retVal))
{
retVal = CreateInstanceCCF_QI(CLSID_IHXValues, IID_IHXValues, (void**)&m_pTmpValues, m_pContext);
}
return retVal;
}
return HXR_FAILED;
}
STDMETHODIMP
CSourceHandler::SetProcessor(IHXMetaDataProcessor* pProcessor)
{
HX_RELEASE(m_pProcessor);
m_pProcessor = pProcessor;
HX_ADDREF(m_pProcessor);
return HXR_OK;
}
-STDMETHODIMP
-CSourceHandler::ExtractMetaData(IHXValues* pDst, IHXValues* pSrc)
-{
- switch(m_eMetaDataFlavor)
- {
- case METADATA_FLAVOR_3GP:
- return CopyAllProperties_MetaInfo3GP(pDst, pSrc, FALSE);
-
- default:
- // unknown flavor
- break;
- }
- return HXR_OK;
-}
-
-STDMETHODIMP
-CSourceHandler::RemoveMetaData(IHXValues* pValues)
-{
- switch(m_eMetaDataFlavor)
- {
- case METADATA_FLAVOR_3GP:
- return RemoveAllProperties_MetaInfo3GP(pValues);
-
- default:
- // unknown flavor
- break;
- }
- return HXR_OK;
-}
-
Index: srchandler.h
===================================================================
RCS file: /cvsroot/datatype/tools/metaeditor/srchandler.h,v
retrieving revision 1.1
diff -d -H -b -B -w -U30 -r1.1 srchandler.h
--- srchandler.h 5 Nov 2007 22:29:46 -0000 1.1
+++ srchandler.h 19 Oct 2009 13:04:53 -0000
@@ -54,47 +54,42 @@
#include "ihxmetaeditor.h"
class CSourceHandler : public IHXMetaDataSourceHandler
{
public:
CSourceHandler();
virtual ~CSourceHandler();
// IUnknown methods
STDMETHOD(QueryInterface)(REFIID riid, void** ppvObj);
STDMETHOD_(ULONG32, AddRef)();
STDMETHOD_(ULONG32, Release)();
// IHXSourceInput methods
STDMETHOD(OnFileHeader)(HX_RESULT status, IHXValues* pValues);
STDMETHOD(OnStreamHeader)(HX_RESULT status, IHXValues* pValues);
STDMETHOD(OnStreamDone)(HX_RESULT status, UINT16 unStreamNumber);
STDMETHOD(OnPacket)(HX_RESULT status, IHXPacket* pPacket);
STDMETHOD(OnTermination)(HX_RESULT status);
// IHXSourceHandler methods
STDMETHOD(InitSourceHandler)(IHXSourceInput* pSourceSink, IHXValues* pOptions);
STDMETHOD(Close)();
// IHXMetaDataSourceHandler methods
STDMETHOD(InitMetaDataSourceHandler)(IUnknown* pContext);
STDMETHOD(SetProcessor)(IHXMetaDataProcessor* pProcessor);
private:
- STDMETHOD(ExtractMetaData)(IHXValues* pDst, IHXValues* pSrc);
- STDMETHOD(RemoveMetaData)(IHXValues* pValues);
-
-private:
LONG32 m_lRefCount;
IUnknown* m_pContext;
IHXSourceInput* m_pSourceSink;
IHXMetaDataProcessor* m_pProcessor;
IHXValues* m_pExtractedMetaData;
IHXValues* m_pInjectedMetaData;
IHXValues* m_pTmpValues;
ULONG32 m_ulDiscardExtracted;
- METADATA_FLAVOR m_eMetaDataFlavor;
};
#endif // _SRCHANDLER_H
Index: pub/metautil3gp.h
===================================================================
RCS file: pub/metautil3gp.h
diff -N pub/metautil3gp.h
--- pub/metautil3gp.h 5 Nov 2007 22:29:46 -0000 1.1
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,227 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: RCSL 1.0/RPSL 1.0
- *
- * Portions Copyright (c) 1995-2007 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file, are
- * subject to the current version of the RealNetworks Public Source License
- * Version 1.0 (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the RealNetworks Community Source License Version 1.0
- * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
- * in which case the RCSL will apply. You may also obtain the license terms
- * directly from RealNetworks. You may not use this file except in
- * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
- * applicable to this file, the RCSL. Please see the applicable RPSL or
- * RCSL for the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the portions
- * it created.
- *
- * This file, and the files included with this file, is distributed and made
- * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
-
-#ifndef _METAUTIL3GP_H_
-#define _METAUTIL3GP_H_
-
-#include "hxtypes.h"
-#include "carray.h"
-#include "encstr.h"
-
-
-HX_RESULT RemoveKeywordProperties_MetaInfo3GP(IHXValues* pValues);
-HX_RESULT RemoveAllProperties_MetaInfo3GP(IHXValues* pValues);
-
-HX_RESULT CopyKeywordProperties_MetaInfo3GP(IHXValues* dst, IHXValues* src, BOOL bBlast);
-HX_RESULT CopyAllProperties_MetaInfo3GP(IHXValues* dst, IHXValues* src, BOOL bBlast);
-
-
-class MetaInfo3GP
-{
-public:
- typedef BOOL (MetaInfo3GP::*FnStringGetter)(EncodedString&) const;
- typedef BOOL (MetaInfo3GP::*FnStringSetter)(const EncodedString&);
-
- typedef BOOL (MetaInfo3GP::*FnUINT8Getter)(UINT8&) const;
- typedef BOOL (MetaInfo3GP::*FnUINT8Setter)(UINT8, BOOL);
-
- typedef BOOL (MetaInfo3GP::*FnUINT16Getter)(UINT16&) const;
- typedef BOOL (MetaInfo3GP::*FnUINT16Setter)(UINT16, BOOL);
-
-public:
- MetaInfo3GP();
- ~MetaInfo3GP();
-
- MetaInfo3GP(const MetaInfo3GP& rhs);
- MetaInfo3GP& operator=(const MetaInfo3GP& rhs);
-
- void Dump();
-
- void Clear();
- void Update(const MetaInfo3GP& src);
-
- void CopyToValues(IHXValues* pValues) const;
- void CopyFromValues(IHXValues* pValues);
-
- // Getters always update <out>.
- // String getters return TRUE if <out> is empty.
- // UINT getters return TRUE if the value copied to <out> is considered valid.
-
- // Exactly 3 ASCII characters, must be valid ISO639.2/T language code
- BOOL GetGlobalLanguageEncoding(EncodedString& out) const;
- BOOL SetGlobalLanguageEncoding(const EncodedString& val);
-
- BOOL GetTitle(EncodedString& out) const;
- BOOL SetTitle(const EncodedString& val);
-
- BOOL GetAuthor(EncodedString& out) const;
- BOOL SetAuthor(const EncodedString& val);
-
- BOOL GetCopyright(EncodedString& out) const;
- BOOL SetCopyright(const EncodedString& val);
-
- BOOL GetDescription(EncodedString& out) const;
- BOOL SetDescription(const EncodedString& val);
-
- BOOL GetPerformer(EncodedString& out) const;
- BOOL SetPerformer(const EncodedString& val);
-
- BOOL GetGenre(EncodedString& out) const;
- BOOL SetGenre(const EncodedString& val);
-
- // Max 4 ASCII characters
- BOOL GetRatingEntity(EncodedString& out) const;
- BOOL SetRatingEntity(const EncodedString& val);
-
- // Max 4 ASCII characters
- BOOL GetRatingCriteria(EncodedString& out) const;
- BOOL SetRatingCriteria(const EncodedString& val);
-
- BOOL GetRatingInfo(EncodedString& out) const;
- BOOL SetRatingInfo(const EncodedString& val);
-
- // Max 4 ASCII characters
- BOOL GetClassificationEntity(EncodedString& out) const;
- BOOL SetClassificationEntity(const EncodedString& val);
-
- BOOL GetClassificationTable(UINT16& out) const;
- BOOL SetClassificationTable(UINT16 val, BOOL bValid=TRUE);
-
- BOOL GetClassificationInfo(EncodedString& out) const;
- BOOL SetClassificationInfo(const EncodedString& val);
-
- UINT32 GetKeywordCount() const;
-
- // Returns FALSE if <index> is out of range.
- BOOL GetKeyword(UINT32 index, EncodedString& out) const;
- void ClearKeywords();
-
- // Returns FALSE if the byte-length of <val> is greater than 255 (maximum allowed by 3GPP).
- // Also, maximum number of keywords that can be written to 3GPP file is 255 (this method
- // does not check this to allow easier addition/removal, so this should be checked after
- // changes by calling GetKeywordCount and taking appropriate actions).
- BOOL AddKeyword(const EncodedString& val);
- void RemoveKeyword(const EncodedString& val);
- void RemoveKeywordDuplicates();
-
- BOOL GetLocationName(EncodedString& out) const;
- BOOL SetLocationName(const EncodedString& val);
-
- BOOL GetLocationAstronomicalBody(EncodedString& out) const;
- BOOL SetLocationAstronomicalBody(const EncodedString& val);
-
- BOOL GetLocationAdditionalNotes(EncodedString& out) const;
- BOOL SetLocationAdditionalNotes(const EncodedString& val);
-
- BOOL GetLocationRole(UINT8& out) const;
- BOOL SetLocationRole(UINT8 val, BOOL bValid=TRUE);
-
- BOOL GetLocationLongitude(EncodedString& out) const;
- BOOL SetLocationLongitude(const EncodedString& val);
-
- BOOL GetLocationLatitude(EncodedString& out) const;
- BOOL SetLocationLatitude(const EncodedString& val);
-
- BOOL GetLocationAltitude(EncodedString& out) const;
- BOOL SetLocationAltitude(const EncodedString& val);
-
- BOOL GetAlbumTitle(EncodedString& out) const;
- BOOL SetAlbumTitle(const EncodedString& val);
-
- BOOL GetAlbumTrackNumber(UINT8& out) const;
- BOOL SetAlbumTrackNumber(UINT8 val, BOOL bValid=TRUE);
-
- BOOL GetRecordingYear(UINT16& out) const;
- BOOL SetRecordingYear(UINT16 val, BOOL bValid=TRUE);
-
-private:
- static BOOL GetString(const EncodedString& src, EncodedString& out);
- static BOOL SetString(EncodedString& dst, const EncodedString& val);
- static BOOL SetStringAsciiMaxLen(EncodedString& dst, const EncodedString& val, UINT32 maxLen);
- static BOOL SetStringFixedPointNum(EncodedString& dst, const EncodedString& val);
- static BOOL GetUINT16(const UINT16& src, const BOOL& srcValid, UINT16& out);
- static BOOL SetUINT16(UINT16& dst, BOOL& dstValid, UINT16 val, BOOL bValid);
- static BOOL GetUINT8(const UINT8& src, const BOOL& srcValid, UINT8& out);
- static BOOL SetUINT8(UINT8& dst, BOOL& dstValid, UINT8 val, BOOL bValid);
- static void Update(EncodedString& dst, const EncodedString& src);
- static void Update(UINT16& dst, BOOL& dstValid, const UINT16& src, const BOOL& srcValid);
- static void Update(UINT8& dst, BOOL& dstValid, const UINT8& src, const BOOL& srcValid);
- static void Dump(const char* propName, const EncodedString& val);
- static void Dump(const char* propName, const UINT16& val, const BOOL& bValid);
- static void Dump(const char* propName, const UINT8& val, const BOOL& bValid);
- static void ClearPropertyStringArray(CHXPtrArray& aStrings);
-
- void CopyString(MetaInfo3GP::FnStringSetter setter, IHXValues* pValues, const char* enginePropName);
- void CopyULONG32(MetaInfo3GP::FnUINT16Setter setter, IHXValues* pValues, const char* enginePropName);
- void CopyULONG32(MetaInfo3GP::FnUINT8Setter setter, IHXValues* pValues, const char* enginePropName);
-
- void CopyString(IHXValues* pValues, const char* enginePropName, MetaInfo3GP::FnStringGetter getter) const;
- void CopyULONG32(IHXValues* pValues, const char* enginePropName, MetaInfo3GP::FnUINT16Getter getter) const;
- void CopyULONG32(IHXValues* pValues, const char* enginePropName, MetaInfo3GP::FnUINT8Getter getter) const;
-
-private:
- EncodedString m_sGlobalLanguageEncoding;
- EncodedString m_sTitle;
- EncodedString m_sAuthor;
- EncodedString m_sCopyright;
- EncodedString m_sDescription;
- EncodedString m_sPerformer;
- EncodedString m_sGenre;
- EncodedString m_sRatingEntity;
- EncodedString m_sRatingCriteria;
- EncodedString m_sRatingInfo;
- EncodedString m_sClassificationEntity;
- BOOL m_bValidClassificationTable;
- UINT16 m_uClassificationTable;
- EncodedString m_sClassificationInfo;
- CHXPtrArray m_aKeywords;
- EncodedString m_sLocationName;
- EncodedString m_sLocationAstronomicalBody;
- EncodedString m_sLocationAdditionalNotes;
- BOOL m_bValidLocationRole;
- UINT8 m_uLocationRole;
- EncodedString m_sLocationLongitude;
- EncodedString m_sLocationLatitude;
- EncodedString m_sLocationAltitude;
- EncodedString m_sAlbumTitle;
- BOOL m_bValidAlbumTrackNumber;
- UINT8 m_uAlbumTrackNumber;
- BOOL m_bValidRecordingYear;
- UINT16 m_uRecordingYear;
-};
-
-#endif // _METAUTIL3GP_H_
-
helix.bif.diff
(text/x-patch, 8.6 KB)
Index: helix.bif
===================================================================
RCS file: /cvsroot/common/build/BIF/helix.bif,v
retrieving revision 1.771
diff -w -B -b -U20 -r1.771 helix.bif
--- helix.bif 15 Oct 2009 17:28:19 -0000 1.771
+++ helix.bif 19 Oct 2009 13:37:02 -0000
@@ -2182,40 +2182,41 @@
common_dbgtool
common_container
common_util
</source_dependlist>
</module>
<!-- DATATYPE/COMMON/UTIL -->
<module id="datatype_common_util" name="datatype/common/util" group="core">
<cvs root="helix"/>
<includeplatforms>
unix mac win32 symbian openwave tm1 wince brew
</includeplatforms>
<source_dependlist>
common_include
common_container
common_util
common_system
common_dbgtool
common_runtime
+ datatype_include
</source_dependlist>
</module>
<!-- DATATYPE/COMMON/AUDREND -->
<module id="datatype_common_audrend" name="datatype/common/audrend" group="core">
<cvs root="helix"/>
<includeplatforms>
unix mac win32 symbian openwave wince brew
</includeplatforms>
<excludeprofiles>
helix-client-local-net-ra
helix-client-local-ra
helix-client-net-ra
helix-client-local-net-ra-mp3
helix-client-local-mp3
helix-client-local-ra-mp3
helix-client-local-ra-rv-mp3
helix-client-mobile-local-net-ra-rv-mp3
</excludeprofiles>
@@ -2495,136 +2496,145 @@
client_common_netio
client_medpltfm
client_netwksvc
</source_dependlist>
</module>
<!-- DATATYPE/TOOLS/DTDRIVER/INCLUDE -->
<module id="datatype_tools_dtdriver_include" name="datatype/tools/dtdriver/include" group="core">
<attribute id="no_build"/>
</module>
<!-- DATATYPE/TOOLS/DTDRIVER/COMMON -->
<module id="datatype_tools_dtdriver_common" name="datatype/tools/dtdriver/common" group="core">
<includeplatforms>
unix mac win32 symbian openwave wince
</includeplatforms>
<source_dependlist>
common_include
common_runtime
+ common_container
+ common_dbgtool
+ common_util
+ datatype_include
</source_dependlist>
</module>
<!-- DATATYPE/TOOLS/DTDRIVER/DECODER/COMMON -->
<module id="datatype_tools_dtdriver_decoder_common" name="datatype/tools/dtdriver/decoder/common" group="core">
<includeplatforms>
unix mac win32 symbian openwave wince
</includeplatforms>
<source_dependlist>
common_include
common_util
common_runtime
common_container
datatype_rm_video_payload_depacker
datatype_tools_dtdriver_include
datatype_tools_dtdriver_engine
datatype_tools_dtdriver_decoder_audio
datatype_tools_dtdriver_decoder_video
</source_dependlist>
</module>
<!-- DATATYPE/TOOLS/DTDRIVER/DECODER/AUDIO -->
<module id="datatype_tools_dtdriver_decoder_audio" name="datatype/tools/dtdriver/decoder/audio" group="core">
<includeplatforms>
unix mac win32 symbian openwave wince
</includeplatforms>
<source_dependlist>
common_include
common_util
common_runtime
common_dbgtool
common_container
common_system
+ datatype_include
+ datatype_common_util
datatype_common_container
datatype_tools_dtdriver_common
datatype_tools_dtdriver_engine
datatype_tools_dtdriver_decoder_common
client_common_container
protocol_transport_rtp_include
</source_dependlist>
</module>
<!-- DATATYPE/TOOLS/DTDRIVER/DECODER/VIDEO -->
<module id="datatype_tools_dtdriver_decoder_video" name="datatype/tools/dtdriver/decoder/video" group="core">
<includeplatforms>
unix mac win32 symbian openwave wince
</includeplatforms>
<defines>
HELIX_FEATURE_VIDREND_UNTIMED_DECODE
</defines>
<source_dependlist>
common_include
common_util
common_runtime
common_dbgtool
common_container
common_system
client_common_container
datatype_rm_video_payload_depacker
+ datatype_include
datatype_common_util
protocol_transport_rtp_include
common_log_logutil
</source_dependlist>
</module>
<!-- DATATYPE/TOOLS/DTDRIVER/DECODER -->
<module id="datatype_tools_dtdriver_decoder" name="datatype/tools/dtdriver/decoder" group="core">
<attribute id="no_build"/>
<dependlist>
datatype_tools_dtdriver_decoder_common
datatype_tools_dtdriver_decoder_audio
datatype_tools_dtdriver_decoder_video
</dependlist>
</module>
<!-- DATATYPE/TOOLS/DTDRIVER/ENGINE -->
<module id="datatype_tools_dtdriver_engine" name="datatype/tools/dtdriver/engine" group="core">
<includeplatforms>
unix mac win32 symbian openwave wince brew
</includeplatforms>
<source_dependlist>
common_include
client_include
datatype_include
datatype_rm_include
common_log_logutil
video_include
common_util
common_runtime
common_dbgtool
common_container
common_system
+ datatype_include
+ datatype_common_util
datatype_tools_dtdriver_include
datatype_tools_dtdriver_decoder
datatype_tools_minicntx
client_encodesvc_include
client_encodesvc_common_include
client_encodesvc_common_util
client_encodesvc_common_system
client_encodesvc_engine_encsession
common_log_logobserverfile
datatype_tools_dtdriver_common
datatype_tools_dtdriver_decoder
datatype_common_filewriter
</source_dependlist>
</module>
<!-- DATATYPE/TOOLS/METADATAENGINE -->
<module id="datatype_tools_metadataeng" name="datatype/tools/metadataeng" group="core">
<includeplatforms>
unix mac win32 symbian openwave wince
</includeplatforms>
@@ -2652,68 +2662,75 @@
<module id="datatype_tools_metaeditor" name="datatype/tools/metaeditor" group="core">
<includeplatforms>
win32 unix
</includeplatforms>
<dependlist>
common_include
common_util
common_runtime
common_dbgtool
common_container
common_fileio
common_system
common_log_logutil
client_common_container
client_common_system
client_common_util
client_medpltfm
client_videosvc
datatype_include
+ datatype_common_util
datatype_tools_dtdriver_common
datatype_tools_dtdriver_engine
datatype_tools_dtdriver_dtdrplin
datatype_tools_minicntx
</dependlist>
</module>
<!-- DATATYPE/TOOLS/DTDRIVER/APPS/META3GP -->
<module id="datatype_tools_dtdriver_apps_meta3gp" name="datatype/tools/dtdriver/apps/meta3gp" group="core">
+ <defines>
+ HELIX_FEATURE_3GPP_METAINFO
+ HELIX_FEATURE_ITUNES_METAINFO
+ </defines>
+
<includeplatforms>
win32 unix
</includeplatforms>
<dependlist>
common_include
common_util
common_runtime
common_dbgtool
common_container
common_fileio
common_system
common_log_logutil
client_common_container
client_common_system
client_common_util
client_medpltfm
client_videosvc
datatype_include
+ datatype_common_util
datatype_tools_dtdriver_common
datatype_tools_dtdriver_engine
datatype_tools_dtdriver_dtdrplin
datatype_tools_minicntx
datatype_tools_metaeditor
filesystem_local
datatype_mp4_fileformat
datatype_mp4_filewriter
</dependlist>
</module>
<!-- DATATYPE/TOOLS/DTDRIVER/APPS/DTDRIVE -->
<module id="datatype_tools_dtdriver_apps_dtdrive" name="datatype/tools/dtdriver/apps/dtdrive" group="core">
<attribute id="has_version_file"/>
<includeplatforms>
unix win32 symbian openwave wince
</includeplatforms>