📄 dabmot.cpp
字号:
/******************************************************************************\
* Technische Universitaet Darmstadt, Institut fuer Nachrichtentechnik
* Copyright (c) 2001
*
* Author(s):
* Volker Fischer, Doyle Richard
*
* Description:
* DAB MOT interface implementation
*
* 12/22/2003 Doyle Richard
* - Header extension decoding
*
******************************************************************************
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
\******************************************************************************/
#include "DABMOT.h"
/* Implementation *************************************************************/
/******************************************************************************\
* Encoder *
\******************************************************************************/
void CMOTDABEnc::SetMOTObject(CMOTObject& NewMOTObject)
{
int i;
CMOTObjectRaw MOTObjectRaw;
/* Get some necessary parameters of object */
const int iPicSizeBits = NewMOTObject.vecbRawData.Size();
const int iPicSizeBytes = iPicSizeBits / SIZEOF__BYTE;
const string strFileName = NewMOTObject.strName;
/* File name size is restricted (in this implementation) to 128 (2^7) bytes.
If file name is longer, cut it. TODO: better solution: set Ext flag in
"ContentName" header extension to allow larger file names */
int iFileNameSize = strFileName.size();
if (iFileNameSize > 128)
iFileNameSize = 128;
/* Copy actual raw data of object */
MOTObjectRaw.Body.vecbiData.Init(iPicSizeBits);
MOTObjectRaw.Body.vecbiData = NewMOTObject.vecbRawData;
/* Get content type and content sub type of object. We use the format string
to get these informations about the object */
int iContentType = 0; /* Set default value (general data) */
int iContentSubType = 0; /* Set default value (gif) */
/* Get ending string which declares the type of the file. Make lowercase */
// The following line is not working for Linux!!!! TODO!
#ifdef _WIN32
const string strFormat = _strlwr(_strdup(NewMOTObject.strFormat.c_str()));
#else
const string strFormat = NewMOTObject.strFormat;
#endif
/* gif: 0, image: 2 */
if (strFormat.compare("gif") == 0)
{
iContentType = 2;
iContentSubType = 0;
}
/* jfif: 1, image: 2. Possible endings: jpg, jpeg, jfif */
if ((strFormat.compare("jpg") == 0) ||
(strFormat.compare("jpeg") == 0) ||
(strFormat.compare("jfif") == 0))
{
iContentType = 2;
iContentSubType = 1;
}
/* bmp: 2, image: 2 */
if (strFormat.compare("bmp") == 0)
{
iContentType = 2;
iContentSubType = 2;
}
/* png: 3, image: 2 */
if (strFormat.compare("png") == 0)
{
iContentType = 2;
iContentSubType = 3;
}
/* Header --------------------------------------------------------------- */
/* Header size (including header extension) */
const int iHeaderSize = 7 /* Header core */ +
5 /* TriggerTime */ +
3 + iFileNameSize /* ContentName (header + actual name) */ +
2 /* VersionNumber */;
/* Allocate memory and reset bit access */
MOTObjectRaw.Header.vecbiData.Init(iHeaderSize * SIZEOF__BYTE);
MOTObjectRaw.Header.vecbiData.ResetBitAccess();
/* BodySize: This 28-bit field, coded as an unsigned binary number,
indicates the total size of the body in bytes */
MOTObjectRaw.Header.vecbiData.Enqueue((uint32_t) iPicSizeBytes, 28);
/* HeaderSize: This 13-bit field, coded as an unsigned binary number,
indicates the total size of the header in bytes */
MOTObjectRaw.Header.vecbiData.Enqueue((uint32_t) iHeaderSize, 13);
/* ContentType: This 6-bit field indicates the main category of the body's
content */
MOTObjectRaw.Header.vecbiData.Enqueue((uint32_t) iContentType, 6);
/* ContentSubType: This 9-bit field indicates the exact type of the body's
content depending on the value of the field ContentType */
MOTObjectRaw.Header.vecbiData.Enqueue((uint32_t) iContentSubType, 9);
/* Header extension ----------------------------------------------------- */
/* MOT Slideshow application: Only the MOT parameter ContentName is
mandatory and must be used for each slide object that will be handled by
the MOT decoder and the memory management of the Slide Show terminal */
/* TriggerTime: This parameter specifies the time for when the presentation
takes place. The TriggerTime activates the object according to its
ContentType. The value of the parameter field is coded in the UTC
format */
/* PLI (Parameter Length Indicator): This 2-bit field describes the total
length of the associated parameter. In this case:
1 0 total parameter length = 5 bytes; length of DataField is 4 bytes */
MOTObjectRaw.Header.vecbiData.Enqueue((uint32_t) 2, 2);
/* ParamId (Parameter Identifier): This 6-bit field identifies the
parameter. 1 0 1 (dec: 5) -> TriggerTime */
MOTObjectRaw.Header.vecbiData.Enqueue((uint32_t) 5, 6);
/* Validity flag = 0: "Now", MJD and UTC shall be ignored and be set to 0.
Set MJD and UTC to zero. UTC flag is also zero -> short form */
MOTObjectRaw.Header.vecbiData.Enqueue((uint32_t) 0, 32);
/* VersionNumber: If several versions of an object are transferred, this
parameter indicates its VersionNumber. The parameter value is coded as an
unsigned binary number, starting at 0 and being incremented by 1 modulo
256 each time the version changes. If the VersionNumber differs, the
content of the body was modified */
/* PLI
0 1 total parameter length = 2 bytes, length of DataField is 1 byte */
MOTObjectRaw.Header.vecbiData.Enqueue((uint32_t) 1, 2);
/* ParamId (Parameter Identifier): This 6-bit field identifies the
parameter. 1 1 0 (dec: 6) -> VersionNumber */
MOTObjectRaw.Header.vecbiData.Enqueue((uint32_t) 6, 6);
/* Version number data field */
MOTObjectRaw.Header.vecbiData.Enqueue((uint32_t) 0, 8);
/* ContentName: The DataField of this parameter starts with a one byte
field, comprising a 4-bit character set indicator (see table 3) and a
4-bit Rfa field. The following character field contains a unique name or
identifier for the object. The total number of characters is determined
by the DataFieldLength indicator minus one byte */
/* PLI
1 1 total parameter length depends on the DataFieldLength indicator */
MOTObjectRaw.Header.vecbiData.Enqueue((uint32_t) 3, 2);
/* ParamId (Parameter Identifier): This 6-bit field identifies the
parameter. 1 1 0 0 (dec: 12) -> ContentName */
MOTObjectRaw.Header.vecbiData.Enqueue((uint32_t) 12, 6);
/* Ext (ExtensionFlag): This 1-bit field specifies the length of the
DataFieldLength Indicator.
0: the total parameter length is derived from the next 7 bits */
MOTObjectRaw.Header.vecbiData.Enqueue((uint32_t) 0, 1);
/* DataFieldLength Indicator: This field specifies as an unsigned binary
number the length of the parameter's DataField in bytes. The length of
this field is either 7 or 15 bits, depending on the setting of the
ExtensionFlag */
MOTObjectRaw.Header.vecbiData.Enqueue((uint32_t) (1 /* header */ +
iFileNameSize /* actual data */), 7);
/* Character set indicator (0 0 0 0 complete EBU Latin based repertoire) */
MOTObjectRaw.Header.vecbiData.Enqueue((uint32_t) 0, 4);
/* Rfa 4 bits */
MOTObjectRaw.Header.vecbiData.Enqueue((uint32_t) 0, 4);
/* Character field */
for (i = 0; i < iFileNameSize; i++)
MOTObjectRaw.Header.vecbiData.Enqueue((uint32_t) strFileName[i], 8);
/* Generate segments ---------------------------------------------------- */
/* Header (header should not be partitioned! TODO) */
const int iPartiSizeHeader = 100; /* Bytes */ // TEST
PartitionUnits(MOTObjectRaw.Header.vecbiData, MOTObjSegments.vvbiHeader,
iPartiSizeHeader);
/* Body */
const int iPartiSizeBody = 100; /* Bytes */ // TEST
PartitionUnits(MOTObjectRaw.Body.vecbiData, MOTObjSegments.vvbiBody,
iPartiSizeBody);
}
void CMOTDABEnc::PartitionUnits(CVector<_BINARY>& vecbiSource,
CVector<CVector<_BINARY> >& vecbiDest,
const int iPartiSize)
{
int i, j;
int iActSegSize;
/* Divide the generated units in partitions */
const int iSourceSize = vecbiSource.Size() / SIZEOF__BYTE;
const int iNumSeg =
(int) ceil((_REAL) iSourceSize / iPartiSize); /* Bytes */
const int iSizeLastSeg = iSourceSize -
(int) floor((_REAL) iSourceSize / iPartiSize) * iPartiSize;
/* Init memory for destination vector, reset bit access of source */
vecbiDest.Init(iNumSeg);
vecbiSource.ResetBitAccess();
for (i = 0; i < iNumSeg; i++)
{
/* All segments except the last one must have the size
"iPartSizeHeader". If "iSizeLastSeg" is =, the source data size is
a multiple of the partitions size. In this case, all units have
the same size (-> "|| (iSizeLastSeg == 0)") */
if ((i < iNumSeg - 1) || (iSizeLastSeg == 0))
iActSegSize = iPartiSize;
else
iActSegSize = iSizeLastSeg;
/* Add segment data ------------------------------------------------- */
/* Header */
/* Allocate memory for body data and segment header bits (16) */
vecbiDest[i].Init(iActSegSize * SIZEOF__BYTE + 16);
vecbiDest[i].ResetBitAccess();
/* Segment header */
/* RepetitionCount: This 3-bit field indicates, as an unsigned
binary number, the remaining transmission repetitions for the
current object.
In our current implementation, no repetitions used. TODO */
vecbiDest[i].Enqueue((uint32_t) 0, 3);
/* SegmentSize: This 13-bit field, coded as an unsigned binary
number, indicates the size of the segment data field in bytes */
vecbiDest[i].Enqueue((uint32_t) iActSegSize, 13);
/* Body */
for (j = 0; j < iActSegSize * SIZEOF__BYTE; j++)
vecbiDest[i].Enqueue(vecbiSource.Separate(1), 1);
}
}
void CMOTDABEnc::GenMOTObj(CVector<_BINARY>& vecbiData,
CVector<_BINARY>& vecbiSeg, const _BOOLEAN bHeader,
const int iSegNum, const int iTranspID,
const _BOOLEAN bLastSeg)
{
int i;
CCRC CRCObject;
/* Standard settings for this implementation */
const _BOOLEAN bCRCUsed = TRUE; /* CRC */
const _BOOLEAN bSegFieldUsed = TRUE; /* segment field */
const _BOOLEAN bUsAccFieldUsed = TRUE; /* user access field */
const _BOOLEAN bTransIDFieldUsed = TRUE; /* transport ID field */
// TODO: Better solution!
/* Total length of object in bits */
int iTotLenMOTObj = 16 /* group header */;
if (bSegFieldUsed == TRUE)
iTotLenMOTObj += 16;
if (bUsAccFieldUsed == TRUE)
{
iTotLenMOTObj += 8;
if (bTransIDFieldUsed == TRUE)
iTotLenMOTObj += 16;
}
iTotLenMOTObj += vecbiSeg.Size();
if (bCRCUsed == TRUE)
iTotLenMOTObj += 16;
/* Init data vector */
vecbiData.Init(iTotLenMOTObj);
vecbiData.ResetBitAccess();
/* MSC data group header ------------------------------------------------ */
/* Extension flag: this 1-bit flag shall indicate whether the extension
field is present, or not. Not used right now -> 0 */
vecbiData.Enqueue((uint32_t) 0, 1);
/* CRC flag: this 1-bit flag shall indicate whether there is a CRC at the
end of the MSC data group */
if (bCRCUsed == TRUE)
vecbiData.Enqueue((uint32_t) 1, 1);
else
vecbiData.Enqueue((uint32_t) 0, 1);
/* Segment flag: this 1-bit flag shall indicate whether the segment field is
present, or not */
if (bSegFieldUsed == TRUE)
vecbiData.Enqueue((uint32_t) 1, 1);
else
vecbiData.Enqueue((uint32_t) 0, 1);
/* User access flag: this 1-bit flag shall indicate whether the user access
field is present, or not. We always use this field -> 1 */
if (bUsAccFieldUsed == TRUE)
vecbiData.Enqueue((uint32_t) 1, 1);
else
vecbiData.Enqueue((uint32_t) 0, 1);
/* Data group type: this 4-bit field shall define the type of data carried
in the data group data field. Data group types:
3: MOT header information
4: MOT data */
if (bHeader == TRUE)
vecbiData.Enqueue((uint32_t) 3, 4);
else
vecbiData.Enqueue((uint32_t) 4, 4);
/* Continuity index: the binary value of this 4-bit field shall be
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -