Logo Search packages:      
Sourcecode: kaffeine version File versions

dvbevents.cpp

/***************************************************************************
                          dvbevents.cpp  -  description
                             -------------------
    begin                : Tue Dec 16 2003
    copyright            : (C) 2003-2005 by Christophe Thommeret
    email                : hftom@free.fr
    last modified        : $Date: 2005/02/15 08:18:25 $ by $Author: hftom $
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include <stdio.h>
#include <unistd.h>

#include <qdatetime.h>

#include "dvbevents.h"



DVBevents::DVBevents( bool *ok, int card ) : DVBsection( ok, card )
{
      events.setAutoDelete( true );

      connect ( &cleanTimer, SIGNAL(timeout()), this, SLOT(setClean()) );
      clean = false;
      cleanTimer.start( 3000 );
      demuxOpened = false;
      isRunning = true;
      pf[0].fd = fdDemux;
      pf[0].events = POLLIN;
      start();
}



DVBevents::~DVBevents()
{
      isRunning = false;
      if ( !wait(300) ) {
            terminate();
            wait();
      }
      events.clear();
      cleanTimer.stop();
}



void DVBevents::doClean( bool b )
{
      if ( b ) {
            if ( cleanTimer.isActive() ) return;
            cleanTimer.start( 3000 );
      }
      else {
            cleanTimer.stop();
            clean = false;
      }
}



bool DVBevents::shortEventDesc( unsigned char *buf, EventDesc *desc )
{
      QString name, text;
      int len, len2;
      ShortEvent *ev;

      if ( !safeLen( buf+6 ) ) return false;
      len = getBits(buf,40,8);
      if ( !safeLen( buf+6+len ) ) return false;
      name = getText( buf+6, len );
      if ( !safeLen( buf+6+len+1 ) ) return false;
      len2 = getBits(buf+6+len,0,8);
      if ( !safeLen( buf+7+len+len2 ) ) return false;
      text = getText( buf+7+len, len2);
      if ( desc->title=="" ) {
            desc->title=name;
            desc->subtitle=text;
            return true;
      }
      desc->shortEvents.append( new ShortEvent() );
      ev = desc->shortEvents.getLast();
      ev->name = name;
      ev->text = text;
      return true;
}



bool DVBevents::extEventDesc( unsigned char *buf, EventDesc *desc )
{
      int loop, len1, len2;
      unsigned char *b = buf;
      QString s;

      if ( !safeLen( b+7 ) ) return false;
      loop = getBits(b+6,0,8);
      b +=7;

      while ( loop>0 ) {
            if ( !safeLen( b+1 ) ) return false;
            len1 = getBits(b,0,8);
            if ( !safeLen( b+1+len1 ) ) return false;
            s = getText(b+1,len1);
            if ( !safeLen( b+1+len1+1 ) ) return false;
            len2 = getBits(b+1+len1,0,8);
            if ( !safeLen( buf+2+len1+len2 ) ) return false;
            if ( s!="" ) s = s+" : ";
            s = s+getText(b+2+len1,len2);
            desc->extEvents.append( new QString( s ) );
            b +=(2+len1+len2);
            loop -=(2+len1+len2);
      }
      if ( !safeLen( b+1 ) ) return false;
      len1 = getBits(b,0,8);
      if ( !safeLen( b+1+len1 ) ) return false;
      s = getText(b+1,len1);
      desc->extEvents.append( new QString( s ) );
      return true;
}



bool DVBevents::tableEIT( unsigned char* buffer )
{
      unsigned char* buf = buffer;
      unsigned int length, loop, sid, tid, eid, tsid, sn, lsn;
      int i, sec;
      EventDesc *desc=0, *itdesc=0;
      bool nodesc, process;
      QDateTime start, cur, dt;
      QPtrListIterator<EventDesc> it( events );

      tid = getBits(buf,0,8);
      length = getBits(buf,12,12);
      sid = getBits(buf,24,16);
      sn = getBits(buf,48,8);
      lsn = getBits(buf,56,8);
      tsid = getBits(buf,64,16);
      length -=11;
      buf +=14;

      while ( length>4 ) {
            nodesc=process=false;
            if ( !safeLen( buf+2 ) ) goto stop;
            eid = getBits(buf,0,16);
            if ( !safeLen( buf+2+5 ) ) goto stop;
            start = getDateTime( buf+2 );
            nodesc=process=true;
            it.toFirst();
            while ( (desc = it.current())!=0 ) {
                  if ( desc->sid==sid && desc->tsid==tsid ) {
                        if ( desc->startDateTime==start || desc->eid==eid ) {
                              if ( desc->tid==0x4e && tid!=0x4e ) {
                                    process = false;
                                    nodesc = false;
                                    break;
                              }
                              else {
                                    desc->extEvents.clear();
                                    desc->shortEvents.clear();
                                    desc->title=desc->subtitle="";
                                    nodesc = false;
                                    break;
                              }
                        }
                  }
                  ++it;
            }
            if ( nodesc ) desc = new EventDesc();
            if ( process ) {
                  if ( !safeLen( buf+10 ) ) goto stop;
                  desc->duration = getTime( buf+7 );
                  if ( !safeLen( buf+11 ) ) goto stop;
                  desc->running = getBits(buf,80,3);
                  desc->sid = sid;
                  desc->tid = tid;
                  desc->tsid = tsid;
                  desc->lsn = lsn;
                  desc->sn = sn;
                  desc->eid = eid;
            }

            if ( desc->sn != sn ) return false;
            if ( !safeLen( buf+12 ) ) goto stop;
            loop = getBits(buf,84,12);
            buf +=12;
            length -=(12+loop);
            while ( loop>0 ) {
                  if ( process ) {
                        if ( !safeLen( buf+1 ) ) goto out;
                        switch ( getBits(buf,0,8) ) {
                              case 0x4D :
                                    if ( !shortEventDesc( buf, desc ) ) goto out;
                                    break;
                              case 0x4E :
                                    if ( !extEventDesc( buf, desc ) ) goto out;
                                    break;
                              default :
                                    break;
                        }
                  }
                  if ( !safeLen( buf+2 ) ) goto out;
                  loop -=( getBits(buf,8,8)+2 );
                  buf +=( getBits(buf,8,8)+2 );
            }
out:
            if ( process ) {
                  if ( !nodesc ) {
                        if ( start==desc->startDateTime ) goto ifend;
                        events.take( events.find( desc ) );
                  }
                  desc->startDateTime = start;
                  for ( i=0; i<(int)events.count(); i++ ) {
                        itdesc = events.at(i);
                        if ( desc->startDateTime<itdesc->startDateTime ) {
                              events.insert( i, desc );
                              break;
                        }
                        itdesc = 0;
                  }
                  if ( !itdesc ) events.append( desc );
            }
ifend:
            if ( process ) ++(desc->sn);
            if ( desc->title.length()<3 ) events.remove( desc );
            else if ( nodesc ) {
                  cur = QDateTime::currentDateTime();
                  dt = desc->startDateTime;
                  sec = desc->duration.hour()*3600+desc->duration.minute()*60+desc->duration.second();
                  if ( dt.addSecs( sec )<cur ) events.remove( desc );
            }
      }
      return true;
stop:
      fprintf( stderr, "Stop parsing EIT\n" );
      if ( nodesc ) delete desc;
      return false;
}



bool DVBevents::safeLen( unsigned char* buf )
{
      if ( !(buf>secbuf+4095) ) return true;
      fprintf( stderr, "EIT : buffer overflow !! Rejected\n" );
      return false;
}



bool DVBevents::go( bool all )
{
      int tid;

      if ( demuxOpened ) return true;

      if ( all ) tid = 0;
      else tid = 0x4e;
      if ( !setFilter( 0x12, tid, 100 ) ) return false;
      demuxOpened = true;
      fprintf(stderr,"dvbEvents started\n");
      return true;
}



void DVBevents::stop()
{
      if ( !demuxOpened ) return;

      demuxOpened = false;
      isRunning = false;
      if ( !wait(100) ) {
            terminate();
            wait();
            fprintf(stderr,"dvbEvents terminated\n");
      }
      else fprintf(stderr,"dvbEvents ended\n");
      stopFilter();
      isRunning = true;
      start();
}



void DVBevents::setClean()
{
      clean = true;
}



void DVBevents::run()
{
      int n=0, sec;
      int skip=0;
      QDateTime dt, cur;
      QPtrListIterator<EventDesc> it( events );
      EventDesc *itdesc;

      while ( isRunning ) {
            if ( clean ) {
                  it.toFirst();
                  cur = QDateTime::currentDateTime();
                  while ( (itdesc = it.current())!=0 ) {
                        dt = itdesc->startDateTime;
                        sec = itdesc->duration.hour()*3600+itdesc->duration.minute()*60+itdesc->duration.second();
                        if ( dt.addSecs( sec )<cur ) events.remove( itdesc );
                        ++it;
                  }
                  clean = false;
                  //fprintf(stderr,"%d events\n", events.count());
            }

            if ( !demuxOpened ) {
                  usleep( 100000 );
                  continue;
            }

            if ( poll(pf,1,100)>0 ){
                  if ( pf[0].revents & POLLIN ){
                        n = read( fdDemux, secbuf, 4096 );
                        skip = 0;
                  }
                  else skip++;
            }
            else skip++;

            if (skip) continue;
            if ( n<4 ) continue;

            switch ( getBits(secbuf,0,8) ) {
                  case 0x4E :
                  case 0x4F :
                  case 0x50 : case 0x51 : case 0x52 : case 0x53 : case 0x54 : case 0x55 :
                  case 0x56 : case 0x57 : case 0x58 : case 0x59 : case 0x5A : case 0x5B :
                  case 0x5C : case 0x5D : case 0x5E : case 0x5F :
                  case 0x60 : case 0x61 : case 0x62 : case 0x63 : case 0x64 : case 0x65 :
                  case 0x66 : case 0x67 : case 0x68 : case 0x69 : case 0x6A : case 0x6B :
                  case 0x6C : case 0x6D : case 0x6E : case 0x6F :
                        tableEIT( secbuf );
                        break;
                  default:
                        break;
            }
      }
}



void DVBevents::dumpEvents()
{
      QPtrListIterator<EventDesc> it( events );
      EventDesc *desc;
      QDateTime dt;

      stop();
      it.toFirst();
      if ( it.current() ) dt = it.current()->startDateTime;
      while ( (desc = it.current())!=0 ) {
            if ( desc->startDateTime<dt ) fprintf( stderr,"\nSORT ERROR !!\n");
            else dt = desc->startDateTime;
            fprintf(stderr,"%d %d %d  %s %s\n", desc->tsid, desc->sid, desc->eid, desc->startDateTime.toString().latin1(), desc->title.latin1() );
            ++it;
      }
      go();
}

Generated by  Doxygen 1.6.0   Back to index