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:
parent
29cb25485f
commit
68459e6553
1
HISTORY
1
HISTORY
@ -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.
|
||||
|
4
Makefile
4
Makefile
@ -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:
|
||||
|
||||
|
13
device.c
13
device.c
@ -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])
|
||||
|
4
device.h
4
device.h
@ -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
116
pidscanner.c
Normal 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
30
pidscanner.h
Normal 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
|
Loading…
Reference in New Issue
Block a user