New CPat class to parse PAT, replace old code

This commit is contained in:
[CST] Focus
2012-01-13 13:55:52 +04:00
parent c79fe413d6
commit c242a61ea2
2 changed files with 87 additions and 120 deletions

View File

@@ -1,12 +1,13 @@
/* /*
* $Id: pat.h,v 1.18 2003/01/30 17:21:16 obi Exp $ * Neutrino-GUI - DBoxII-Project
* *
* (C) 2002-2003 Andreas Oberritter <obi@tuxbox.org> * Copyright (C) 2011 CoolStream International Ltd
*
* License: GPLv2
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation;
* (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -22,11 +23,30 @@
#ifndef __zapit_pat_h__ #ifndef __zapit_pat_h__
#define __zapit_pat_h__ #define __zapit_pat_h__
#include "channel.h" #include <zapit/channel.h>
#include <dmx.h>
int parse_pat(CZapitChannel * const channel); #define PAT_SECTION_SIZE 1024
int scan_parse_pat( std::vector<std::pair<int,int> > &sidpmt );
int parse_pat(void); typedef std::map<int,int> sidpmt_map_t;
int pat_get_pmt_pid (CZapitChannel * const channel); typedef sidpmt_map_t::iterator sidpmt_map_iterator_t;
typedef std::pair<int,int> sidpmt_map_pair_t;
class CPat
{
private:
cDemux * dmx;
int dmxnum;
bool parsed;
sidpmt_map_t sidpmt;
public:
CPat(int dnum = 0);
~CPat();
void Reset();
bool Parse();
unsigned short GetPmtPid(t_service_id sid);
bool Parse(CZapitChannel * const channel);
};
#endif /* __zapit_pat_h__ */ #endif /* __zapit_pat_h__ */

View File

