1
0
mirror of https://github.com/rofafor/vdr-plugin-iptv.git synced 2023-10-10 13:37:03 +02:00

Added preliminary automatic Pid scanning functionality.

This commit is contained in:
Rolf Ahrenberg 2008-01-30 22:41:58 +00:00
parent 29cb25485f
commit 68459e6553
6 changed files with 162 additions and 6 deletions

View File

@ -43,3 +43,4 @@ VDR Plugin 'iptv' Revision History
- Updated French translation (Thanks to Michaël Nival).
- Modified VDR locale support detection.
- Added preliminary automatic Pid scanning functionality.

View File

@ -1,7 +1,7 @@
#
# Makefile for a Video Disk Recorder plugin
#
# $Id: Makefile,v 1.25 2008/01/28 22:37:27 rahrenbe Exp $
# $Id: Makefile,v 1.26 2008/01/30 22:41:58 rahrenbe Exp $
# Debugging on/off
#IPTV_DEBUG = 1
@ -64,7 +64,7 @@ endif
OBJS = $(PLUGIN).o config.o setup.o device.o streamer.o protocoludp.o \
protocolhttp.o protocolfile.o protocolext.o sectionfilter.o \
sidscanner.o statistics.o common.o socket.o i18n.o
sidscanner.o pidscanner.o statistics.o common.o socket.o i18n.o
### The main target:

View File

