mirror of
https://github.com/rofafor/vdr-plugin-iptv.git
synced 2023-10-10 13:37:03 +02:00
Very rudimentary pid & section filtering, uses code from libdvb. Does
not work anyway.
This commit is contained in:
parent
638025eb26
commit
a7bd285fc6
4
Makefile
4
Makefile
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Makefile for a Video Disk Recorder plugin
|
# Makefile for a Video Disk Recorder plugin
|
||||||
#
|
#
|
||||||
# $Id: Makefile,v 1.6 2007/09/16 12:18:15 ajhseppa Exp $
|
# $Id: Makefile,v 1.7 2007/09/19 15:14:32 ajhseppa Exp $
|
||||||
|
|
||||||
# Debugging on/off
|
# Debugging on/off
|
||||||
#IPTV_DEBUG = 1
|
#IPTV_DEBUG = 1
|
||||||
@ -57,7 +57,7 @@ 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 protocolhttp.o protocolfile.o
|
OBJS = $(PLUGIN).o config.o setup.o device.o streamer.o protocoludp.o protocolhttp.o protocolfile.o pidfilter.o
|
||||||
|
|
||||||
### The main target:
|
### The main target:
|
||||||
|
|
||||||
|
122
device.c
122
device.c
@ -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.c,v 1.23 2007/09/18 18:48:10 rahrenbe Exp $
|
* $Id: device.c,v 1.24 2007/09/19 15:14:32 ajhseppa Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
@ -25,6 +25,8 @@ cIptvDevice::cIptvDevice(unsigned int Index)
|
|||||||
debug("cIptvDevice::cIptvDevice(%d)\n", deviceIndex);
|
debug("cIptvDevice::cIptvDevice(%d)\n", deviceIndex);
|
||||||
tsBuffer = new cRingBufferLinear(MEGABYTE(IptvConfig.GetTsBufferSize()),
|
tsBuffer = new cRingBufferLinear(MEGABYTE(IptvConfig.GetTsBufferSize()),
|
||||||
(TS_SIZE * 2), false, "IPTV");
|
(TS_SIZE * 2), false, "IPTV");
|
||||||
|
memset(&filter, '\0', sizeof(filter));
|
||||||
|
init_trans(&filter);
|
||||||
tsBuffer->SetTimeouts(100, 100);
|
tsBuffer->SetTimeouts(100, 100);
|
||||||
// pad prefill to multiple of TS_SIZE
|
// pad prefill to multiple of TS_SIZE
|
||||||
tsBufferPrefill = MEGABYTE(IptvConfig.GetTsBufferSize()) *
|
tsBufferPrefill = MEGABYTE(IptvConfig.GetTsBufferSize()) *
|
||||||
@ -36,6 +38,12 @@ cIptvDevice::cIptvDevice(unsigned int Index)
|
|||||||
pFileProtocol = new cIptvProtocolFile();
|
pFileProtocol = new cIptvProtocolFile();
|
||||||
pIptvStreamer = new cIptvStreamer(tsBuffer, &mutex);
|
pIptvStreamer = new cIptvStreamer(tsBuffer, &mutex);
|
||||||
StartSectionHandler();
|
StartSectionHandler();
|
||||||
|
|
||||||
|
for(int i = 0; i < 32; ++i) {
|
||||||
|
filters[i].active = false;
|
||||||
|
filters[i].fifoDesc = -1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cIptvDevice::~cIptvDevice()
|
cIptvDevice::~cIptvDevice()
|
||||||
@ -44,6 +52,18 @@ cIptvDevice::~cIptvDevice()
|
|||||||
delete pIptvStreamer;
|
delete pIptvStreamer;
|
||||||
delete pUdpProtocol;
|
delete pUdpProtocol;
|
||||||
delete tsBuffer;
|
delete tsBuffer;
|
||||||
|
|
||||||
|
// Iterate over all filters and clear their settings
|
||||||
|
for (int i = 0; i < 32; ++i) {
|
||||||
|
if (filters[i].active) {
|
||||||
|
close(filters[i].fifoDesc);
|
||||||
|
unlink(filters[i].pipeName);
|
||||||
|
memset(filters[i].pipeName, '\0', sizeof(filters[i].pipeName));
|
||||||
|
filters[i].fifoDesc = -1;
|
||||||
|
filters[i].active = false;
|
||||||
|
clear_trans_filt(&filter, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cIptvDevice::Initialize(unsigned int DeviceCount)
|
bool cIptvDevice::Initialize(unsigned int DeviceCount)
|
||||||
@ -156,17 +176,46 @@ bool cIptvDevice::SetPid(cPidHandle *Handle, int Type, bool On)
|
|||||||
|
|
||||||
int cIptvDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask)
|
int cIptvDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask)
|
||||||
{
|
{
|
||||||
int pipeDesc[2];
|
|
||||||
debug("cIptvDevice::OpenFilter(): Pid=%d Tid=%02X Mask=%02X\n", Pid, Tid, Mask);
|
// Search the next free filter slot
|
||||||
// Create a pipe
|
for (int i = 0; i < 32; ++i) {
|
||||||
if (pipe(pipeDesc) < 0) {
|
if(!filters[i].active) {
|
||||||
char tmp[64];
|
|
||||||
error("ERROR: pipe(): %s", strerror_r(errno, tmp, sizeof(tmp)));
|
debug("cIptvDevice::OpenFilter(): Pid=0x%X Tid=%02X Mask=%02X, filterCount = %d\n", Pid, Tid, Mask, i);
|
||||||
}
|
|
||||||
// Write pipe is used by the pid filtering class
|
uint8_t mask = Mask;
|
||||||
// cIptvSectionFilter Filter(pipeDesc[1], Pid, Tid, Mask)
|
uint8_t filt = Tid;
|
||||||
// Give the read pipe to vdr
|
|
||||||
return pipeDesc[0];
|
int err = set_trans_filt(&filter, i, Pid, &mask, &filt, 0);
|
||||||
|
if (err < 0)
|
||||||
|
error("Cannot set filter %d\n", i);
|
||||||
|
|
||||||
|
memset(filters[i].pipeName, '\0', sizeof(filters[i].pipeName));
|
||||||
|
snprintf(filters[i].pipeName, sizeof(filters[i].pipeName),
|
||||||
|
"/tmp/iptvPipe.%d", i);
|
||||||
|
err = mknod(filters[i].pipeName, 0644 | S_IFIFO, 0);
|
||||||
|
if (err < 0) {
|
||||||
|
char tmp[64];
|
||||||
|
error("ERROR: mknod(): %s", strerror_r(errno, tmp, sizeof(tmp)));
|
||||||
|
unlink(filters[i].pipeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create descriptors
|
||||||
|
int fifoDescriptor = open(filters[i].pipeName, O_RDWR | O_NONBLOCK);
|
||||||
|
int returnDescriptor = open(filters[i].pipeName, O_RDONLY | O_NONBLOCK);
|
||||||
|
|
||||||
|
// Store the write pipe and set active flag
|
||||||
|
filters[i].active = true;
|
||||||
|
filters[i].fifoDesc = fifoDescriptor;
|
||||||
|
|
||||||
|
//++filterCount;
|
||||||
|
return returnDescriptor;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// No free filter slot found
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cIptvDevice::OpenDvr(void)
|
bool cIptvDevice::OpenDvr(void)
|
||||||
@ -215,6 +264,55 @@ bool cIptvDevice::GetTSPacket(uchar *&Data)
|
|||||||
}
|
}
|
||||||
isPacketDelivered = true;
|
isPacketDelivered = true;
|
||||||
Data = p;
|
Data = p;
|
||||||
|
memcpy(filter.packet, p, sizeof(filter.packet));
|
||||||
|
trans_filt(p, 188, &filter);
|
||||||
|
|
||||||
|
|
||||||
|
for(int i = 0; i < 32; ++i) {
|
||||||
|
|
||||||
|
if(filters[i].active) {
|
||||||
|
|
||||||
|
section *filtered = get_filt_sec(&filter, i);
|
||||||
|
|
||||||
|
if (filtered->found) {
|
||||||
|
|
||||||
|
// Select on the fifo emptyness. Using null timeout to return
|
||||||
|
// immediately
|
||||||
|
struct timeval tv;
|
||||||
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
fd_set rfds;
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(filters[i].fifoDesc, &rfds);
|
||||||
|
int retval = select(filters[i].fifoDesc + 1, &rfds, NULL, NULL,
|
||||||
|
&tv);
|
||||||
|
// Check if error
|
||||||
|
if (retval < 0) {
|
||||||
|
char tmp[64];
|
||||||
|
error("ERROR: select(): %s", strerror_r(errno, tmp, sizeof(tmp)));
|
||||||
|
|
||||||
|
// VDR has probably closed the filter file descriptor.
|
||||||
|
// Clear the filter
|
||||||
|
close(filters[i].fifoDesc);
|
||||||
|
unlink(filters[i].pipeName);
|
||||||
|
memset(filters[i].pipeName, '\0', sizeof(filters[i].pipeName));
|
||||||
|
filters[i].fifoDesc = -1;
|
||||||
|
filters[i].active = false;
|
||||||
|
clear_trans_filt(&filter, i);
|
||||||
|
}
|
||||||
|
// There is no data in the fifo, more can be written
|
||||||
|
if (!retval) {
|
||||||
|
int err = write(filters[i].fifoDesc, filtered->payload,
|
||||||
|
filtered->length+3);
|
||||||
|
if (err < 0) {
|
||||||
|
char tmp[64];
|
||||||
|
error("ERROR: write(): %s", strerror_r(errno, tmp,
|
||||||
|
sizeof(tmp)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Data = NULL;
|
Data = NULL;
|
||||||
|
14
device.h
14
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.9 2007/09/16 13:11:19 rahrenbe Exp $
|
* $Id: device.h,v 1.10 2007/09/19 15:14:32 ajhseppa Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __IPTV_DEVICE_H
|
#ifndef __IPTV_DEVICE_H
|
||||||
@ -16,6 +16,16 @@
|
|||||||
#include "protocolfile.h"
|
#include "protocolfile.h"
|
||||||
#include "streamer.h"
|
#include "streamer.h"
|
||||||
|
|
||||||
|
#include "pidfilter.h"
|
||||||
|
|
||||||
|
struct filterInfo {
|
||||||
|
bool active;
|
||||||
|
int fifoDesc;
|
||||||
|
char pipeName[128];
|
||||||
|
int lastProvided;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class cIptvDevice : public cDevice {
|
class cIptvDevice : public cDevice {
|
||||||
// static ones
|
// static ones
|
||||||
public:
|
public:
|
||||||
@ -37,6 +47,8 @@ private:
|
|||||||
//cIptvProtocolRtsp *pRtspProtocol;
|
//cIptvProtocolRtsp *pRtspProtocol;
|
||||||
cIptvStreamer *pIptvStreamer;
|
cIptvStreamer *pIptvStreamer;
|
||||||
cMutex mutex;
|
cMutex mutex;
|
||||||
|
trans filter;
|
||||||
|
filterInfo filters[32];
|
||||||
|
|
||||||
// constructor & destructor
|
// constructor & destructor
|
||||||
public:
|
public:
|
||||||
|
334
pidfilter.c
Normal file
334
pidfilter.c
Normal file
@ -0,0 +1,334 @@
|
|||||||
|
/*
|
||||||
|
* dvb-mpegtools for the Siemens Fujitsu DVB PCI card
|
||||||
|
*
|
||||||
|
* Copyright (C) 2000, 2001 Marcus Metzler
|
||||||
|
* for convergence integrated media GmbH
|
||||||
|
* Copyright (C) 2002 Marcus Metzler
|
||||||
|
*
|
||||||
|
* 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 the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||||
|
*
|
||||||
|
|
||||||
|
* The author can be reached at mocm@metzlerbros.de,
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pidfilter.h"
|
||||||
|
|
||||||
|
#define PID_MASK_HI 0x1F
|
||||||
|
uint16_t get_pid(uint8_t *pid)
|
||||||
|
{
|
||||||
|
uint16_t pp = 0;
|
||||||
|
|
||||||
|
pp = (pid[0] & PID_MASK_HI)<<8;
|
||||||
|
pp |= pid[1];
|
||||||
|
|
||||||
|
return pp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define ADAPT_FIELD 0x20
|
||||||
|
#define PAYLOAD 0x10
|
||||||
|
#define PAY_START 0x40
|
||||||
|
/*
|
||||||
|
conversion
|
||||||
|
*/
|
||||||
|
|
||||||
|
void init_trans(trans *p)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
p->found = 0;
|
||||||
|
p->pes = 0;
|
||||||
|
p->is_full = 0;
|
||||||
|
p->pes_start = 0;
|
||||||
|
p->pes_started = 0;
|
||||||
|
p->set = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < MASKL*MAXFILT ; i++){
|
||||||
|
p->mask[i] = 0;
|
||||||
|
p->filt[i] = 0;
|
||||||
|
}
|
||||||
|
for (i = 0; i < MAXFILT ; i++){
|
||||||
|
p->sec[i].found = 0;
|
||||||
|
p->sec[i].length = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int set_trans_filt(trans *p, int filtn, uint16_t pid, uint8_t *mask, uint8_t *filt, int pes)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int off;
|
||||||
|
|
||||||
|
if ( filtn > MAXFILT-1 || filtn<0 ) return -1;
|
||||||
|
p->pid[filtn] = pid;
|
||||||
|
if (pes) p->pes |= (tflags)(1 << filtn);
|
||||||
|
else {
|
||||||
|
off = MASKL*filtn;
|
||||||
|
p->pes &= ~((tflags) (1 << filtn) );
|
||||||
|
for (i = 0; i < MASKL ; i++){
|
||||||
|
p->mask[off+i] = mask[i];
|
||||||
|
p->filt[off+i] = filt[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p->set |= (tflags) (1 << filtn);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_trans_filt(trans *p,int filtn)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
p->set &= ~((tflags) (1 << filtn) );
|
||||||
|
p->pes &= ~((tflags) (1 << filtn) );
|
||||||
|
p->is_full &= ~((tflags) (1 << filtn) );
|
||||||
|
p->pes_start &= ~((tflags) (1 << filtn) );
|
||||||
|
p->pes_started &= ~((tflags) (1 << filtn) );
|
||||||
|
|
||||||
|
for (i = MASKL*filtn; i < MASKL*(filtn+1) ; i++){
|
||||||
|
p->mask[i] = 0;
|
||||||
|
p->filt[i] = 0;
|
||||||
|
}
|
||||||
|
p->sec[filtn].found = 0;
|
||||||
|
p->sec[filtn].length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int filt_is_set(trans *p, int filtn)
|
||||||
|
{
|
||||||
|
if (p->set & ((tflags)(1 << filtn))) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pes_is_set(trans *p, int filtn)
|
||||||
|
{
|
||||||
|
if (p->pes & ((tflags)(1 << filtn))) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pes_is_started(trans *p, int filtn)
|
||||||
|
{
|
||||||
|
if (p->pes_started & ((tflags)(1 << filtn))) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pes_is_start(trans *p, int filtn)
|
||||||
|
{
|
||||||
|
if (p->pes_start & ((tflags)(1 << filtn))) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int filt_is_ready(trans *p,int filtn)
|
||||||
|
{
|
||||||
|
if (p->is_full & ((tflags)(1 << filtn))) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void trans_filt(uint8_t *buf, int count, trans *p)
|
||||||
|
{
|
||||||
|
int c=0;
|
||||||
|
//fprintf(stderr,"trans_filt\n");
|
||||||
|
|
||||||
|
|
||||||
|
while (c < count && p->found <1 ){
|
||||||
|
if ( buf[c] == 0x47) p->found = 1;
|
||||||
|
c++;
|
||||||
|
p->packet[0] = 0x47;
|
||||||
|
}
|
||||||
|
if (c == count) return;
|
||||||
|
|
||||||
|
while( c < count && p->found < 188 && p->found > 0 ){
|
||||||
|
p->packet[p->found] = buf[c];
|
||||||
|
c++;
|
||||||
|
p->found++;
|
||||||
|
}
|
||||||
|
if (p->found == 188){
|
||||||
|
p->found = 0;
|
||||||
|
tfilter(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c < count) trans_filt(buf+c,count-c,p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void tfilter(trans *p)
|
||||||
|
{
|
||||||
|
int l,c;
|
||||||
|
int tpid;
|
||||||
|
uint8_t flag,flags;
|
||||||
|
uint8_t adapt_length = 0;
|
||||||
|
uint8_t cpid[2];
|
||||||
|
|
||||||
|
|
||||||
|
// fprintf(stderr,"tfilter\n");
|
||||||
|
|
||||||
|
cpid[0] = p->packet[1];
|
||||||
|
cpid[1] = p->packet[2];
|
||||||
|
tpid = get_pid(cpid);
|
||||||
|
|
||||||
|
if ( p->packet[1]&0x80){
|
||||||
|
fprintf(stderr,"Error in TS for PID: %d\n",
|
||||||
|
tpid);
|
||||||
|
}
|
||||||
|
|
||||||
|
flag = cpid[0];
|
||||||
|
flags = p->packet[3];
|
||||||
|
|
||||||
|
if ( flags & ADAPT_FIELD ) {
|
||||||
|
// adaption field
|
||||||
|
adapt_length = p->packet[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
c = 5 + adapt_length - (int)(!(flags & ADAPT_FIELD));
|
||||||
|
if (flags & PAYLOAD){
|
||||||
|
for ( l = 0; l < MAXFILT ; l++){
|
||||||
|
if ( filt_is_set(p,l) ) {
|
||||||
|
if ( p->pid[l] == tpid) {
|
||||||
|
if ( pes_is_set(p,l) ){
|
||||||
|
if (cpid[0] & PAY_START){
|
||||||
|
p->pes_started |=
|
||||||
|
(tflags)
|
||||||
|
(1 << l);
|
||||||
|
p->pes_start |=
|
||||||
|
(tflags)
|
||||||
|
(1 << l);
|
||||||
|
} else {
|
||||||
|
p->pes_start &= ~
|
||||||
|
((tflags)
|
||||||
|
(1 << l));
|
||||||
|
}
|
||||||
|
pes_filter(p,l,c);
|
||||||
|
} else {
|
||||||
|
sec_filter(p,l,c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void pes_filter(trans *p, int filtn, int off)
|
||||||
|
{
|
||||||
|
int count,c;
|
||||||
|
uint8_t *buf;
|
||||||
|
|
||||||
|
if (filtn < 0 || filtn >= MAXFILT) return;
|
||||||
|
|
||||||
|
count = 188 - off;
|
||||||
|
c = 188*filtn;
|
||||||
|
buf = p->packet+off;
|
||||||
|
if (pes_is_started(p,filtn)){
|
||||||
|
p->is_full |= (tflags) (1 << filtn);
|
||||||
|
memcpy(p->transbuf+c,buf,count);
|
||||||
|
p->transcount[filtn] = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
section *get_filt_sec(trans *p, int filtn)
|
||||||
|
{
|
||||||
|
section *sec;
|
||||||
|
|
||||||
|
sec = &p->sec[filtn];
|
||||||
|
p->is_full &= ~((tflags) (1 << filtn) );
|
||||||
|
return sec;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_filt_buf(trans *p, int filtn,uint8_t **buf)
|
||||||
|
{
|
||||||
|
*buf = p->transbuf+188*filtn;
|
||||||
|
p->is_full &= ~((tflags) (1 << filtn) );
|
||||||
|
return p->transcount[filtn];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void sec_filter(trans *p, int filtn, int off)
|
||||||
|
{
|
||||||
|
int i,j;
|
||||||
|
int error;
|
||||||
|
int count,c;
|
||||||
|
uint8_t *buf, *secbuf;
|
||||||
|
section *sec;
|
||||||
|
|
||||||
|
// fprintf(stderr,"sec_filter\n");
|
||||||
|
|
||||||
|
if (filtn < 0 || filtn >= MAXFILT) return;
|
||||||
|
|
||||||
|
count = 188 - off;
|
||||||
|
c = 0;
|
||||||
|
buf = p->packet+off;
|
||||||
|
sec = &p->sec[filtn];
|
||||||
|
secbuf = sec->payload;
|
||||||
|
if(!filt_is_ready(p,filtn)){
|
||||||
|
p->is_full &= ~((tflags) (1 << filtn) );
|
||||||
|
sec->found = 0;
|
||||||
|
sec->length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !sec->found ){
|
||||||
|
c = buf[c]+1;
|
||||||
|
if (c >= count) return;
|
||||||
|
sec->id = buf[c];
|
||||||
|
secbuf[0] = buf[c];
|
||||||
|
c++;
|
||||||
|
sec->found++;
|
||||||
|
sec->length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( c < count && sec->found < 3){
|
||||||
|
secbuf[sec->found] = buf[c];
|
||||||
|
c++;
|
||||||
|
sec->found++;
|
||||||
|
}
|
||||||
|
if (c == count) return;
|
||||||
|
|
||||||
|
if (!sec->length && sec->found == 3){
|
||||||
|
sec->length |= ((secbuf[1] & 0x0F) << 8);
|
||||||
|
sec->length |= (secbuf[2] & 0xFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( c < count && sec->found < sec->length+3){
|
||||||
|
secbuf[sec->found] = buf[c];
|
||||||
|
c++;
|
||||||
|
sec->found++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( sec->length && sec->found == sec->length+3 ){
|
||||||
|
error=0;
|
||||||
|
for ( i = 0; i < MASKL; i++){
|
||||||
|
if (i > 0 ) j=2+i;
|
||||||
|
else j = 0;
|
||||||
|
error += (sec->payload[j]&p->mask[MASKL*filtn+i])^
|
||||||
|
(p->filt[MASKL*filtn+i]&
|
||||||
|
p->mask[MASKL*filtn+i]);
|
||||||
|
}
|
||||||
|
if (!error){
|
||||||
|
p->is_full |= (tflags) (1 << filtn);
|
||||||
|
}
|
||||||
|
if (buf[0]+1 < c ) c=count;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( c < count ) sec_filter(p, filtn, off);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern int errno;
|
||||||
|
const char * strerrno (void)
|
||||||
|
{
|
||||||
|
return strerror(errno);
|
||||||
|
}
|
92
pidfilter.h
Normal file
92
pidfilter.h
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* dvb-mpegtools for the Siemens Fujitsu DVB PCI card
|
||||||
|
*
|
||||||
|
* Copyright (C) 2000, 2001 Marcus Metzler
|
||||||
|
* for convergence integrated media GmbH
|
||||||
|
* Copyright (C) 2002 Marcus Metzler
|
||||||
|
*
|
||||||
|
* 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 the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||||
|
*
|
||||||
|
|
||||||
|
* The author can be reached at mocm@metzlerbros.de,
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __PIDFILTER_H
|
||||||
|
#define __PIDFILTER_H
|
||||||
|
|
||||||
|
#define MAX_PLENGTH 0xFFFF
|
||||||
|
|
||||||
|
typedef struct sectionstruct {
|
||||||
|
int id;
|
||||||
|
int length;
|
||||||
|
int found;
|
||||||
|
uint8_t payload[4096+3];
|
||||||
|
} section;
|
||||||
|
|
||||||
|
|
||||||
|
typedef uint32_t tflags;
|
||||||
|
#define MAXFILT 32
|
||||||
|
#define MASKL 16
|
||||||
|
typedef struct trans_struct {
|
||||||
|
int found;
|
||||||
|
uint8_t packet[188];
|
||||||
|
uint16_t pid[MAXFILT];
|
||||||
|
uint8_t mask[MAXFILT*MASKL];
|
||||||
|
uint8_t filt[MAXFILT*MASKL];
|
||||||
|
uint8_t transbuf[MAXFILT*188];
|
||||||
|
int transcount[MAXFILT];
|
||||||
|
section sec[MAXFILT];
|
||||||
|
tflags is_full;
|
||||||
|
tflags pes_start;
|
||||||
|
tflags pes_started;
|
||||||
|
tflags pes;
|
||||||
|
tflags set;
|
||||||
|
} trans;
|
||||||
|
|
||||||
|
|
||||||
|
void init_trans(trans *p);
|
||||||
|
int set_trans_filt(trans *p, int filtn, uint16_t pid, uint8_t *mask,
|
||||||
|
uint8_t *filt, int pes);
|
||||||
|
|
||||||
|
void clear_trans_filt(trans *p,int filtn);
|
||||||
|
int filt_is_set(trans *p, int filtn);
|
||||||
|
int filt_is_ready(trans *p,int filtn);
|
||||||
|
|
||||||
|
void trans_filt(uint8_t *buf, int count, trans *p);
|
||||||
|
void tfilter(trans *p);
|
||||||
|
void sec_filter(trans *p, int filtn, int off);
|
||||||
|
int get_filt_buf(trans *p, int filtn,uint8_t **buf);
|
||||||
|
section *get_filt_sec(trans *p, int filtn);
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t get_pid(uint8_t *pid);
|
||||||
|
void pes_filter(trans *p, int filtn, int off);
|
||||||
|
|
||||||
|
#endif //__PIDFILTER_H
|
Loading…
Reference in New Issue
Block a user