mirror of
https://github.com/rofafor/vdr-plugin-iptv.git
synced 2023-10-10 13:37:03 +02:00
Implement some statistics.
This commit is contained in:
parent
e210b8197b
commit
978fb7aa0f
5
Makefile
5
Makefile
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Makefile for a Video Disk Recorder plugin
|
# Makefile for a Video Disk Recorder plugin
|
||||||
#
|
#
|
||||||
# $Id: Makefile,v 1.14 2007/10/01 18:14:57 rahrenbe Exp $
|
# $Id: Makefile,v 1.15 2007/10/05 19:00:44 ajhseppa Exp $
|
||||||
|
|
||||||
# Debugging on/off
|
# Debugging on/off
|
||||||
#IPTV_DEBUG = 1
|
#IPTV_DEBUG = 1
|
||||||
@ -58,7 +58,8 @@ endif
|
|||||||
### The object files (add further files here):
|
### The object files (add further files here):
|
||||||
|
|
||||||
OBJS = $(PLUGIN).o config.o setup.o device.o streamer.o protocoludp.o \
|
OBJS = $(PLUGIN).o config.o setup.o device.o streamer.o protocoludp.o \
|
||||||
protocolhttp.o protocolfile.o sectionfilter.o sidscanner.o
|
protocolhttp.o protocolfile.o sectionfilter.o sidscanner.o \
|
||||||
|
statistics.o
|
||||||
|
|
||||||
### The main target:
|
### The main target:
|
||||||
|
|
||||||
|
7
device.c
7
device.c
@ -3,12 +3,13 @@
|
|||||||
*
|
*
|
||||||
* See the README file for copyright information and how to reach the author.
|
* See the README file for copyright information and how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: device.c,v 1.49 2007/10/01 18:14:57 rahrenbe Exp $
|
* $Id: device.c,v 1.50 2007/10/05 19:00:44 ajhseppa Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
|
#include "sectionfilter.h"
|
||||||
|
|
||||||
#define IPTV_MAX_DEVICES 8
|
#define IPTV_MAX_DEVICES 8
|
||||||
|
|
||||||
@ -299,6 +300,9 @@ bool cIptvDevice::GetTSPacket(uchar *&Data)
|
|||||||
}
|
}
|
||||||
isPacketDelivered = true;
|
isPacketDelivered = true;
|
||||||
Data = p;
|
Data = p;
|
||||||
|
// Increment statistics counter
|
||||||
|
dataBytes += Count;
|
||||||
|
UpdateActivePids(ts_pid(p), payload(p));
|
||||||
// Run the data through all filters
|
// Run the data through all filters
|
||||||
for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) {
|
for (unsigned int i = 0; i < eMaxSecFilterCount; ++i) {
|
||||||
if (secfilters[i])
|
if (secfilters[i])
|
||||||
@ -310,4 +314,3 @@ bool cIptvDevice::GetTSPacket(uchar *&Data)
|
|||||||
Data = NULL;
|
Data = NULL;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
device.h
5
device.h
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* See the README file for copyright information and how to reach the author.
|
* See the README file for copyright information and how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: device.h,v 1.23 2007/10/01 18:14:57 rahrenbe Exp $
|
* $Id: device.h,v 1.24 2007/10/05 19:00:44 ajhseppa Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __IPTV_DEVICE_H
|
#ifndef __IPTV_DEVICE_H
|
||||||
@ -16,8 +16,9 @@
|
|||||||
#include "streamer.h"
|
#include "streamer.h"
|
||||||
#include "sectionfilter.h"
|
#include "sectionfilter.h"
|
||||||
#include "sidscanner.h"
|
#include "sidscanner.h"
|
||||||
|
#include "statistics.h"
|
||||||
|
|
||||||
class cIptvDevice : public cDevice {
|
class cIptvDevice : public cDevice, public cIptvDeviceStatistics {
|
||||||
// static ones
|
// static ones
|
||||||
public:
|
public:
|
||||||
static unsigned int deviceCount;
|
static unsigned int deviceCount;
|
||||||
|
@ -3,13 +3,34 @@
|
|||||||
*
|
*
|
||||||
* See the README file for copyright information and how to reach the author.
|
* See the README file for copyright information and how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: sectionfilter.c,v 1.6 2007/09/27 11:48:28 ajhseppa Exp $
|
* $Id: sectionfilter.c,v 1.7 2007/10/05 19:00:44 ajhseppa Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sectionfilter.h"
|
#include "sectionfilter.h"
|
||||||
|
#include "statistics.h"
|
||||||
|
|
||||||
#define IPTV_FILTER_FILENAME "/tmp/vdr-iptv%d.filter%d"
|
#define IPTV_FILTER_FILENAME "/tmp/vdr-iptv%d.filter%d"
|
||||||
|
|
||||||
|
uint16_t ts_pid(const uint8_t *buf)
|
||||||
|
{
|
||||||
|
return ((buf[1] & 0x1f) << 8) + buf[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t payload(const uint8_t *tsp)
|
||||||
|
{
|
||||||
|
if (!(tsp[3] & 0x10)) // no payload?
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (tsp[3] & 0x20) { // adaptation field?
|
||||||
|
if (tsp[4] > 183) // corrupted data?
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return 184 - 1 - tsp[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 184;
|
||||||
|
}
|
||||||
|
|
||||||
cIptvSectionFilter::cIptvSectionFilter(int Index, int devInd,
|
cIptvSectionFilter::cIptvSectionFilter(int Index, int devInd,
|
||||||
u_short Pid, u_char Tid, u_char Mask)
|
u_short Pid, u_char Tid, u_char Mask)
|
||||||
: pusi_seen(0),
|
: pusi_seen(0),
|
||||||
@ -93,26 +114,6 @@ inline uint16_t cIptvSectionFilter::section_length(const uint8_t *buf)
|
|||||||
return 3 + ((buf[1] & 0x0f) << 8) + buf[2];
|
return 3 + ((buf[1] & 0x0f) << 8) + buf[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint16_t cIptvSectionFilter::ts_pid(const uint8_t *buf)
|
|
||||||
{
|
|
||||||
return ((buf[1] & 0x1f) << 8) + buf[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint8_t cIptvSectionFilter::payload(const uint8_t *tsp)
|
|
||||||
{
|
|
||||||
if (!(tsp[3] & 0x10)) // no payload?
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (tsp[3] & 0x20) { // adaptation field?
|
|
||||||
if (tsp[4] > 183) // corrupted data?
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return 184 - 1 - tsp[4];
|
|
||||||
}
|
|
||||||
|
|
||||||
return 184;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cIptvSectionFilter::dvb_dmxdev_section_callback(const uint8_t *buffer1, size_t buffer1_len,
|
int cIptvSectionFilter::dvb_dmxdev_section_callback(const uint8_t *buffer1, size_t buffer1_len,
|
||||||
const uint8_t *buffer2, size_t buffer2_len,
|
const uint8_t *buffer2, size_t buffer2_len,
|
||||||
enum dmx_success success)
|
enum dmx_success success)
|
||||||
@ -143,6 +144,9 @@ int cIptvSectionFilter::dvb_dmxdev_section_callback(const uint8_t *buffer1, size
|
|||||||
char tmp[64];
|
char tmp[64];
|
||||||
error("ERROR: write(): %s", strerror_r(errno, tmp, sizeof(tmp)));
|
error("ERROR: write(): %s", strerror_r(errno, tmp, sizeof(tmp)));
|
||||||
}
|
}
|
||||||
|
// Increment statistics counters
|
||||||
|
filteredData += retval;
|
||||||
|
++numberOfCalls;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_PRINTF
|
#ifdef DEBUG_PRINTF
|
||||||
else if (retval)
|
else if (retval)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* See the README file for copyright information and how to reach the author.
|
* See the README file for copyright information and how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: sectionfilter.h,v 1.2 2007/09/24 17:20:58 rahrenbe Exp $
|
* $Id: sectionfilter.h,v 1.3 2007/10/05 19:00:44 ajhseppa Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __IPTV_SECTIONFILTER_H
|
#ifndef __IPTV_SECTIONFILTER_H
|
||||||
@ -23,6 +23,7 @@
|
|||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "statistics.h"
|
||||||
|
|
||||||
#ifndef DMX_MAX_FILTER_SIZE
|
#ifndef DMX_MAX_FILTER_SIZE
|
||||||
#define DMX_MAX_FILTER_SIZE 18
|
#define DMX_MAX_FILTER_SIZE 18
|
||||||
@ -37,7 +38,10 @@
|
|||||||
|
|
||||||
#define DVB_DEMUX_MASK_MAX 18
|
#define DVB_DEMUX_MASK_MAX 18
|
||||||
|
|
||||||
class cIptvSectionFilter {
|
uint16_t ts_pid(const uint8_t *buf);
|
||||||
|
uint8_t payload(const uint8_t *tsp);
|
||||||
|
|
||||||
|
class cIptvSectionFilter : public cIptvSectionStatistics {
|
||||||
private:
|
private:
|
||||||
enum dmx_success {
|
enum dmx_success {
|
||||||
DMX_OK = 0, /* Received Ok */
|
DMX_OK = 0, /* Received Ok */
|
||||||
@ -76,8 +80,6 @@ private:
|
|||||||
char pipeName[128];
|
char pipeName[128];
|
||||||
|
|
||||||
inline uint16_t section_length(const uint8_t *buf);
|
inline uint16_t section_length(const uint8_t *buf);
|
||||||
inline uint16_t ts_pid(const uint8_t *buf);
|
|
||||||
inline uint8_t payload(const uint8_t *tsp);
|
|
||||||
|
|
||||||
int dvb_dmxdev_section_callback(const uint8_t *buffer1,
|
int dvb_dmxdev_section_callback(const uint8_t *buffer1,
|
||||||
size_t buffer1_len,
|
size_t buffer1_len,
|
||||||
|
23
statisticif.h
Normal file
23
statisticif.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* statisticif.h: IPTV plugin for the Video Disk Recorder
|
||||||
|
*
|
||||||
|
* See the README file for copyright information and how to reach the author.
|
||||||
|
*
|
||||||
|
* $Id: statisticif.h,v 1.1 2007/10/05 19:00:44 ajhseppa Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __IPTV_STATISTICIF_H
|
||||||
|
#define __IPTV_STATISTICIF_H
|
||||||
|
|
||||||
|
class cIptvStatisticIf {
|
||||||
|
public:
|
||||||
|
cIptvStatisticIf() {}
|
||||||
|
virtual ~cIptvStatisticIf() {}
|
||||||
|
virtual char* GetStatistic() = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
cIptvStatisticIf(const cIptvStatisticIf&);
|
||||||
|
cIptvStatisticIf& operator=(const cIptvStatisticIf&);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __IPTV_STATISTICIF_H
|
130
statistics.c
Normal file
130
statistics.c
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* statistics.c: IPTV plugin for the Video Disk Recorder
|
||||||
|
*
|
||||||
|
* See the README file for copyright information and how to reach the author.
|
||||||
|
*
|
||||||
|
* $Id: statistics.c,v 1.1 2007/10/05 19:00:44 ajhseppa Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "statistics.h"
|
||||||
|
|
||||||
|
// Section statistic class
|
||||||
|
cIptvSectionStatistics::cIptvSectionStatistics()
|
||||||
|
: filteredData(0),
|
||||||
|
numberOfCalls(0)
|
||||||
|
{
|
||||||
|
debug("cIptvSectionStatistics::cIptvSectionStatistics()\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
cIptvSectionStatistics::~cIptvSectionStatistics()
|
||||||
|
{
|
||||||
|
debug("cIptvSectionStatistics::~cIptvSectionStatistics()\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
char* cIptvSectionStatistics::GetStatistic()
|
||||||
|
{
|
||||||
|
debug("cIptvSectionStatistics::GetStatistic()\n");
|
||||||
|
char* retval;
|
||||||
|
asprintf(&retval, "Filtered data: %ld Data packets passed: %ld",
|
||||||
|
filteredData, numberOfCalls);
|
||||||
|
|
||||||
|
filteredData = numberOfCalls = 0;
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Device statistic class
|
||||||
|
cIptvDeviceStatistics::cIptvDeviceStatistics()
|
||||||
|
: dataBytes(0)
|
||||||
|
{
|
||||||
|
debug("cIptvDeviceStatistics::cIptvDeviceStatistics()\n");
|
||||||
|
memset(mostActivePids, '\0', sizeof(mostActivePids));
|
||||||
|
}
|
||||||
|
|
||||||
|
cIptvDeviceStatistics::~cIptvDeviceStatistics()
|
||||||
|
{
|
||||||
|
debug("cIptvDeviceStatistics::~cIptvDeviceStatistics()\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
char* cIptvDeviceStatistics::GetStatistic()
|
||||||
|
{
|
||||||
|
debug("cIptvDeviceStatistics::GetStatistic()\n");
|
||||||
|
char* retval;
|
||||||
|
asprintf(&retval, "Stream data bytes: %ld, Active Pids: 1: Pid %d %ld 2: Pid %d %ld 3: %d %ld", dataBytes, mostActivePids[0].pid,
|
||||||
|
mostActivePids[0].DataAmount, mostActivePids[1].pid,
|
||||||
|
mostActivePids[1].DataAmount, mostActivePids[2].pid,
|
||||||
|
mostActivePids[2].DataAmount);
|
||||||
|
|
||||||
|
dataBytes = 0;
|
||||||
|
memset(&mostActivePids, '\0', sizeof(mostActivePids));
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SortFunc(const void* data1, const void* data2)
|
||||||
|
{
|
||||||
|
debug("cIptvDeviceStatistics::SortFunc()\n");
|
||||||
|
|
||||||
|
pidStruct *comp1 = (pidStruct*)data1;
|
||||||
|
pidStruct *comp2 = (pidStruct*)data2;
|
||||||
|
|
||||||
|
if (comp1->DataAmount > comp2->DataAmount)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (comp1->DataAmount < comp2->DataAmount)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cIptvDeviceStatistics::UpdateActivePids(u_short pid, long payload)
|
||||||
|
{
|
||||||
|
debug("cIptvDeviceStatistics::UpdateActivePids()\n");
|
||||||
|
|
||||||
|
const int numberOfElements = sizeof(mostActivePids) / sizeof(pidStruct);
|
||||||
|
|
||||||
|
// If our statistic already is in the array, update it and quit
|
||||||
|
for (int i = 0; i < numberOfElements; ++i) {
|
||||||
|
if (mostActivePids[i].pid == pid) {
|
||||||
|
mostActivePids[i].DataAmount += payload;
|
||||||
|
// Now re-sort the array and quit
|
||||||
|
qsort(&mostActivePids, numberOfElements, sizeof(pidStruct), SortFunc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apparently our pid isn't in the array. Replace the last element with this
|
||||||
|
// one if new payload is greater
|
||||||
|
if (mostActivePids[numberOfElements - 1].DataAmount < payload) {
|
||||||
|
mostActivePids[numberOfElements - 1].pid = pid;
|
||||||
|
mostActivePids[numberOfElements - 1].DataAmount = payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-sort
|
||||||
|
qsort(&mostActivePids, numberOfElements, sizeof(pidStruct), SortFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Streamer statistic class
|
||||||
|
cIptvStreamerStatistics::cIptvStreamerStatistics()
|
||||||
|
: dataBytes(0)
|
||||||
|
{
|
||||||
|
debug("cIptvStreamerStatistics::cIptvStreamerStatistics()\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
cIptvStreamerStatistics::~cIptvStreamerStatistics()
|
||||||
|
{
|
||||||
|
debug("cIptvStreamerStatistics::~cIptvStreamerStatistics()\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
char* cIptvStreamerStatistics::GetStatistic()
|
||||||
|
{
|
||||||
|
debug("cIptvStreamerStatistics::GetStatistic()\n");
|
||||||
|
char* retval;
|
||||||
|
asprintf(&retval, "Stream data bytes: %ld", dataBytes);
|
||||||
|
|
||||||
|
dataBytes = 0;
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
64
statistics.h
Normal file
64
statistics.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* statistics.h: IPTV plugin for the Video Disk Recorder
|
||||||
|
*
|
||||||
|
* See the README file for copyright information and how to reach the author.
|
||||||
|
*
|
||||||
|
* $Id: statistics.h,v 1.1 2007/10/05 19:00:44 ajhseppa Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __IPTV_STATISTICS_H
|
||||||
|
#define __IPTV_STATISTICS_H
|
||||||
|
|
||||||
|
#include "statisticif.h"
|
||||||
|
|
||||||
|
struct pidStruct {
|
||||||
|
u_short pid;
|
||||||
|
long DataAmount;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Section statistics
|
||||||
|
class cIptvSectionStatistics : public cIptvStatisticIf {
|
||||||
|
protected:
|
||||||
|
long filteredData;
|
||||||
|
long numberOfCalls;
|
||||||
|
|
||||||
|
public:
|
||||||
|
cIptvSectionStatistics();
|
||||||
|
virtual ~cIptvSectionStatistics();
|
||||||
|
|
||||||
|
char* GetStatistic();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Device statistics
|
||||||
|
class cIptvDeviceStatistics : public cIptvStatisticIf {
|
||||||
|
protected:
|
||||||
|
long dataBytes;
|
||||||
|
|
||||||
|
public:
|
||||||
|
cIptvDeviceStatistics();
|
||||||
|
virtual ~cIptvDeviceStatistics();
|
||||||
|
|
||||||
|
char* GetStatistic();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void UpdateActivePids(u_short pid, long payload);
|
||||||
|
|
||||||
|
private:
|
||||||
|
pidStruct mostActivePids[10];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Streamer statistics
|
||||||
|
class cIptvStreamerStatistics : public cIptvStatisticIf {
|
||||||
|
protected:
|
||||||
|
long dataBytes;
|
||||||
|
|
||||||
|
public:
|
||||||
|
cIptvStreamerStatistics();
|
||||||
|
virtual ~cIptvStreamerStatistics();
|
||||||
|
|
||||||
|
char* GetStatistic();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // __IPTV_STATISTICS_H
|
||||||
|
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* See the README file for copyright information and how to reach the author.
|
* See the README file for copyright information and how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: streamer.c,v 1.16 2007/09/29 16:21:05 rahrenbe Exp $
|
* $Id: streamer.c,v 1.17 2007/10/05 19:00:44 ajhseppa Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <vdr/thread.h>
|
#include <vdr/thread.h>
|
||||||
@ -37,6 +37,7 @@ void cIptvStreamer::Action(void)
|
|||||||
unsigned char *buffer = NULL;
|
unsigned char *buffer = NULL;
|
||||||
int length = protocol->Read(&buffer);
|
int length = protocol->Read(&buffer);
|
||||||
if (length >= 0) {
|
if (length >= 0) {
|
||||||
|
dataBytes += length; // Statistics update
|
||||||
mutex->Lock();
|
mutex->Lock();
|
||||||
int p = ringBuffer->Put(buffer, length);
|
int p = ringBuffer->Put(buffer, length);
|
||||||
if (p != length && Running())
|
if (p != length && Running())
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* See the README file for copyright information and how to reach the author.
|
* See the README file for copyright information and how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: streamer.h,v 1.7 2007/09/29 16:21:05 rahrenbe Exp $
|
* $Id: streamer.h,v 1.8 2007/10/05 19:00:44 ajhseppa Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __IPTV_STREAMER_H
|
#ifndef __IPTV_STREAMER_H
|
||||||
@ -15,8 +15,9 @@
|
|||||||
#include <vdr/ringbuffer.h>
|
#include <vdr/ringbuffer.h>
|
||||||
|
|
||||||
#include "protocolif.h"
|
#include "protocolif.h"
|
||||||
|
#include "statistics.h"
|
||||||
|
|
||||||
class cIptvStreamer : public cThread {
|
class cIptvStreamer : public cThread, public cIptvStreamerStatistics {
|
||||||
private:
|
private:
|
||||||
cRingBufferLinear* ringBuffer;
|
cRingBufferLinear* ringBuffer;
|
||||||
cMutex* mutex;
|
cMutex* mutex;
|
||||||
|
Loading…
Reference in New Issue
Block a user