📄 dvbsect.c
字号:
/*****************************************************************************
File name : dvbsect.c
Description: Functions for displaying DVBSI data
COPYRIGHT (C) STMicroelectronics 2004.
*****************************************************************************/
/* Includes --------------------------------------------------------------- */
#include <stdio.h>
#include <string.h>
#include "stddefs.h"
#include "stlite.h"
#include "stdevice.h"
#include "sttbx.h"
#include "errors.h"
#include "tuner.h"
#include "lists.h"
#include "dvb_si.h"
/* Global definitions ----------------------------------------------------- */
#define OUTPUT_HEADER 0
#define OUTPUT_BYTES 0
#define MAX_NAME_LEN 20
/* macro to limit the value y to a maximum of x in which case defaults to z */
#define LIMITED_TO_(x,y,z) (( y < x ) ? y : z )
#define DISPLAY(x) { if ( Display == TRUE ) { STTBX_Print(x); }}
/* Local Variables -------------------------------------------------------- */
/*
** Service Status types
*/
static char *StatusTypeNames[] = {
"Undefined",
"Stopped",
"Starts soon",
"Paused",
"Running" };
static char *ServiceTypeNames[] = {
"resvd",
"Digital TV",
"Digital Radio",
"Teletext",
"NVOD Ref",
"NVOD Time-shifted",
"Mosaic",
"PAL coded",
"SECAM coded",
"D/D2-MAC",
"FM Radio",
"NTSC coded" };
PAT_Data_t PAT_Data[MAX_PAT_DATA_SIZE];
DescriptorInfo_t Desc;
/*-------------------------------------------------------------------------
* Function : StreamTypeNameLookup
*
* Input : Stream type index
* Output :
* Return : pointer to Stream Name
* ----------------------------------------------------------------------*/
static char *StreamTypeNameLookup( U8 Index )
{
static char* StreamTypes[]=
{
"Reserved",
"VidMpeg1",
"VidMpeg2",
"AudMpeg1",
"AudMpeg2",
"PrivSect",
"PrivData",
"MHEG",
"DSM-CC",
"Other",
"type A",
"type B",
"type C",
"type D",
"type E",
"AudAAC"
};
if ( Index <= 0xf )
return StreamTypes[Index];
else if ( Index < 0x7f )
return StreamTypes[0];
else if ( Index == 0x81 ) /* AC3 */
return "AudAC3";
else
return "UserPriv";
}
/*-------------------------------------------------------------------------
* Function : GetDescriptorData
* Return pointer to data start of requested descriptor
* Input : U8 *Buff_p, U16 BuffSize, U8 DescriptorTag
* Output :
* Return : pointer to start of Descriptor Data or NULL if not found
* ----------------------------------------------------------------------*/
static U8 *GetDescriptorData( U8 *Buff_p, U16 BuffSize, U8 DescriptorTag )
{
U16 Length;
U8 *Desc_p;
U8 i,j;
memset( &Desc, 0, sizeof(Desc));
for( Length = 0, Desc_p = Buff_p; Length < BuffSize; )
{
if ( Length > BuffSize )
break;
Desc.Tag = Desc_p[0];
Desc.Length = Desc_p[1];
switch ( Desc_p[0] ) /* descriptor tag */
{
case ECM_DESCRIPTOR:
Desc.Info.ECMPid = extract(&Desc_p[4], PID_MASK);
break;
case SERVICE_DESCRIPTOR:
Desc.Info.Service.Type = Desc_p[2];
Desc.Info.Service.ProviderLen = Desc_p[3];
Desc.Info.Service.ProviderName_p = (char*) &Desc_p[4];
Desc.Info.Service.ServiceLen = Desc_p[4 + Desc.Info.Service.ProviderLen];
Desc.Info.Service.ServiceName_p = (char*) &Desc_p[5 + Desc.Info.Service.ProviderLen];
break;
case SHORT_EVENT_DESCRIPTOR:
memset( Desc.Info.ShortEvent.Language, 0, 4 );
memcpy( Desc.Info.ShortEvent.Language, (char*) Desc_p[2], 3);
Desc.Info.ShortEvent.NameLen = Desc_p[5];
Desc.Info.ShortEvent.Name_p = (char*) &Desc_p[6];
Desc.Info.ShortEvent.TextLen = Desc_p[6+Desc.Info.ShortEvent.NameLen];
Desc.Info.ShortEvent.Text_p = (char*) &Desc_p[7+Desc.Info.ShortEvent.NameLen];
break;
case SUBTITLING_DESCRIPTOR:
memset( Desc.Info.Subtitle.Language, 0, 4 );
memcpy( Desc.Info.Subtitle.Language, (char*) Desc_p[2], 3);
Desc.Info.Subtitle.Type = Desc_p[5];
Desc.Info.Subtitle.CompositionId = (Desc_p[6] << 8) + Desc_p[7];
Desc.Info.Subtitle.AnciliaryId = Desc_p[8] * 256 + Desc_p[9];
break;
case TELETEXT_DESCRIPTOR:
for ( i = 2, j = 0; (i < Desc_p[1]) && (j < 2); i+=5, j++ )
{
memset( Desc.Info.Teletext[j].Language, 0, 4 );
memcpy( Desc.Info.Teletext[j].Language, (char*) Desc_p[i], 3);
Desc.Info.Teletext[j].Type = ( Desc_p[i+3] >> 3 ) & 0x1f;
Desc.Info.Teletext[j].Magazine = Desc_p[i+3] & 0x7;
Desc.Info.Teletext[j].Page = Desc_p[i+4];
}
break;
default:
break;
}
if ( Desc_p[0] == DescriptorTag )
return Desc_p; /* return pointer to data */
Length += 2 + Desc_p[1];
Desc_p += 2 + Desc_p[1];
}
return NULL;
} /* end GetDescriptorData */
/*-------------------------------------------------------------------------
* Function : MJD2YMD
* : Modified Julian Date to Year/Month/Day
* Input : MJD
* Output : Year, Month, Day
* Return : None
* ----------------------------------------------------------------------*/
#if 0 // EXT_SHARE
void MJD2YMD( U16 MJD, U16 *Year, U16 *Month, U16 *Day )
{
U8 K;
*Year = (int)((MJD - 15078.2)/365.25);
*Month = (int)((MJD - 14956.1 - (*Year *365.25))/30.6001);
*Day = MJD - 14956 - (int)(*Year * 365.25) - (int)(*Month * 30.6001);
if (( *Month == 14 ) || ( *Month == 15 ))
K = 1;
else
K = 0;
*Year += K;
*Month = *Month - 1 - K * 12;
}
#endif
/*-------------------------------------------------------------------------
* Function : DVB_HeaderExtract
*
* Input :
* Output :
* Return : None
* ----------------------------------------------------------------------*/
void DVB_HeaderExtract( U8 *Data_p, SECTION_Header_t *Header_p )
{
/* extract the general data */
Header_p->TableId = Data_p[0];
Header_p->Indicators = Data_p[1] & 0x0f;
Header_p->SectionLength = 3 + extract(&Data_p[1], LENGTH_MASK);
Header_p->StreamId = extract(&Data_p[3], PROG_MASK);
Header_p->VersionNumber = GET_VERSION_NUMBER(Data_p[5]);
Header_p->CurrentNext = Data_p[5] & CURRENT_NEXT_INDICATOR_MASK;
Header_p->SectionNumber = Data_p[6];
Header_p->LastSectionNumber = Data_p[7];
#if OUTPUT_HEADER
STTBX_Print(("Table id = %d\t", Header_p->TableId ));
STTBX_Print(("Indicators = %d\t", Header_p->Indicators ));
STTBX_Print(("Section Len = %d\t", Header_p->SectionLength ));
STTBX_Print(("Stream Id = %d\n", Header_p->StreamId ));
STTBX_Print(("Version num = %d\t", Header_p->VersionNumber ));
STTBX_Print(("CurrNext Ind = %s\t", Header_p->CurrentNext ? "CURR":"NEXT" ));
STTBX_Print(("Section Num = %d\t", Header_p->SectionNumber ));
STTBX_Print(("LastSect Num = %d\n", Header_p->LastSectionNumber ));
#endif
#if OUTPUT_BYTES
STTBX_Print(("Data %02x %02x %02x %02x %02x %02x %02x %02x (%02x %5d)\n",
Data_p[0], Data_p[3], Data_p[4], Data_p[5],
Data_p[6], Data_p[7], Data_p[8], Data_p[9],
Header_p->SectionLength, Header_p->SectionLength ));
#endif
}
/*-------------------------------------------------------------------------
* Function : DVB_BufferDecode
* Input :
* Output :
* Return : Error code
* ----------------------------------------------------------------------*/
void DVB_BufferDecode( U8 *Buffer_p, BOOL Display )
{
SECTION_Header_t Header;
U16 i, j, k;
U16 DescLoopLength;
/* Header_p->syntax_indicator
1 = normal header,
0 = private_data_bytes follow section_length field
*/
DVB_HeaderExtract(Buffer_p, &Header);
switch ( Header.TableId )
{
case PAT_TABLE_ID: /* Program Association Table */
{
memset(PAT_Data, 0, sizeof(PAT_Data)); /* clear old data */
DISPLAY(("---- PAT - Transport Id %5d ----\n", Header.StreamId ));
DISPLAY(("Program PMT Pid\n"));
DISPLAY(("------- -------\n"));
for ( i = PAT_HEAD_SIZE, j = 1;
i < (Header.SectionLength - CRC_SIZE);
i += PAT_DATA_SIZE )
{
U16 PgmPid, PmtPid;
PgmPid = extract(&Buffer_p[i], PROG_MASK);
PmtPid = extract(&Buffer_p[i+2], PID_MASK);
if ( PgmPid == 0) /*program pid 0 points NIT table*/
{
PAT_Data[0].PmtPid = PmtPid;
}
else if ( j < MAX_PAT_DATA_SIZE)
{
PAT_Data[j].PgmPid = PgmPid;
PAT_Data[j].PmtPid = PmtPid;
j++;
}
DISPLAY(("%7d %7d %s\n",
PgmPid, PmtPid,
PgmPid==0?"NwID":""));
}
NumPrograms = j--;
}
break;
case PMT_TABLE_ID: /* Program Map Table */
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -