From: leslie Date: Tue, 25 Aug 2009 22:03:49 +0000 (+0800) Subject: handle channels with split ECM (see README addition!) X-Git-Tag: upstream/620~186 X-Git-Url: http://www.vanbest.org/gitweb/?a=commitdiff_plain;h=8d6a87d0973e7b839ffab34bf159b19ad9505df0;p=sasc-ng.git handle channels with split ECM (see README addition!) --- diff --git a/README b/README index 111fd7e..d7e4a4f 100644 --- a/README +++ b/README @@ -55,8 +55,17 @@ only recent versions support concurrent recording! Recompile the driver, unload the modules, install the new ones and reload the DVB driver. If you suffer from ARM crashes, add "hw_sections=0" while loading the dvb-ttpci module. -Contrary to older plugin versions (before 0.7.0) you MUST NOT apply any patches -to the VDR core (neither vdr-sc nor ffdecsa/softcsa). +Contrary to older plugin versions (before 0.7.0) you MUST NOT apply patches to +the VDR core (neither vdr-sc nor ffdecsa/softcsa) except if: +- you are using VDR 1.4.x (see section below) +- you are using VDR 1.7.8 or lower and want to view channels with split ECM + +To correctly decode channels with split ECM (i.e. audio and video encrypted +with different CW) you need to apply a patch to the VDR core if you are using +a VDR version before 1.7.9. You can find the "vdr-1.6.0-2-streamca.diff" file +in the patches subdirectory. It has been tested with VDR 1.6.0-2 only, but +probably will apply to other VDR versions as well. This feature is explicitely +not supported for VDR 1.4.x. You must have installed the openssl development files. For most distributions this means to install openssl-devel package. You should use a openssl package diff --git a/cam.c b/cam.c index 165771e..e71de66 100644 --- a/cam.c +++ b/cam.c @@ -600,11 +600,12 @@ bool cEcmData::Parse(const char *buf) int nu=0, num, vers=0; Name[0]=0; if(sscanf(buf,"V%d:%d:%x:%x:%63[^:]:%x/%x:%x:%x/%x:%d:%d/%d%n", - &vers,&prgId,&source,&transponder,Name,&caId,&emmCaId,&provId, + &vers,&grPrgId,&source,&transponder,Name,&caId,&emmCaId,&provId, &ecm_pid,&ecm_table,&rewriterId,&nu,&dataIdx,&num)>=13 && vers==CACHE_VERS) { SetName(Name); SetRewriter(); + prgId=grPrgId%SIDGRP_SHIFT; const char *line=buf+num; if(nu>0 && *line++==':') { unsigned char *dat=AUTOMEM(nu); @@ -629,7 +630,7 @@ cString cEcmData::ToString(bool hide) sprintf(str,"0/%d:",dataIdx); } return cString::sprintf("V%d:%d:%x:%x:%s:%x/%x:%x:%x/%x:%d:%s", - CACHE_VERS,prgId,source,transponder,name, + CACHE_VERS,grPrgId,source,transponder,name, caId,emmCaId,provId,ecm_pid,ecm_table,rewriterId, str); } @@ -651,7 +652,7 @@ void cEcmCache::New(cEcmInfo *e) dat=new cEcmData(e); Add(dat); Modified(); - PRINTF(L_CORE_ECM,"cache add prgId=%d source=%x transponder=%x ecm=%x/%x",e->prgId,e->source,e->transponder,e->ecm_pid,e->ecm_table); + PRINTF(L_CORE_ECM,"cache add prgId=%d source=%x transponder=%x ecm=%x/%x",e->grPrgId,e->source,e->transponder,e->ecm_pid,e->ecm_table); } else { if(strcasecmp(e->name,dat->name)) { @@ -680,7 +681,7 @@ int cEcmCache::GetCached(cSimpleList *list, int sid, int Source, int T if(ScSetup.EcmCache>1) return 0; ListLock(false); for(cEcmData *dat=First(); dat; dat=Next(dat)) { - if(dat->prgId==sid && dat->source==Source && dat->transponder==Transponder) { + if(dat->grPrgId==sid && dat->source==Source && dat->transponder==Transponder) { cEcmInfo *e=new cEcmInfo(dat); if(e) { PRINTF(L_CORE_ECM,"from cache: system %s (%04x) id %04x with ecm %x/%x",e->name,e->caId,e->provId,e->ecm_pid,e->ecm_table); @@ -702,7 +703,7 @@ void cEcmCache::Delete(cEcmInfo *e) ListUnlock(); if(dat) { DelItem(dat); - PRINTF(L_CORE_ECM,"invalidated cached prgId=%d source=%x transponder=%x ecm=%x/%x",dat->prgId,dat->source,dat->transponder,dat->ecm_pid,dat->ecm_table); + PRINTF(L_CORE_ECM,"invalidated cached prgId=%d source=%x transponder=%x ecm=%x/%x",dat->grPrgId,dat->source,dat->transponder,dat->ecm_pid,dat->ecm_table); } } @@ -1474,6 +1475,7 @@ cCam::cCam(cScDvbDevice *dev, int CardNum) source=transponder=-1; liveVpid=liveApid=0; logger=0; hookman=0; memset(lastCW,0,sizeof(lastCW)); memset(indexMap,0,sizeof(indexMap)); + memset(splitSid,0,sizeof(splitSid)); } cCam::~cCam() @@ -1526,6 +1528,7 @@ void cCam::Stop(void) handler->Stop(); if(logger) logger->Down(); if(hookman) hookman->Down(); + memset(splitSid,0,sizeof(splitSid)); } void cCam::AddPrg(cPrg *prg) @@ -1547,20 +1550,113 @@ void cCam::AddPrg(cPrg *prg) LBPUT(" %s=%04x",TYPENAME(pid->type),pid->pid); LBEND(); } - if(prg->pids.Count()>0 && prg->SimplifyCaDescr()) { - PRINTF(L_GEN_WARN,"Stream specific caDescr (aka split-ecm) cannot be handled yet (SID %d)",prg->sid); - // take first caDescr and ignore the rest.... - cPrgPid *pid=prg->pids.First(); - prg->caDescr.Set(&pid->caDescr); - for(; pid; pid=prg->pids.Next(pid)) pid->caDescr.Clear(); - prg->SetPidCaDescr(false); - } - cEcmHandler *handler=GetHandler(prg->sid,needZero,noshift); - if(handler) { - PRINTF(L_CORE_PIDS,"%d: found handler for SID %d (%s idle=%d idx=%d)",cardNum,prg->sid,handler->Id(),handler->IsIdle(),handler->CwIndex()); - prg->source=source; - prg->transponder=transponder; - handler->SetPrg(prg); + bool isSplit=false; + if(prg->pids.Count()>0 && prg->SimplifyCaDescr()) isSplit=true; + else { + for(int i=0; splitSid[i]; i++) + if(splitSid[i]==prg->sid) { isSplit=true; break; } + } + if(!isSplit) { + cEcmHandler *handler=GetHandler(prg->sid,needZero,noshift); + if(handler) { + PRINTF(L_CORE_PIDS,"%d: found handler for SID %d (%s idle=%d idx=%d)",cardNum,prg->sid,handler->Id(),handler->IsIdle(),handler->CwIndex()); + prg->source=source; + prg->transponder=transponder; + handler->SetPrg(prg); + } + } + else { + PRINTF(L_CORE_PIDS,"%d: SID %d is handled as splitted",cardNum,prg->sid); + // first update the splitSid list + if(prg->pids.Count()==0) { // delete + for(int i=0; splitSid[i]; i++) + if(splitSid[i]==prg->sid) { + memmove(&splitSid[i],&splitSid[i+1],sizeof(splitSid[0])*(MAX_SPLIT_SID-i)); + break; + } + PRINTF(L_CORE_PIDS,"%d: deleted from list",cardNum); + } + else { // add + bool has=false; + int i; + for(i=0; splitSid[i]; i++) if(splitSid[i]==prg->sid) has=true; + if(!has) { + if(isid; + splitSid[i+1]=0; + PRINTF(L_CORE_PIDS,"%d: added to list",cardNum); + } + else PRINTF(L_CORE_PIDS,"%d: split SID list overflow",cardNum); + } + } + LBSTART(L_CORE_PIDS); + LBPUT("%d: split SID list now:",cardNum); + for(int i=0; i<=MAX_SPLIT_SID; i++) LBPUT(" %d",splitSid[i]); + LBEND(); + // prepare an empty prg head + cPrg work; + work.source=source; + work.transponder=transponder; + // loop through pids + int group=1; + cPrgPid *first; + while((first=prg->pids.First())) { + LBSTARTF(L_CORE_PIDS); + LBPUT("%d: group %d pids",cardNum,group); + prg->pids.Del(first,false); + work.caDescr.Set(&first->caDescr); + first->caDescr.Clear(); + work.pids.Add(first); + LBPUT(" %04x",first->pid); + for(cPrgPid *pid=prg->pids.First(); pid;) { + cPrgPid *next=prg->pids.Next(pid); + if(work.caDescr==pid->caDescr) { // same group + prg->pids.Del(pid,false); + pid->caDescr.Clear(); + work.pids.Add(pid); + LBPUT(" %04x",pid->pid); + } + pid=next; + } + LBEND(); + // get a handler for the group + int grsid=group*SIDGRP_SHIFT+prg->sid; + cEcmHandler *handler=0; + if(group==1) { + // in the first group check if we have a non-split handler + // for the sid + for(handler=handlerList.First(); handler; handler=handlerList.Next(handler)) + if(handler->Sid()==prg->sid) { + // let GetHandler() take care of needZero/noshift stuff + handler=GetHandler(prg->sid,needZero,noshift); + break; + } + } + // otherwise get the group-sid handler + if(!handler) handler=GetHandler(grsid,needZero,noshift); + if(handler) { + PRINTF(L_CORE_PIDS,"%d: found handler for group-SID %d (%s idle=%d idx=%d)",cardNum,grsid,handler->Id(),handler->IsIdle(),handler->CwIndex()); + work.sid=grsid; + handler->SetPrg(&work); + } + // prepare for next group + work.pids.Clear(); + needZero=false; // only one group can have this + group++; + } + // now we scan the handler list for leftover group handlers + for(cEcmHandler *handler=handlerList.First(); handler; handler=handlerList.Next(handler)) { + int sid=handler->Sid(); + if(!handler->IsIdle() && sid>SIDGRP_SHIFT) { + int gr=sid/SIDGRP_SHIFT; + sid%=SIDGRP_SHIFT; + if(sid==prg->sid && gr>=group) { + PRINTF(L_CORE_PIDS,"%d: idle group handler %s idx=%d",cardNum,handler->Id(),handler->CwIndex()); + work.sid=handler->Sid(); + handler->SetPrg(&work); + } + } + } } } diff --git a/cam.h b/cam.h index 56b81ff..1586332 100644 --- a/cam.h +++ b/cam.h @@ -125,6 +125,7 @@ typedef unsigned short caid_t; #else #define MAX_CI_SLOT_CAIDS 16 #endif +#define MAX_SPLIT_SID 16 class cCam : private cMutex { private: @@ -134,6 +135,7 @@ private: cLogger *logger; cHookManager *hookman; int source, transponder, liveVpid, liveApid; + int splitSid[MAX_SPLIT_SID+1]; unsigned char indexMap[MAX_CW_IDX], lastCW[MAX_CW_IDX][2*8]; // cEcmHandler *GetHandler(int sid, bool needZero, bool noshift); diff --git a/data.c b/data.c index 0027aaa..a24d86b 100644 --- a/data.c +++ b/data.c @@ -587,7 +587,7 @@ cEcmInfo::cEcmInfo(const cEcmInfo *e) provId=e->provId; AddCaDescr(e); dataIdx=e->dataIdx; - prgId=e->prgId; + grPrgId=e->grPrgId; prgId=grPrgId%SIDGRP_SHIFT; source=e->source; transponder=e->transponder; rewriterId=e->rewriterId; @@ -613,20 +613,20 @@ void cEcmInfo::Setup(void) { cached=failed=false; name=0; caDescr=0; caDescrLen=0; dataIdx=-1; - prgId=source=transponder=-1; + prgId=grPrgId=source=transponder=-1; ecm_table=0x80; emmCaId=0; rewriter=0; rewriterId=0; } bool cEcmInfo::Compare(const cEcmInfo *e) { - return prgId==e->prgId && source==e->source && transponder==e->transponder && + return grPrgId==e->grPrgId && source==e->source && transponder==e->transponder && caId==e->caId && ecm_pid==e->ecm_pid && provId==e->provId; } -void cEcmInfo::SetSource(int PrgId, int Source, int Transponder) +void cEcmInfo::SetSource(int GrPrgId, int Source, int Transponder) { - prgId=PrgId; + grPrgId=GrPrgId; prgId=grPrgId%SIDGRP_SHIFT; source=Source; transponder=Transponder; } diff --git a/data.h b/data.h index 0c719bb..e11b830 100644 --- a/data.h +++ b/data.h @@ -217,6 +217,8 @@ public: // ---------------------------------------------------------------- +#define SIDGRP_SHIFT 100000 // for group in split ECM handling + class cEcmInfo : public cStructItem { private: bool cached, failed; @@ -231,7 +233,7 @@ public: char *name; int ecm_pid, ecm_table; int caId, provId, emmCaId; - int prgId, source, transponder; + int prgId, grPrgId, source, transponder; cRewriter *rewriter; int rewriterId; // @@ -241,7 +243,7 @@ public: ~cEcmInfo(); virtual cString ToString(bool hide=false) { return ""; } bool Compare(const cEcmInfo *e); - void SetSource(int PrgId, int Source, int Transponder); + void SetSource(int GrPrgId, int Source, int Transponder); void SetName(const char *Name); void SetDataIdx(int idx); const unsigned char *Data(void) const; diff --git a/patches/vdr-1.6.0-2-streamca.diff b/patches/vdr-1.6.0-2-streamca.diff new file mode 100644 index 0000000..2079843 --- /dev/null +++ b/patches/vdr-1.6.0-2-streamca.diff @@ -0,0 +1,315 @@ +diff -u vdr-1.6.0-2-orig/ci.c vdr/ci.c +--- vdr-1.6.0-2-orig/ci.c 2009-01-15 16:21:16.000000000 -0500 ++++ vdr/ci.c 2009-08-17 05:56:38.000000000 -0400 +@@ -551,6 +551,8 @@ + + // --- cCiCaPmt -------------------------------------------------------------- + ++#define MAXCASYSTEMIDS 64 ++ + // Ca Pmt List Management: + + #define CPLM_MORE 0x00 +@@ -574,9 +576,10 @@ + int length; + int esInfoLengthPos; + uint8_t capmt[2048]; ///< XXX is there a specified maximum? +- int caDescriptorsLength; +- uint8_t caDescriptors[2048]; +- bool streamFlag; ++ int source; ++ int transponder; ++ int programNumber; ++ int caSystemIds[MAXCASYSTEMIDS + 1]; // list is zero terminated! + void AddCaDescriptors(int Length, const uint8_t *Data); + public: + cCiCaPmt(uint8_t CmdId, int Source, int Transponder, int ProgramNumber, const int *CaSystemIds); +@@ -589,7 +592,17 @@ + cCiCaPmt::cCiCaPmt(uint8_t CmdId, int Source, int Transponder, int ProgramNumber, const int *CaSystemIds) + { + cmdId = CmdId; +- caDescriptorsLength = GetCaDescriptors(Source, Transponder, ProgramNumber, CaSystemIds, sizeof(caDescriptors), caDescriptors, streamFlag); ++ source = Source; ++ transponder = Transponder; ++ programNumber = ProgramNumber; ++ int i = 0; ++ if (CaSystemIds) { ++ for (; CaSystemIds[i]; i++) ++ caSystemIds[i] = CaSystemIds[i]; ++ } ++ caSystemIds[i] = 0; ++ uint8_t caDescriptors[512]; ++ int caDescriptorsLength = GetCaDescriptors(source, transponder, programNumber, caSystemIds, sizeof(caDescriptors), caDescriptors, 0); + length = 0; + capmt[length++] = CPLM_ONLY; + capmt[length++] = (ProgramNumber >> 8) & 0xFF; +@@ -597,8 +610,9 @@ + capmt[length++] = 0x01; // version_number, current_next_indicator - apparently vn doesn't matter, but cni must be 1 + esInfoLengthPos = length; + capmt[length++] = 0x00; // program_info_length H (at program level) +- capmt[length++] = 0x00; // program_info_length L +- if (!streamFlag) ++ capmt[length++] = 0x01; // program_info_length L ++ capmt[length++] = cmdId; ++ if (caDescriptorsLength>0) + AddCaDescriptors(caDescriptorsLength, caDescriptors); + } + +@@ -610,14 +624,17 @@ + void cCiCaPmt::AddPid(int Pid, uint8_t StreamType) + { + if (Pid) { ++ uint8_t caDescriptors[512]; ++ int caDescriptorsLength = GetCaDescriptors(source, transponder, programNumber, caSystemIds, sizeof(caDescriptors), caDescriptors, Pid); + //XXX buffer overflow check??? + capmt[length++] = StreamType; + capmt[length++] = (Pid >> 8) & 0xFF; + capmt[length++] = Pid & 0xFF; + esInfoLengthPos = length; + capmt[length++] = 0x00; // ES_info_length H (at ES level) +- capmt[length++] = 0x00; // ES_info_length L +- if (streamFlag) ++ capmt[length++] = 0x01; // ES_info_length L ++ capmt[length++] = cmdId; ++ if (caDescriptorsLength>0) + AddCaDescriptors(caDescriptorsLength, caDescriptors); + } + } +@@ -625,8 +642,7 @@ + void cCiCaPmt::AddCaDescriptors(int Length, const uint8_t *Data) + { + if (esInfoLengthPos) { +- if (length + Length < int(sizeof(capmt))) { +- capmt[length++] = cmdId; ++ if (length + Length <= int(sizeof(capmt))) { + memcpy(capmt + length, Data, Length); + length += Length; + int l = length - esInfoLengthPos - 2; +@@ -643,8 +659,6 @@ + + // --- cCiConditionalAccessSupport ------------------------------------------- + +-#define MAXCASYSTEMIDS 64 +- + // CA Enable Ids: + + #define CAEI_POSSIBLE 0x01 +diff -u vdr-1.6.0-2-orig/pat.c vdr/pat.c +--- vdr-1.6.0-2-orig/pat.c 2008-02-08 08:48:30.000000000 -0500 ++++ vdr/pat.c 2009-08-17 05:58:14.000000000 -0400 +@@ -21,23 +21,23 @@ + class cCaDescriptor : public cListObject { + private: + int caSystem; +- bool stream; ++ int esPid; + int length; + uchar *data; + public: +- cCaDescriptor(int CaSystem, int CaPid, bool Stream, int Length, const uchar *Data); ++ cCaDescriptor(int CaSystem, int CaPid, int EsPid, int Length, const uchar *Data); + virtual ~cCaDescriptor(); + bool operator== (const cCaDescriptor &arg) const; + int CaSystem(void) { return caSystem; } +- int Stream(void) { return stream; } ++ int EsPid(void) { return esPid; } + int Length(void) const { return length; } + const uchar *Data(void) const { return data; } + }; + +-cCaDescriptor::cCaDescriptor(int CaSystem, int CaPid, bool Stream, int Length, const uchar *Data) ++cCaDescriptor::cCaDescriptor(int CaSystem, int CaPid, int EsPid, int Length, const uchar *Data) + { + caSystem = CaSystem; +- stream = Stream; ++ esPid = EsPid; + length = Length + 6; + data = MALLOC(uchar, length); + data[0] = SI::CaDescriptorTag; +@@ -57,7 +57,7 @@ + + bool cCaDescriptor::operator== (const cCaDescriptor &arg) const + { +- return length == arg.length && memcmp(data, arg.data, length) == 0; ++ return esPid == arg.esPid && length == arg.length && memcmp(data, arg.data, length) == 0; + } + + // --- cCaDescriptors -------------------------------------------------------- +@@ -77,8 +77,8 @@ + bool Is(int Source, int Transponder, int ServiceId); + bool Is(cCaDescriptors * CaDescriptors); + bool Empty(void) { return caDescriptors.Count() == 0; } +- void AddCaDescriptor(SI::CaDescriptor *d, bool Stream); +- int GetCaDescriptors(const int *CaSystemIds, int BufSize, uchar *Data, bool &StreamFlag); ++ void AddCaDescriptor(SI::CaDescriptor *d, int EsPid); ++ int GetCaDescriptors(const int *CaSystemIds, int BufSize, uchar *Data, int EsPid); + const int *CaIds(void) { return caIds; } + }; + +@@ -126,9 +126,9 @@ + } + } + +-void cCaDescriptors::AddCaDescriptor(SI::CaDescriptor *d, bool Stream) ++void cCaDescriptors::AddCaDescriptor(SI::CaDescriptor *d, int EsPid) + { +- cCaDescriptor *nca = new cCaDescriptor(d->getCaType(), d->getCaPid(), Stream, d->privateData.getLength(), d->privateData.getData()); ++ cCaDescriptor *nca = new cCaDescriptor(d->getCaType(), d->getCaPid(), EsPid, d->privateData.getLength(), d->privateData.getData()); + for (cCaDescriptor *ca = caDescriptors.First(); ca; ca = caDescriptors.Next(ca)) { + if (*ca == *nca) { + delete nca; +@@ -141,28 +141,30 @@ + #ifdef DEBUG_CA_DESCRIPTORS + char buffer[1024]; + char *q = buffer; +- q += sprintf(q, "CAM: %04X %5d %5d %04X %d -", source, transponder, serviceId, d->getCaType(), Stream); ++ q += sprintf(q, "CAM: %04X %5d %5d %04X %04X -", source, transponder, serviceId, d->getCaType(), EsPid); + for (int i = 0; i < nca->Length(); i++) + q += sprintf(q, " %02X", nca->Data()[i]); + dsyslog(buffer); + #endif + } + +-int cCaDescriptors::GetCaDescriptors(const int *CaSystemIds, int BufSize, uchar *Data, bool &StreamFlag) ++// EsPid is to select the "type" of CaDescriptor to be returned ++// >0 - CaDescriptor for the particular esPid ++// =0 - common CaDescriptor ++// <0 - all CaDescriptors regardless of type (old default) ++ ++int cCaDescriptors::GetCaDescriptors(const int *CaSystemIds, int BufSize, uchar *Data, int EsPid) + { + if (!CaSystemIds || !*CaSystemIds) + return 0; + if (BufSize > 0 && Data) { + int length = 0; +- int IsStream = -1; + for (cCaDescriptor *d = caDescriptors.First(); d; d = caDescriptors.Next(d)) { ++ if(EsPid<0 || d->EsPid()==EsPid) { + const int *caids = CaSystemIds; + do { + if (d->CaSystem() == *caids) { + if (length + d->Length() <= BufSize) { +- if (IsStream >= 0 && IsStream != d->Stream()) +- dsyslog("CAM: different stream flag in CA descriptors"); +- IsStream = d->Stream(); + memcpy(Data + length, d->Data(), d->Length()); + length += d->Length(); + } +@@ -171,7 +173,7 @@ + } + } while (*++caids); + } +- StreamFlag = IsStream == 1; ++ } + return length; + } + return -1; +@@ -187,7 +189,7 @@ + // Returns 0 if this is an already known descriptor, + // 1 if it is an all new descriptor with actual contents, + // and 2 if an existing descriptor was changed. +- int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, bool &StreamFlag); ++ int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, int EsPid); + }; + + int cCaDescriptorHandler::AddCaDescriptors(cCaDescriptors *CaDescriptors) +@@ -208,22 +210,21 @@ + return CaDescriptors->Empty() ? 0 : 1; + } + +-int cCaDescriptorHandler::GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, bool &StreamFlag) ++int cCaDescriptorHandler::GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, int EsPid) + { + cMutexLock MutexLock(&mutex); +- StreamFlag = false; + for (cCaDescriptors *ca = First(); ca; ca = Next(ca)) { + if (ca->Is(Source, Transponder, ServiceId)) +- return ca->GetCaDescriptors(CaSystemIds, BufSize, Data, StreamFlag); ++ return ca->GetCaDescriptors(CaSystemIds, BufSize, Data, EsPid); + } + return 0; + } + + cCaDescriptorHandler CaDescriptorHandler; + +-int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, bool &StreamFlag) ++int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, int EsPid) + { +- return CaDescriptorHandler.GetCaDescriptors(Source, Transponder, ServiceId, CaSystemIds, BufSize, Data, StreamFlag); ++ return CaDescriptorHandler.GetCaDescriptors(Source, Transponder, ServiceId, CaSystemIds, BufSize, Data, EsPid); + } + + // --- cPatFilter ------------------------------------------------------------ +@@ -322,7 +323,7 @@ + cCaDescriptors *CaDescriptors = new cCaDescriptors(Channel->Source(), Channel->Transponder(), Channel->Sid()); + // Scan the common loop: + for (SI::Loop::Iterator it; (d = (SI::CaDescriptor*)pmt.commonDescriptors.getNext(it, SI::CaDescriptorTag)); ) { +- CaDescriptors->AddCaDescriptor(d, false); ++ CaDescriptors->AddCaDescriptor(d, 0); + delete d; + } + // Scan the stream-specific loop: +@@ -340,16 +341,17 @@ + int NumDpids = 0; + int NumSpids = 0; + for (SI::Loop::Iterator it; pmt.streamLoop.getNext(stream, it); ) { ++ int esPid = stream.getPid(); + switch (stream.getStreamType()) { + case 1: // STREAMTYPE_11172_VIDEO + case 2: // STREAMTYPE_13818_VIDEO +- Vpid = stream.getPid(); ++ Vpid = esPid; + break; + case 3: // STREAMTYPE_11172_AUDIO + case 4: // STREAMTYPE_13818_AUDIO + { + if (NumApids < MAXAPIDS) { +- Apids[NumApids] = stream.getPid(); ++ Apids[NumApids] = esPid; + SI::Descriptor *d; + for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) { + switch (d->getDescriptorTag()) { +@@ -388,11 +390,11 @@ + for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) { + switch (d->getDescriptorTag()) { + case SI::AC3DescriptorTag: +- dpid = stream.getPid(); ++ dpid = esPid; + break; + case SI::SubtitlingDescriptorTag: + if (NumSpids < MAXSPIDS) { +- Spids[NumSpids] = stream.getPid(); ++ Spids[NumSpids] = esPid; + SI::SubtitlingDescriptor *sd = (SI::SubtitlingDescriptor *)d; + SI::SubtitlingDescriptor::Subtitling sub; + char *s = SLangs[NumSpids]; +@@ -411,7 +413,7 @@ + } + break; + case SI::TeletextDescriptorTag: +- Tpid = stream.getPid(); ++ Tpid = esPid; + break; + case SI::ISO639LanguageDescriptorTag: { + SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d; +@@ -434,7 +436,7 @@ + //default: printf("PID: %5d %5d %2d %3d %3d\n", pmt.getServiceId(), stream.getPid(), stream.getStreamType(), pmt.getVersionNumber(), Channel->Number());//XXX + } + for (SI::Loop::Iterator it; (d = (SI::CaDescriptor*)stream.streamDescriptors.getNext(it, SI::CaDescriptorTag)); ) { +- CaDescriptors->AddCaDescriptor(d, true); ++ CaDescriptors->AddCaDescriptor(d, esPid); + delete d; + } + } +diff -u vdr-1.6.0-2-orig/pat.h vdr/pat.h +--- vdr-1.6.0-2-orig/pat.h 2007-01-05 05:42:10.000000000 -0500 ++++ vdr/pat.h 2009-06-13 20:17:56.000000000 -0400 +@@ -32,7 +32,7 @@ + void Trigger(void); + }; + +-int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, bool &StreamFlag); ++int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSystemIds, int BufSize, uchar *Data, int EsPid); + ///< Gets all CA descriptors for a given channel. + ///< Copies all available CA descriptors for the given Source, Transponder and ServiceId + ///< into the provided buffer at Data (at most BufSize bytes). Only those CA descriptors diff --git a/systems/cardclient/cccam2.c b/systems/cardclient/cccam2.c index 6589cc4..8868bab 100644 --- a/systems/cardclient/cccam2.c +++ b/systems/cardclient/cccam2.c @@ -692,7 +692,7 @@ bool cCardClientCCcam2::ProcessECM(const cEcmInfo *ecm, const unsigned char *dat cMutexLock lock(this); if(!so.Connected() && !Login()) { Logout(); return false; } if(!CanHandle(ecm->caId)) return false; - PRINTF(L_CC_CCCAM2,"%d: ECM caid %04x prov %04x sid %04x pid %04x",cardnum,ecm->caId,ecm->provId,ecm->prgId,ecm->ecm_pid); + PRINTF(L_CC_CCCAM2,"%d: ECM caid %04x prov %04x sid %d pid %04x",cardnum,ecm->caId,ecm->provId,ecm->prgId,ecm->ecm_pid); int sctlen=SCT_LEN(data); if(sctlen>=256) { PRINTF(L_CC_CCCAM2,"ECM data length >=256 not supported by CCcam"); diff --git a/version.h b/version.h index 3af783e..0afd27b 100644 --- a/version.h +++ b/version.h @@ -25,7 +25,7 @@ extern const char *ScVersion; // SC API version number for loading shared libraries -#define SCAPIVERS 26 +#define SCAPIVERS 27 #ifndef STATICBUILD #define SCAPIVERSTAG() int ScLibApiVersion=SCAPIVERS #else