@ -3,7 +3,7 @@
*
* See the README file for copyright information and how to reach the author.
*
* $Id: device.c,v 1.80 2008/01/30 21:57:33 rahrenbe Exp $
* $Id: device.c,v 1.81 2008/01/30 22:41:59 rahrenbe Exp $
*/
#include "config.h"
@ -32,6 +32,7 @@ cIptvDevice::cIptvDevice(unsigned int Index)
pFileProtocol = new cIptvProtocolFile();
pExtProtocol = new cIptvProtocolExt();
pIptvStreamer = new cIptvStreamer(tsBuffer, &mutex);
pPidScanner = new cPidScanner;
// Initialize filter pointers
memset(secfilters, '\0', sizeof(secfilters));
// Start section handler for iptv device
@ -51,6 +52,7 @@ cIptvDevice::~cIptvDevice()
DELETE_POINTER(pFileProtocol);
DELETE_POINTER(pExtProtocol);
DELETE_POINTER(tsBuffer);
DELETE_POINTER(pPidScanner);
// Detach and destroy sid filter
if (pSidScanner) {
Detach(pSidScanner);
@ -236,6 +238,8 @@ bool cIptvDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
pIptvStreamer->Set(location, parameter, deviceIndex, protocol);
if (pSidScanner && IptvConfig.GetSectionFiltering() && IptvConfig.GetSidScanning())
pSidScanner->SetChannel(Channel);
if (pPidScanner && IptvConfig.GetPidScanning())
pPidScanner->SetChannel(Channel);
return true;
}
@ -381,8 +385,11 @@ bool cIptvDevice::GetTSPacket(uchar *&Data)
}
isPacketDelivered = true;
Data = p;
// Update pid statistics
AddPidStatistic(ts_pid(p), payload(p));
// Update pid statistics
AddPidStatistic(ts_pid(p), payload(p));
// Analyze incomplete streams with built-in pid analyzer
if (pPidScanner && IptvConfig.GetPidScanning())
pPidScanner->Process(p);
// Run the data through all filters
for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) {
if (secfilters[i])

View File

@ -3,7 +3,7 @@
*
* See the README file for copyright information and how to reach the author.
*
* $Id: device.h,v 1.36 2008/01/28 21:36:33 rahrenbe Exp $
* $Id: device.h,v 1.37 2008/01/30 22:41:59 rahrenbe Exp $
*/
#ifndef __IPTV_DEVICE_H
@ -17,6 +17,7 @@
#include "protocolext.h"
#include "streamer.h"
#include "sectionfilter.h"
#include "pidscanner.h"
#include "sidscanner.h"
#include "statistics.h"
@ -43,6 +44,7 @@ private:
cIptvProtocolFile *pFileProtocol;
cIptvProtocolExt *pExtProtocol;
cIptvStreamer *pIptvStreamer;
cPidScanner *pPidScanner;
cSidScanner *pSidScanner;
cMutex mutex;
cIptvSectionFilter* secfilters[eMaxSecFilterCount];

116
pidscanner.c Normal file
View File

@ -0,0 +1,116 @@
/*
* pidscanner.c: IPTV plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
* $Id: pidscanner.c,v 1.1 2008/01/30 22:41:59 rahrenbe Exp $
*/
#include "common.h"
#include "pidscanner.h"
cPidScanner::cPidScanner(void)
: process(true),
Vpid(0xFFFF),
Apid(0xFFFF),
numVpids(0),
numApids(0)
{
debug("cPidScanner::cPidScanner()\n");
channel = cChannel();
}
cPidScanner::~cPidScanner()
{
debug("cPidScanner::~cPidScanner()\n");
}
void cPidScanner::Process(const uint8_t* buf)
{
//debug("cPidScanner::Process()\n");
if (!process)
return;
if (buf[0] != 0x47) {
error("Not TS packet: 0x%X\n", buf[0]);
return;
}
// Found TS packet
int pid = ts_pid(buf);
int xpid = (buf[1] << 8 | buf[2]);
// count == 0 if no payload or out of range
uint8_t count = payload(buf);
if (count == 0)
return;
if (xpid & 0x4000) {
// Stream start (Payload Unit Start Indicator)
uchar *d = (uint8_t*)buf;
d += 4;
// pointer to payload
if (buf[3] & 0x20)
d += d[0] + 1;
// Skip adaption field
if (buf[3] & 0x10) {
// Payload present
if ((d[0] == 0) && (d[1] == 0) && (d[2] == 1)) {
// PES packet start
int sid = d[3];
// Stream ID
if ((sid >= 0xC0) && (sid <= 0xDF)) {
if (pid < Apid) {
Apid = pid;
numApids = 1;
}
else if (pid == Apid)
++numApids;
}
else if ((sid >= 0xE0) && (sid <= 0xEF)) {
if (pid < Vpid) {
Vpid = pid;
numVpids = 1;
}
else if (pid == Vpid)
++numVpids;
}
}
if (numVpids > 10 && numApids > 5) {
if (!Channels.Lock(true, 10))
return;
debug("cPidScanner::Process(): Vpid=0x%04X, Apid=0x%04X\n", Vpid, Apid);
cChannel *IptvChannel = Channels.GetByChannelID(channel.GetChannelID());
int Ppid = 0;
int Apids[MAXAPIDS + 1] = { 0 }; // these lists are zero-terminated
int Dpids[MAXDPIDS + 1] = { 0 };
int Spids[MAXSPIDS + 1] = { 0 };
char ALangs[MAXAPIDS][MAXLANGCODE2] = { "" };
char DLangs[MAXDPIDS][MAXLANGCODE2] = { "" };
char SLangs[MAXSPIDS][MAXLANGCODE2] = { "" };
int Tpid = 0;
Apids[0] = Apid;
IptvChannel->SetPids(Vpid, Ppid, Apids, ALangs, Dpids, DLangs, Spids, SLangs, Tpid);
Channels.Unlock();
process = false;
}
}
}
}
void cPidScanner::SetChannel(const cChannel *Channel)
{
if (Channel) {
debug("cPidScanner::SetChannel(): %s\n", Channel->PluginParam());
channel = *Channel;
}
else {
debug("cPidScanner::SetChannel()\n");
channel = cChannel();
}
Vpid = 0xFFFF;
numVpids = 0;
Apid = 0xFFFF;
numApids = 0;
process = true;
}

30
pidscanner.h Normal file
View File

@ -0,0 +1,30 @@
/*
* pidscanner.h: IPTV plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
* $Id: pidscanner.h,v 1.1 2008/01/30 22:41:59 rahrenbe Exp $
*/
#ifndef __PIDSCANNER_H
#define __PIDSCANNER_H
#include <vdr/channels.h>
class cPidScanner {
private:
cChannel channel;
bool process;
int Vpid;
int Apid;
int numVpids;
int numApids;
public:
cPidScanner(void);
~cPidScanner();
void Process(const uint8_t* buf);
void SetChannel(const cChannel *Channel);
};
#endif // __PIDSCANNER_H