⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tsdlg.cpp

📁 DVB的TS流解析
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// TSDlg.cpp : implementation file
//

#include "stdafx.h"
#include "TS.h"
#include "TSDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

CTSDlg* _this = NULL;
void log(CString strLog)
{
	if (_this) 
	{
		_this->AddLog(strLog);
	}
}

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTSDlg dialog

CTSDlg::CTSDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CTSDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CTSDlg)
	m_strLog = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CTSDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CTSDlg)
	DDX_Control(pDX, IDC_TREE, m_ctrlTree);
	DDX_Text(pDX, IDC_EDIT_LOG, m_strLog);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CTSDlg, CDialog)
	//{{AFX_MSG_MAP(CTSDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON_OPEN, OnButtonOpen)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTSDlg message handlers

BOOL CTSDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	_this = this;
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CTSDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CTSDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CTSDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

//////////////////////////////////////////////////////////////////////////
//TS packet header


/*
 *	Parse fields from stream "s" and evaluate to struct "d".
 */
#define EVALUATE(d, s)		TransData(&d, s, sizeof(d)); s += sizeof(d)

/*
 *	1. Define a struct entity "_STRUCT";
 *  2. evaluate to struct "_STRUCT" from stream "_STREAM";
 *  3. Move the stream to next position.
 */
#define INIT_STRUCT(_STRUCT, _STREAM)	_STRUCT; \
										TransData(&_STRUCT, _STREAM, sizeof(_STRUCT)); \
										_STREAM += sizeof(_STRUCT)
/*
 *	EQ: equar operator
 */
#define EQ ==

/*
 *	NIHILITY_PID set to an invalid value to drop all packets.
 */
#define NIHILITY_PID 0xFFFF

/*
 *	MAX_SERV_COUNT used in defining DB_service_list
 */
#define MAX_SERV_COUNT 512

struct TS_packet_header//defined in reverse order
{
	unsigned long continuity_counter 			:4 ;
	unsigned long adaptation_field_control 		:2 ;
	unsigned long transport_scrambling_control 	:2 ;
	unsigned long PID 							:13 ;
	unsigned long transport_priority 			:1 ;
	unsigned long payload_unit_start_indicator 	:1 ;
	unsigned long transport_error_indicator 	:1 ;
	unsigned long sync_byte 					:8 ;
};

/*
 *	If MAX_SERV_NAME_LENG is n, active max string length is (n - 1).
 */
#define MAX_SERV_NAME_LENG 32


/*
 *	Service Type
 */
enum ServType
{
	eST_Unkown = 0x00,
	eST_Radio,
	eST_Other,
	eST_TV
};

struct DB_service_data 
{
	unsigned long PID							:13;
	unsigned long b_scrambled					:1;
	unsigned long b_teletext					:1;
	unsigned long b_subtitle					:1;
	unsigned long program_number				:16;

	unsigned long PCR_PID						:13;
	unsigned long serv_type						:2;
	unsigned long reserved						:17;
	byte serv_name[MAX_SERV_NAME_LENG];
};

const byte				cnPktSize = 188;
const byte				cnSyncByte = 0x47;
const unsigned short	cnBuffSize = 376;
const int				cnCRC32Size = 4;

short					PID_Filter;
short					DC_PID_List[512];
short					DC_PID_count = 1;
short					DC_PID_index = 0;

DB_service_data			DB_service_list[MAX_SERV_COUNT];
int						DB_service_index = 0;
int						DB_service_count = 0;

void LogServList()
{
	CString s;
	log("-------------->>>---------------\r\nSID- PID  PCR  CA SUBT TTXT SName");
	for (int i = 0; i < DB_service_count; i ++) 
	{
		s.Format("%04X %04X %04X  %d   %d   %d  %s", 
				 DB_service_list[i].program_number, 
				 DB_service_list[i].PID, 
				 DB_service_list[i].PCR_PID,
				 DB_service_list[i].b_scrambled,
				 DB_service_list[i].b_teletext,
				 DB_service_list[i].b_subtitle,
				 DB_service_list[i].serv_name
				 );
		log(s);
	}
	log("--------------<<<---------------");
}

/*
 *	从码流赋值给结构体。pTarget指向的结构体必须按标准指定的倒序来定义。
 *  pStream指向用作解析的码流的首字节。nBytes标明pTarget的大小,也即是
 *  要从pStream取出多少个字节放到到pTarget中去,必须为1、2、或4的倍数。
 */
inline bool TransData(void * pTarget, const byte * pStream, int nBytes)
{
	if (nBytes <= 0) 
	{
		return false;
	}

	if (nBytes == 1 || nBytes == 2 || (nBytes % 4) == 0) 
	{
		for (int i = 0; i < nBytes; i ++)
		{
			*((byte*)(pTarget) + i) = *(pStream + (nBytes - i - 1));
		}
		return true;
	}
	else
	{
		return false;
	}
}


void descriptorDVB_NetName (byte* p_descriptor)
{	TRACE("descriptorDVB_NetName\n");
}
void descriptorDVB_ServList (byte* p_descriptor)
{	TRACE("descriptorDVB_ServList\n");
}
void descriptorDVB_Stuffing (byte* p_descriptor)
{	TRACE("descriptorDVB_Stuffing\n");
}
void descriptorDVB_SatDelivSys (byte* p_descriptor)
{	TRACE("SatDelivSys\n");
}
void descriptorDVB_CableDelivSys (byte* p_descriptor)
{	TRACE("CableDelivSys\n");
}
void descriptorDVB_VBI_Data (byte* p_descriptor)
{	TRACE("descriptorDVB_VBI_Data\n");
}
void descriptorDVB_VBI_Teletext (byte* p_descriptor)
{	TRACE("descriptorDVB_VBI_Teletext\n");
}
void descriptorDVB_BouquetName (byte* p_descriptor)
{	TRACE("descriptorDVB_BouquetName\n");
}

/*
 *	ETSI EN 300 468 V1.7.1 (2006-62 05) 6.2.32 Service descriptor
 */
void descriptorDVB_Service (byte* p_descriptor)
{
	struct _ 
	{
		unsigned __int32 service_provider_name_length:8;
		unsigned __int32 service_type :8;
		unsigned __int32 descriptor_length :8;
		unsigned __int32 descriptor_tag :8;
	}INIT_STRUCT(SVC_data, p_descriptor);

	//Ignore service_provider_name_length here
	p_descriptor += SVC_data.service_provider_name_length;

	byte service_name_length = *p_descriptor;
	p_descriptor += 1;

	if (DB_service_index < DB_service_count) 
	{
		if (service_name_length < MAX_SERV_NAME_LENG) 
		{
			memcpy(DB_service_list[DB_service_index].serv_name, p_descriptor, service_name_length);
			DB_service_list[DB_service_index].serv_name[service_name_length] = '\0';
		}
		else
		{
			memcpy(DB_service_list[DB_service_index].serv_name, p_descriptor, MAX_SERV_NAME_LENG - 1);
			DB_service_list[DB_service_index].serv_name[MAX_SERV_NAME_LENG - 1] = '\0';
		}

		switch(SVC_data.service_type) 
		{
		case 0x02:
		case 0x0A:
			DB_service_list[DB_service_index].serv_type = eST_Radio;
			break;
		case 0x01:
		case 0x11:
		case 0x16:
		case 0x19:
			DB_service_list[DB_service_index].serv_type = eST_TV;
			break;
		default:
			DB_service_list[DB_service_index].serv_type = eST_Other;
		}
	}
}
void descriptorDVB_CountryAvail (byte* p_descriptor)
{	TRACE("descriptorDVB_CountryAvail\n");
}
void descriptorDVB_Linkage (byte* p_descriptor)
{	TRACE("descriptorDVB_Linkage\n");
}
void descriptorDVB_NVOD_Reference (byte* p_descriptor)
{	TRACE("descriptorDVB_NVOD_Reference\n");
}
void descriptorDVB_TimeShiftedService (byte* p_descriptor)
{	TRACE("descriptorDVB_TimeShiftedService\n");
}
void descriptorDVB_ShortEvent (byte* p_descriptor)
{	TRACE("descriptorDVB_ShortEvent\n");
}
void descriptorDVB_ExtendedEvent (byte* p_descriptor)
{	TRACE("descriptorDVB_ExtendedEvent\n");
}
void descriptorDVB_TimeShiftedEvent(byte* p_descriptor)
{	TRACE("descriptorDVB_TimeShiftedEven\n");
}
void descriptorDVB_Component(byte* p_descriptor)
{	TRACE("Componen\n");
}
void descriptorDVB_Mosaic(byte* p_descriptor)
{	TRACE("descriptorDVB_Mosai\n");
}
void descriptorDVB_StreamIdent (byte* p_descriptor)
{	TRACE("descriptorDVB_StreamIdent\n");
}
void descriptorDVB_CAIdentifier (byte* p_descriptor)
{
	if (DB_service_index < DB_service_count)
	{
		DB_service_list[DB_service_index].b_scrambled = 0x01;
	}
}
void descriptorDVB_Content (byte* p_descriptor)
{	TRACE("descriptorDVB_Content\n");
}
void descriptorDVB_ParentalRating(byte* p_descriptor)
{	TRACE("descriptorDVB_ParentalRatin\n");
}

/*
 *	ETSI EN 300 468 V1.7.1 (2006-70 05) 6.2.42 Teletext descriptor
 */
void descriptorDVB_Teletext (byte* stream)
{
	if (DB_service_index < DB_service_count)
	{
		DB_service_list[DB_service_index].b_teletext = 0x01;
	}
	
	CString str;
	char lang[4] = {'\0'};
	int N = *(stream + 1) / 5;
	stream += 2;
	for (int i = 0; i < N; i++) 
	{
		memcpy(lang, stream, 3);
		str.Format("%d:%s", i, lang);
		log(str);
		stream += 5;
	}
}
void descriptorDVB_Telephone (byte* p_descriptor)
{	TRACE("descriptorDVB_Telephone\n");
}
void descriptorDVB_LocalTimeOffset (byte* p_descriptor)
{	TRACE("descriptorDVB_LocalTimeOffset\n");
}
void descriptorDVB_Subtitling (byte* p_descriptor)
{
	if (DB_service_index < DB_service_count)
	{
		DB_service_list[DB_service_index].b_subtitle = 0x01;
	}
}
void descriptorDVB_TerrestDelivSys (byte* p_descriptor)
{	TRACE("descriptorDVB_TerrestDelivSys\n");
}
void descriptorDVB_MultilingNetworkName (byte* p_descriptor)
{	TRACE("descriptorDVB_MultilingNetworkName\n");
}
void descriptorDVB_MultilingBouquetName (byte* p_descriptor)
{	TRACE("descriptorDVB_MultilingBouquetName\n");
}
void descriptorDVB_MultilingServiceName (byte* p_descriptor)
{	TRACE("descriptorDVB_MultilingServiceName\n");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -