TSReader

Descriptor Decoding

Updated January 23, 2008

Introduction

Many MPEG, DVB, ATSC and DCII tables can contain descriptors which add to the information being sent on these tables. TSReader decodes almost all of these descriptors as shown below. Descriptors are decoded based on the network type that TSReader is currently processing. The following table explains how TSReader recognizes a network type:

MPEG-2 Transport Stream Always assumed.
DVB A PMT entry for program 0 pointing to PID 0x0010 or NIT traffic on PID 0x0010.
ATSC A TVCT or CVCT being carried on PID 0x1ffe.
DCII A PMT entry for program 0 pointing to PID 0x0ffe.

TSReader makes the decision about the network type the first time it sees one of the above conditions. We've seen a few (very few) networks carrying both DVB and ATSC tables so there's a special switch -D to force TSReader to operate in DVB mode on such networks.

The implications of the network type in TSReader alter the way in which descriptors are decoded. On DVB networks for example, descriptor tags have a value from 0x40 - 0x7f and anything above (0x80 - 0xff) are deemed user defined descriptors. On the other hand, DCII networks use descriptors from 0x80 - 0x90, so when TSReader is in DVB mode it'll decode descriptor 0x82 as a user-defined descriptor and output it in hex/ASCII. However, if TSReader is looking at a DCII network, descriptor 0x82 will be correctly decoded as a DCII frame-rate descriptor.

Descriptor List

Descriptor Tag Descriptor Usage Supported?
MPEG-2
0x02 Video Stream Y
0x03 Audio Stream Y
0x04 Hierarchy Y
0x05 Registration Y
0x06 Data Stream Alignment Y
0x07 Target Background Grid Y
0x08 Video Window Y
0x09 Conditional Access Y
0x0a ISO 639 Language Y
0x0b System Clock Y
0x0c Multiplex Buffer Utilization Y
0x0d Copyright Descriptor * 1
0x0e Maximum Bitrate Y
0x0f Private Data Indicator * 1
0x10 Smoothing Buffer Y
0x11 STD Y
0x12 IBP Y
DVB
0x40 Network Name * 2
0x41 Service List Y
0x42 Stuffing * 1
0x43 Satellite Delivery * 2
0x44 Cable Delivery * 2
0x45 VBI Data Y
0x46 VBI Teletext Y
0x47 Bouquet Name Y
0x48 Service Y
0x49 Country Availability Y
0x4a Linkage Y
0x4b NVOD Reference Y
0x4c Time Shifted Service Y
0x4d Short Event * 2
0x4e Extended Event * 2
0x4f Time Shifted Event Y
0x50 Component Y
0x51 Mosaic Y
0x52 Stream Indentifier * 1
0x53 Conditional Access Y
0x54 Content Y
0x55 Parental Rating Y
0x56 Teletext Y
0x57 Telephone Y
0x58 Local Time Offset Y
0x59 Subtitling Y
0x5a Terrestrial Delivery * 2
0x5b Multi Lingual Network Name Y
0x5c Multi Lingual Bouquet Name Y
0x5d Multi Lingual Service Name Y
0x5e Multi Lingual Component Name Y
0x5f Private Data Specifier Y
0x60 Service Move Y
0x61 Short Smoothing Buffer Y
0x62 Frequency List Y
0x63 Partial Transport Stream Y
0x64 Data Broadcast Y
0x65 CA Systen * 3
0x66 Data Broadcast ID Y
0x67 Transport Stream * 1
0x68 DSNG * 1
0x69 PDC Y
0x6a AC-3 Audio Y
0x6b Ancilliary Data Y
0x6c Cell List Y
0x6d Cell Frequency Link Y
0x6e Announcement Support Y
0x73 DTS Audio Y
0x83 Logical Channel Number Y
DCII
0x80 Stuffing * 1
0x81 AC-3 Audio Y
0x82 Frame Rate Y
0x83 Extended Video Y
0x84 Component Name Y
0x90 Frequency Spec
0x91 Modulation Parameters  
0x92 Transport Stream ID
0xc0 Banner Override  
ATSC
0x80 Stuffing * 1
0x81 AC-3 Audio Y
0x86 Caption Service Y
0x87 Content Advisory Y
0xa0 Extended Channel Name Y
0xa1 Service Location Y
0xa2 Time-Shifted Service Y
0xa3 Component Name Y

Others
0x91 Dish Network Compressed Short Event * 2
0x92 Dish Network Compressed Extended Event * 2

Notes

1 The descriptor has no defined value in the appropriate specification. For example the contents of the stuffing descriptor is user defined. In these cases, TSReader outputs the contents of the descriptor in hex and ASCII.
2 This descriptor is used internally by TSReader to tie various pieces of the transport stream together and therefore isn't handled the same way as other descriptors. It is decoded in context of the mux or network.
3 As per note 1, but this descriptor is from the DAVIC standard which isn't currently supported in TSReader.

User Defined Descriptor Decoding in TSReader Professional

TSReader Professional has the ability for users to decode private descriptors via a special entry point in a standard MD plugin called On_Descriptor_Decode. There's a sample MD plugin provided in the TSReader folder.

The On_Descriptor_Decode function is defined as:

BOOL On_Descriptor_Decode(BOOL fWantDescription, int nNetworkPID, BYTE * pDescriptor, char * szDecoded)

When fWantDescription is TRUE, TSReader is attempting to get the name of the descriptor and pDescriptor points to just the descriptor tag. Conversely, when fWantDescription is FALSE, TSReader passes the full descriptor including the tag and length and the returned value should be a textual decode of the descriptor.

Here's an example of decoding a user-defined descriptor that announces the day of the week (yes, a silly application but possible). This descriptor has this syntax:

Syntax No. of bits Identifier
day_of_week_descriptor(){    
 descriptor_tag 8 uimsbf (0xcd)
 descriptor_length 8 uimsbf
 day_of_week 8 uimsbf
}

day_of_week is 0 for Sunday, 1 for Monday and so on. So here's the code to handle decoding this descriptor in a plugin:

BOOL On_Descriptor_Decode(BOOL fWantDescription, int nNetworkPID, BYTE * pDescriptor, char * szDecoded)
{
	if (fWantDescription)
	{
		switch(*pDescriptor)
		{
		case 0xcd:
			lstrcpy(szDecoded, "Day of Week");
			return TRUE;
		}
	}
	else
	{
		switch(*pDescriptor)
		{
		case 0xcd:
			{
				char * szDayOfWeek = NULL;
				switch(pDescriptor[2])
				{
				case 0:
					szDayOfWeek = "Sunday";
					break;
				case 1:
					szDayOfWeek = "Monday";
					break;
				case 2:
					szDayOfWeek = "Tuesday";
					break;
				case 3:
					szDayOfWeek = "Wedensday";
					break;
				case 4:
					szDayOfWeek = "Thursday";
					break;
				case 5:
					szDayOfWeek = "Friday";
					break;
				case 6:
					szDayOfWeek = "Saturday";
					break;
				}
				if (szDayOfWeek != NULL)
					wsprintf(szDecoded, " Day of week: %s\r\n", szDayOfWeek);
				else
					wsprintf(szDecoded, " **Invalid day of week specified - value %02x **\r\n", pDescriptor[2]);
				return TRUE;
			}
		}
	}
	return FALSE;
}