zapit/src/fastscan.cpp: implement new/removed channel marking

This commit is contained in:
[CST] Focus
2014-04-08 15:18:45 +04:00
parent b925988afe
commit 241b8d7724
3 changed files with 79 additions and 74 deletions

View File

@@ -173,6 +173,7 @@ class CZapitChannel
UPDATED = 0x04, UPDATED = 0x04,
NOT_FOUND = 0x08, NOT_FOUND = 0x08,
PRESENT = 0x05, // NEW + UPDATED PRESENT = 0x05, // NEW + UPDATED
FASTSCAN = 0x10,
ANY = 0xFF ANY = 0xFF
} channel_flags_t; } channel_flags_t;
casys_map_t camap; casys_map_t camap;

View File

@@ -26,6 +26,7 @@
#include <inttypes.h> #include <inttypes.h>
#include <map> #include <map>
#include <list>
#include <string> #include <string>
#include <zapit/femanager.h> #include <zapit/femanager.h>
@@ -105,11 +106,13 @@ class CServiceScan : public OpenThreads::Thread
std::map <t_channel_id, t_satellite_position> fast_services_sat; std::map <t_channel_id, t_satellite_position> fast_services_sat;
std::map <t_channel_id, freq_id_t> fast_services_freq; std::map <t_channel_id, freq_id_t> fast_services_freq;
std::map <t_channel_id, int> fast_services_number; std::map <t_channel_id, int> fast_services_number;
std::list<std::vector<uint8_t> > fst_sections;
unsigned char fst_version; unsigned char fst_version;
bool quiet_fastscan; bool quiet_fastscan;
void InitFastscanLnb(int id); void InitFastscanLnb(int id);
bool FastscanTune(int id); bool FastscanTune(int id);
bool ReadFst(unsigned short pid, unsigned short operator_id, bool one_section = false);
bool ParseFst(unsigned short pid, fast_scan_operator_t * op); bool ParseFst(unsigned short pid, fast_scan_operator_t * op);
bool ParseFnt(unsigned short pid, unsigned short operator_id); bool ParseFnt(unsigned short pid, unsigned short operator_id);
void process_logical_service_descriptor(const unsigned char * const buffer, const t_transport_stream_id transport_stream_id, const t_original_network_id original_network_id, t_satellite_position satellitePosition, freq_id_t freq); void process_logical_service_descriptor(const unsigned char * const buffer, const t_transport_stream_id transport_stream_id, const t_original_network_id original_network_id, t_satellite_position satellitePosition, freq_id_t freq);

View File

