In the interactive TV world, simple transmission of data from the broadcaster to a receiver is handled using DSM-CC data carousels. A data carousel consists of a number of modules, where each module contains one item of data such as a file. This module may in turn be split into blocks to make it easier to broadcast, but there is no higher-level structure above the module level.
Let’s assume that we have two modules. Module A is small, and can fit inside a single block, while, module B is slightly bigger and needs two blocks to hold all of its data. A simple data carousel would first transmit the block containing module A, then the block containing the first part of module B, then the block containing the second part of module B, and then start again by broadcasting the block containing module A.
This seems simple enough, but how does the receiver know when module A ends and module B starts?
Elements of a DSM-CC carousel are contained in a set of DSM-CC messages. These fall in to two basic categories: DSM-CC download data messages contain the actual data belonging to the modules in the carousel, while DSM-CC download control messages tell the receiver how the download data messages are organised into modules.
Download Data messages
There is only one type of download data message – the DownloadDataBlock message. As the name suggests, each DownloadDataBlock message corresponds to one block of data that is broadcast as a single unit. Each DownloadDataBlock is also the same size, except for the last block in each module – this makes it easier for the receiver to parse the messages.
Each DownloadDataBlock message contains the ID and version number of the module it is part of, the block number within that module and the data itself. The module ID and version number let the receiver know whether it should pay attention to this message (since the receiver will know which modules it should load, and whether the block refers to a current version of the module or an old one), while the block number tells the receiver what part of the module is contained in that block.
Syntax | No. of bytes |
---|---|
DownloadDataBlock () { | |
dsmccDownloadDataHeader() | |
moduleId | 2 |
moduleVersion | 1 |
reserved | 8 bits |
blockNumber | 16 bits |
for (i=0; i < N; i++) { | |
blockDataByte | 1 |
} | |
} |
As you can see from the tables above, each DownloadDataBlock message begins with a downloadDataHeader structure This structure has the following format:
Syntax | No. of bytes |
---|---|
dsmccDownloadDataHeader { | |
protocolDiscriminator | 1 |
dsmccType | 1 |
messageId | 2 |
downloadId | 4 |
reserved | 1 |
adaptationLength | 1 |
messageLength | 2 |
if (adaptationLength > 0) { | |
dsmccAdaptationHeader () | |
} | |
} |
Some fields in the DSMCC download data header have fixed values. These are shown below.
Field | Value |
---|---|
protocolDiscriminator |
0x11 |
dsmccType |
0x03 |
reserved |
0xFF |
Download Control messages
Now that we’ve seen how data is carried in a carousel, we need to see how the blocks that carry that data are organised in to a sensible structure. The structure of a module is defined by one or more download control messages.
As we have already seen, small modules may fit into a single block, while larger modules may need more than one block. In the latter case, and in the case where there is more than one module in the carousel, some extra control information is needed to describe how the blocks are grouped into modules. This is done using the first type of download control message, known as a DownloadInfoIndication message.
DownloadInfoIndication Messages
Each DownloadInfoIndication (DII) message contains a description of a number of modules and of the parameters that are used to transmit them. Any modules that are listed in the same DII message are said to be members of the same group. This provides a way for broadcasters to identify modules that belong together, for instance because they all carry different parts of a single block of data.
The DII message gives the size of the DownloadDataBlock messages that are used to transmit the module data, and for each module that it describes it gives the ID of the module, its version and its size, as well as a number of descriptors that may give a more detailed description of the module. By knowing the size of a module and the size of each DownloadDataBlock message, the receiver can calculate how many blocks will be used to transmit each module. This lets the receiver make sure that it has all of the data it needs when reading a module. The version number lets the receiver see when the contents of a given module have changed, and tell the receiver to replace any versions of that module that it may have cached.
Syntax | No. of bytes |
---|---|
DownloadInfoIndication () { | |
dsmccMessageHeader() | |
downloadId | 32 bits |
blockSize | 16 bits |
windowSize | 8 bits (0x00) |
ackPeriod | 8 bits (0x00) |
tCDownloadWindow | 32 bits (0x00) |
tCDownloadScenario | 32 bits |
compatibilityDescriptor | |
numberOfModules | 16 bits |
for (i = 0; i < numberOfModules; i++) { | |
moduleId | 16 bits |
moduleSize | 32 bits |
moduleVersion | 8 bits |
moduleInfoLength | 8 bits |
for (j = 0; j < moduleInfoLength; j++) { | |
moduleInfoByte | depends on module info length |
} | |
} | |
privateDataLength | 16 bits |
for (k = 0; k < privateDataLength; k++) { | |
privateDataByte | depends on private data length |
} | |
} |
Some of the values for these fields are fixed by DVB. These are shown in the following table:
Field | Value |
---|---|
windowSize |
0x00 |
ackPeriod |
0x00 |
tcDownloadWindow |
0x00 |
For data carousels that are carrying object carousels, the moduleInfoByte
field will contain a ModuleInfo structure that describes the structure of the blocks within the module. Like DownloadDataBlock messages, every DII message begins with a header structure. The dsmccMessageHeader has the following format:
Syntax | No. of bytes |
---|---|
dsmccMessageHeader () { | |
protocolDiscriminator | 1 |
dsmccType | 1 |
messageId | 2 |
transactionId | 4 |
reserved | 1 |
adaptationLength | 1 |
messageLength | 2 |
if (adaptation length > 0) { | |
dsmccAdaptationHeader () | |
} | |
} |
As with the download data header, a number of these fields will have fixed values. These are the same in both cases, and details of these fields are given above.
DownloadServerInitiate messages and two-layer carousels
One limitation that MPEG imposes on DSM-CC concerns the size of the messages. Each DSM-CC message is limited to a total size of 4K, which can cause problems for DII messages. In particular, it means that a DII message can only describe up to around 150 modules. For small carousels, this is not a problem. Carousels which only use a single DII message are called one-layer carousels.
For bigger carousels (and also in other scenarios that we’ll see later), this means that more than one DII message is needed to describe all of the modules. Unfortunately, DSM-CC only allows a carousel to have a single top-level download control message. If a carousel has more than one DII message, which one of them is the top level one? Actually, none of them is – that privilege goes to the DownloadServerInitiate message.
The DownloadServerInitiate (DSI) message acts as a top-level control message for those carousels which have several DII messages. It groups together a number of DII messages, and the groups of modules associated with them, into a single supergroup.
Carousels where a number of DII message are linked to a supergroup by a DSI message are called two-layer carousels.
Syntax | No. of bytes |
---|---|
DownloadServerInitiate () { |
|
dsmccMessageHeader () | |
serverId | 20 |
compatibilityDescriptor () |
|
privateDataLength | 2 |
for (i = 0; i < privateDataLength; i++) { | |
privateDataByte | 1 |
} | |
} |
In DVB systems, the private data bytes will in most cases contain a GroupInfoIndication structure as shown below:
Syntax | No. of bytes |
---|---|
GroupInfoIndication { | |
NumberOfGroups | 2 |
for (i=0; i < NumberOfGroups; i++) { | |
GroupId | 4 |
GroupSize | 4 |
GroupCompatibility() | |
GroupInfoLength | 2 |
for (i=0; i < GroupInfoLength; i++) { | |
GroupInfoByte | 1 |
} | |
} | |
PrivateDataLength | 2 |
for (i=0; i < PrivateDataLength; i++) { | |
PrivateDataByte | 1 |
} | |
} |
For data carousels that are carrying object carousels, the private data bytes will contain a ServiceGatewayInfo structure instead. This identifies the DSI message that describes the service gateway for the object carousel, and enables the receiver to find all of the necessary DSI messages more efficiently.
Groups and supergroups
We have already seen that all modules that are listed in the same DII message are said to be members of the same group (which includes the DII message itself); and that a DSI message, any DII messages that it refers to and their associated modules are members of the same supergroup. But how do we tell which group and supergroup contains a given module?
Identifying the members of a given group is easy – each DII message contains a list of the module IDs that identify the modules associated with that group. Each DownloadDataBlock message that is a member of a given module also contains that module ID.
Identifying the supergroup that contains a given group is equally easy. The downloadId
field of every DII and DownloadDataBlock message within the supergroup is set to the same value. We also get some more help from the DSI message to identify the DII messages that make up a supergroup. The GroupInfoByte
field of the GroupInfoIndication structure in a DSI contains a set of descriptors that describe how the DSI is linked to the DII messages that are part of its supergroup. The most important of these descriptors from our perspective is the group link descriptor. This identifies a DII message that is part of the supergroup described by this DSI message:
Syntax | No. of bytes | Value |
---|---|---|
group_link_descriptor { | ||
descriptor_tag | 1 | 0x08 |
descriptor_length | 1 | |
position | 1 | |
group_id | 4 | |
} |
Each group link descriptor identifies one DII message that is linked to this DSI, and so a DSI message will typically contain several group link descriptors. The group_id
field contains the transaction ID of the DII, while the position
field identifies where that descriptor comes in the list. A value of 0x00 indicates that a descriptor is the first one in the list of DIIs, a value of 0x01 indicates that the descriptor is in the middle of the list and a value of 0x02 indicates that the descriptor is the last one in the list. Any other values in the position
field mean that the descriptor should be ignored.