@@ -1,12 +1,13 @@
/* /*
* $Id: pat.cpp,v 1.44 2003/01/30 17:21:17 obi Exp $ * Neutrino-GUI - DBoxII-Project
* *
* (C) 2002 by Andreas Oberritter <obi@tuxbox.org> * Copyright (C) 2011 CoolStream International Ltd
*
* License: GPLv2
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation;
* (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -23,18 +24,34 @@
#include <zapit/pat.h> #include <zapit/pat.h>
#include <dmx.h> #include <dmx.h>
#define PAT_SIZE 1024 CPat::CPat(int dnum)
int parse_pat(CZapitChannel * const channel)
{ {
if (!channel) parsed = false;
return -1; dmxnum = dnum;
}
cDemux * dmx = new cDemux(); CPat::~CPat()
{
sidpmt.clear();
}
void CPat::Reset()
{
sidpmt.clear();
parsed = false;
}
bool CPat::Parse()
{
//INFO("parsed: %s", parsed ? "yes" : "no");
if(parsed)
return true;
dmx = new cDemux(dmxnum);
dmx->Open(DMX_PSI_CHANNEL); dmx->Open(DMX_PSI_CHANNEL);
/* buffer for program association table */ /* buffer for program association table */
unsigned char buffer[PAT_SIZE]; unsigned char buffer[PAT_SECTION_SIZE];
/* current positon in buffer */ /* current positon in buffer */
unsigned short i; unsigned short i;
@@ -51,113 +68,43 @@ int parse_pat(CZapitChannel * const channel)
do { do {
/* set filter for program association section */ /* set filter for program association section */
/* read section */ /* read section */
if ((dmx->sectionFilter(0, filter, mask, 5) < 0) || (i = dmx->Read(buffer, PAT_SIZE) < 0)) if ((dmx->sectionFilter(0, filter, mask, 5) < 0) || (i = dmx->Read(buffer, PAT_SECTION_SIZE) < 0))
{ {
delete dmx; delete dmx;
printf("[pat.cpp] dmx read failed\n"); printf("[pat.cpp] dmx read failed\n");
return -1; return false;
} }
if(buffer[7]) printf("[PAT] ***************************************************** section %X last %X\n", buffer[6], buffer[7]);
//printf("[pat.cpp] dmx read %d len %d\n", i, ( (buffer[1] & 0x0F) << 8) | buffer[2]);
/* loop over service id / program map table pid pairs */ /* loop over service id / program map table pid pairs */
for (i = 8; i < (((buffer[1] & 0x0F) << 8) | buffer[2]) + 3; i += 4) { for (i = 8; i < (((buffer[1] & 0x0F) << 8) | buffer[2]) + 3; i += 4) {
/* compare service id */
if (channel->getServiceId() == ((buffer[i] << 8) | buffer[i+1])) {
/* store program map table pid */
channel->setPmtPid(((buffer[i+2] & 0x1F) << 8) | buffer[i+3]);
delete dmx;
return 0;
}
}
} while (filter[4]++ != buffer[7]);
delete dmx;
printf("[pat.cpp] sid %X not found..\n", channel->getServiceId());
return -1;
}
int scan_parse_pat( std::vector<std::pair<int,int> > &sidpmt )
{
cDemux * dmx = new cDemux();
dmx->Open(DMX_PSI_CHANNEL);
/* buffer for program association table */
unsigned char buffer[PAT_SIZE];
/* current positon in buffer */
unsigned short i;
unsigned char filter[DMX_FILTER_SIZE];
unsigned char mask[DMX_FILTER_SIZE];
memset(filter, 0x00, DMX_FILTER_SIZE);
memset(mask, 0x00, DMX_FILTER_SIZE);
mask[0] = 0xFF;
mask[4] = 0xFF;
do {
/* set filter for program association section */
/* read section */
if ((dmx->sectionFilter(0, filter, mask, 5) < 0) || (i = dmx->Read(buffer, PAT_SIZE) < 0))
{
delete dmx;
printf("[%s] dmx read failed\n",__FILE__);
return -1;
}
dmx->Stop();
for (i = 8; i < (((buffer[1] & 0x0F) << 8) | buffer[2]) + 3; i += 4) {
int service_id = ((buffer[i] << 8) | buffer[i+1]);
if (service_id != 0)
sidpmt.push_back(std::make_pair( service_id , (((buffer[i+2] & 0x1F) << 8) | buffer[i+3]) ) );
}
} while (filter[4]++ != buffer[7]);
delete dmx;
return 1;
}
static unsigned char pbuffer[PAT_SIZE];
int parse_pat()
{
int ret = 0;
printf("[scan] Parsing pat ...\n");
cDemux * dmx = new cDemux();
dmx->Open(DMX_PSI_CHANNEL);
unsigned char filter[DMX_FILTER_SIZE];
unsigned char mask[DMX_FILTER_SIZE];
memset(filter, 0x00, DMX_FILTER_SIZE);
memset(mask, 0x00, DMX_FILTER_SIZE);
mask[0] = 0xFF;
mask[4] = 0xFF;
memset(pbuffer, 0x00, PAT_SIZE);
if ((dmx->sectionFilter(0, filter, mask, 5) < 0) || (dmx->Read(pbuffer, PAT_SIZE) < 0))
{
printf("[pat.cpp] dmx read failed\n");
ret = -1;
}
delete dmx;
return ret;
}
int pat_get_pmt_pid (CZapitChannel * const channel)
{
unsigned short i;
for (i = 8; i < (((pbuffer[1] & 0x0F) << 8) | pbuffer[2]) + 3; i += 4) {
/* compare service id */
if (channel->getServiceId() == ((pbuffer[i] << 8) | pbuffer[i+1])) {
/* store program map table pid */ /* store program map table pid */
channel->setPmtPid(((pbuffer[i+2] & 0x1F) << 8) | pbuffer[i+3]); int service_id = ((buffer[i] << 8) | buffer[i+1]);
return 0; int pmt_pid = (((buffer[i+2] & 0x1F) << 8) | buffer[i+3]);
sidpmt.insert(sidpmt_map_pair_t(service_id, pmt_pid));
} }
} } while (filter[4]++ != buffer[7]);
printf("[pat.cpp] sid %X not found..\n", channel->getServiceId()); parsed = true;
return -1; delete dmx;
return true;
} }
unsigned short CPat::GetPmtPid(t_service_id sid)
{
unsigned short pid = 0;
if(Parse()) {
sidpmt_map_iterator_t it = sidpmt.find(sid);
if(it != sidpmt.end())
pid = it->second;
}
return pid;
}
bool CPat::Parse(CZapitChannel * const channel)
{
unsigned short pid = GetPmtPid(channel->getServiceId());
if(pid > 0) {
channel->setPmtPid(pid);
return true;
}
return false;
}