@@ -273,69 +273,24 @@ bool CServiceScan::ReadFstVersion(int num)
return false; return false;
frontend->setTsidOnid(0); frontend->setTsidOnid(0);
if (!ReadFst(pid, operator_id, true))
cDemux * dmx = new cDemux();
dmx->Open(DMX_PSI_CHANNEL);
unsigned char buffer[SEC_SIZE];
unsigned char filter[DMX_FILTER_SIZE];
unsigned char mask[DMX_FILTER_SIZE];
memset(filter, 0x00, DMX_FILTER_SIZE);
memset(mask, 0x00, DMX_FILTER_SIZE);
filter[0] = 0xBD;
filter[1] = (operator_id >> 8) & 0xff;
filter[2] = operator_id & 0xff;
mask[0] = mask[1] = mask[2] = 0xFF;
if (dmx->sectionFilter(pid, filter, mask, 3) < 0) {
delete dmx;
return false; return false;
}
if (dmx->Read(buffer, SEC_SIZE) < 0) {
delete dmx;
return false;
}
fst_version = (buffer[5] >> 1) & 0x1f; fst_sections.clear();
printf("[FST VERSION] version %02x\n", fst_version); printf("[FST VERSION] version %02x\n", fst_version);
delete dmx;
return true; return true;
} }
bool CServiceScan::ParseFst(unsigned short pid, fast_scan_operator_t * op) bool CServiceScan::ReadFst(unsigned short pid, unsigned short operator_id, bool one_section)
{ {
int secdone[255]; int secdone[255];
int sectotal = -1; int sectotal = -1;
unsigned short operator_id = op->id; uint8_t last = 0;
CZapitBouquet* bouquet;
int bouquetId;
memset(secdone, 0, 255);
cDemux * dmx = new cDemux();
dmx->Open(DMX_PSI_CHANNEL);
unsigned char buffer[SEC_SIZE];
/* position in buffer */
unsigned short pos;
unsigned short pos2;
/* service_description_section elements */
unsigned short section_length;
unsigned short transport_stream_id = 0;
unsigned short original_network_id = 0;
unsigned short operator_network_id = 0;
unsigned short service_id;
unsigned short descriptors_loop_length;
unsigned short video_pid, audio_pid, pcr_pid;
unsigned char filter[DMX_FILTER_SIZE]; unsigned char filter[DMX_FILTER_SIZE];
unsigned char mask[DMX_FILTER_SIZE]; unsigned char mask[DMX_FILTER_SIZE];
memset(secdone, 0, 255);
memset(filter, 0x00, DMX_FILTER_SIZE); memset(filter, 0x00, DMX_FILTER_SIZE);
memset(mask, 0x00, DMX_FILTER_SIZE); memset(mask, 0x00, DMX_FILTER_SIZE);
@@ -344,45 +299,88 @@ bool CServiceScan::ParseFst(unsigned short pid, fast_scan_operator_t * op)
filter[2] = operator_id & 0xff; filter[2] = operator_id & 0xff;
mask[0] = mask[1] = mask[2] = 0xFF; mask[0] = mask[1] = mask[2] = 0xFF;
printf("[FST] scaning pid %d operator %d\n", pid, operator_id); printf("[FST] reading pid %d operator %d\n", pid, operator_id);
cDemux * dmx = new cDemux();
dmx->Open(DMX_PSI_CHANNEL);
if (dmx->sectionFilter(pid, filter, mask, 3) < 0) { if (dmx->sectionFilter(pid, filter, mask, 3) < 0) {
delete dmx; delete dmx;
return false; return false;
} }
#if 0
g_bouquetManager->clearAll();
CServiceManager::getInstance()->RemoveAllChannels();
#endif
do { do {
if (dmx->Read(buffer, SEC_SIZE) < 0) { std::vector<uint8_t> section(SEC_SIZE);
delete dmx; uint8_t * buffer = section.data();
return false;
} if (dmx->Read(buffer, SEC_SIZE) < 0)
break;
if(buffer[0] != 0xBD) if(buffer[0] != 0xBD)
printf("[FST] ******************************************* Bogus section received: 0x%x\n", buffer[0]); printf("[FST] ******************************************* Bogus section received: 0x%x\n", buffer[0]);
section_length = ((buffer[1] & 0x0F) << 8) | buffer[2];
operator_network_id = (buffer[3] << 8) | buffer[4];
fst_version = (buffer[5] >> 1) & 0x1f; fst_version = (buffer[5] >> 1) & 0x1f;
unsigned char secnum = buffer[6]; unsigned char secnum = buffer[6];
printf("[FST] version %x section %X last %X operator 0x%x -> %s\n", fst_version, buffer[6], buffer[7], operator_network_id, secdone[secnum] ? "skip" : "use"); printf("[FST] version %x section %X last %X -> %s\n", fst_version, buffer[6], buffer[7], secdone[secnum] ? "skip" : "use");
if(secdone[secnum]) if(secdone[secnum])
continue; continue;
secdone[secnum] = 1; secdone[secnum] = 1;
sectotal++; sectotal++;
fst_sections.push_back(section);
last = buffer[7];
} while(!one_section && (sectotal < last));
delete dmx;
printf("[FST] %d sections\n", fst_sections.size());
return !fst_sections.empty();
}
bool CServiceScan::ParseFst(unsigned short pid, fast_scan_operator_t * op)
{
unsigned short operator_id = op->id;
CZapitBouquet* bouquet;
int bouquetId;
/* position in buffer */
unsigned short pos;
unsigned short pos2;
printf("[FST] scaning pid %d operator %d\n", pid, operator_id);
if (!ReadFst(pid, operator_id)) {
printf("[FST] sections read failed\n");
return false;
}
#if 0
g_bouquetManager->clearAll();
CServiceManager::getInstance()->RemoveAllChannels();
#endif
ZapitChannelList ChannelList;
CServiceManager::getInstance()->GetAllTvChannels(ChannelList, CZapitChannel::FASTSCAN);
for (zapit_list_it_t oldI = ChannelList.begin(); oldI != ChannelList.end(); ++oldI)
(*oldI)->flags = CZapitChannel::REMOVED;
CServiceManager::getInstance()->GetAllRadioChannels(ChannelList, CZapitChannel::FASTSCAN);
for (zapit_list_it_t oldI = ChannelList.begin(); oldI != ChannelList.end(); ++oldI)
(*oldI)->flags = CZapitChannel::REMOVED;
for (std::list<std::vector<uint8_t> >::iterator it = fst_sections.begin(); it != fst_sections.end(); ++it) {
uint8_t * buffer = (*it).data();
unsigned short section_length = ((buffer[1] & 0x0F) << 8) | buffer[2];
unsigned short operator_network_id = (buffer[3] << 8) | buffer[4];
fst_version = (buffer[5] >> 1) & 0x1f;
//printf("[FST] version %x section %X last %X operator 0x%x\n", fst_version, buffer[6], buffer[7], operator_network_id);
unsigned short descriptors_loop_length;
for (pos = 8; pos < section_length - 1; pos += descriptors_loop_length + 18) { for (pos = 8; pos < section_length - 1; pos += descriptors_loop_length + 18) {
original_network_id = (buffer[pos] << 8) | buffer[pos+1]; unsigned short original_network_id = (buffer[pos] << 8) | buffer[pos+1];
transport_stream_id = (buffer[pos+2] << 8) | buffer[pos+3]; unsigned short transport_stream_id = (buffer[pos+2] << 8) | buffer[pos+3];
service_id = (buffer[pos+4] << 8) | buffer[pos+5]; unsigned short service_id = (buffer[pos+4] << 8) | buffer[pos+5];
video_pid = (buffer[pos+6] << 8) | buffer[pos+7]; unsigned short video_pid = (buffer[pos+6] << 8) | buffer[pos+7];
audio_pid = (buffer[pos+8] << 8) | buffer[pos+9]; unsigned short audio_pid = (buffer[pos+8] << 8) | buffer[pos+9];
pcr_pid = (buffer[pos+14] << 8) | buffer[pos+15]; unsigned short pcr_pid = (buffer[pos+14] << 8) | buffer[pos+15];
//printf("[FST] onid %x tid %x sid %x vpid %x apid %x pcr %x\n", original_network_id, transport_stream_id, service_id, video_pid, audio_pid, pcr_pid); //printf("[FST] onid %x tid %x sid %x vpid %x apid %x pcr %x\n", original_network_id, transport_stream_id, service_id, video_pid, audio_pid, pcr_pid);
descriptors_loop_length = ((buffer[pos + 16] & 0x0F) << 8) | buffer[pos + 17]; descriptors_loop_length = ((buffer[pos + 16] & 0x0F) << 8) | buffer[pos + 17];
@@ -453,10 +451,11 @@ bool CServiceScan::ParseFst(unsigned short pid, fast_scan_operator_t * op)
satellitePosition, satellitePosition,
freq); freq);
newchannel->deltype = FE_QPSK; newchannel->deltype = FE_QPSK;
newchannel->flags = CZapitChannel::NEW | CZapitChannel::FASTSCAN;
CServiceManager::getInstance()->AddChannel(newchannel); CServiceManager::getInstance()->AddChannel(newchannel);
} else {
newchannel->flags = CZapitChannel::UPDATED | CZapitChannel::FASTSCAN;
} }
// FIXME detect new/removed
newchannel->flags = CZapitChannel::UPDATED;
newchannel->setName(serviceName); newchannel->setName(serviceName);
newchannel->setServiceType(service_type); newchannel->setServiceType(service_type);
newchannel->setVideoPid(video_pid); newchannel->setVideoPid(video_pid);
@@ -504,13 +503,13 @@ bool CServiceScan::ParseFst(unsigned short pid, fast_scan_operator_t * op)
} }
} }
} }
} while(sectotal < buffer[7]); }
delete dmx;
bouquetId = g_bouquetManager->existsUBouquet(op->name); bouquetId = g_bouquetManager->existsUBouquet(op->name);
if (bouquetId >= 0) if (bouquetId >= 0)
g_bouquetManager->Bouquets[bouquetId]->sortBouquetByNumber(); g_bouquetManager->Bouquets[bouquetId]->sortBouquetByNumber();
fst_sections.clear();
printf("[FST] done\n\n"); printf("[FST] done\n\n");
return true; return true;
} }
@@ -553,6 +552,8 @@ bool CServiceScan::ParseFnt(unsigned short pid, unsigned short operator_id)
mask[0] = mask[1] = mask[2] = 0xFF; mask[0] = mask[1] = mask[2] = 0xFF;
frontendType = FE_QPSK;
printf("[FNT] scaning pid %d operator %d\n", pid, operator_id); printf("[FNT] scaning pid %d operator %d\n", pid, operator_id);
if (dmx->sectionFilter(pid, filter, mask, 3) < 0) { if (dmx->sectionFilter(pid, filter, mask, 3) < 0) {
delete dmx; delete dmx;