diff --git a/CONTRIBUTORS b/CONTRIBUTORS index de1a3be0..93db6e33 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1100,6 +1100,7 @@ Rolf Ahrenberg for implementing handling of HD resolution subtitles according to v1.3.1 of ETSI EN 300 743, chapter 7.2.1 for fixing the array size of Atypes in cPatFilter::Process() + for adding support for "registration descriptor" to 'libsi' and using it in pat.c Ralf Klueber for reporting a bug in cutting a recording if there is only a single editing mark diff --git a/HISTORY b/HISTORY index 4b8d95ca..404f398c 100644 --- a/HISTORY +++ b/HISTORY @@ -6500,3 +6500,5 @@ Video Disk Recorder Revision History channels. To fix the index of existing recordings from such channels, just delete the 'index' file of the recording and VDR will generate a new one the next time you play it. You should also change the line "F 25" to "F 50" in the 'info' file of that recording. +- Added support for "registration descriptor" to 'libsi' and using it in pat.c (thanks + to Rolf Ahrenberg). diff --git a/libsi/descriptor.c b/libsi/descriptor.c index f3bb3442..59f636a3 100644 --- a/libsi/descriptor.c +++ b/libsi/descriptor.c @@ -6,7 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: descriptor.c 1.22 2007/02/03 11:45:58 kls Exp $ + * $Id: descriptor.c 2.1 2010/11/01 15:24:31 kls Exp $ * * ***************************************************************************/ @@ -1032,4 +1032,15 @@ void MHP_ApplicationIconsDescriptor::Parse() { data.setPointerAndOffset(s, offset); } +int RegistrationDescriptor::getFormatIdentifier() const { + return HILOHILO(s->format_identifier); +} + +void RegistrationDescriptor::Parse() { + int offset=0; + data.setPointerAndOffset(s, offset); + if (checkSize(getLength()-offset)) + privateData.assign(data.getData(offset), getLength()-offset); +} + } //end of namespace diff --git a/libsi/descriptor.h b/libsi/descriptor.h index 161793e5..4f2e41b6 100644 --- a/libsi/descriptor.h +++ b/libsi/descriptor.h @@ -6,7 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: descriptor.h 1.16 2007/02/03 11:45:58 kls Exp $ + * $Id: descriptor.h 2.1 2010/11/01 15:24:32 kls Exp $ * * ***************************************************************************/ @@ -660,6 +660,16 @@ private: const descr_application_icons_descriptor_end *s; }; +class RegistrationDescriptor : public Descriptor { +public: + int getFormatIdentifier() const; + CharArray privateData; +protected: + virtual void Parse(); +private: + const descr_registration *s; +}; + } //end of namespace #endif //LIBSI_TABLE_H diff --git a/libsi/headers.h b/libsi/headers.h index db1e261e..3ec35def 100644 --- a/libsi/headers.h +++ b/libsi/headers.h @@ -10,7 +10,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: headers.h 1.9 2007/02/03 11:45:58 kls Exp $ + * $Id: headers.h 2.1 2010/11/01 15:24:32 kls Exp $ * * ***************************************************************************/ @@ -2006,6 +2006,18 @@ struct item_premiere_content_transmission_time { u_char start_time_s :8; }; +/* 0x05 registration_descriptor */ + +#define DESCR_REGISTRATION_LEN 6 +struct descr_registration { + u_char descriptor_tag :8; + u_char descriptor_length :8; + u_char format_identifier_hi_hi :8; + u_char format_identifier_hi_lo :8; + u_char format_identifier_lo_hi :8; + u_char format_identifier_lo_lo :8; +}; + } //end of namespace #endif //LIBSI_HEADERS_H diff --git a/libsi/si.c b/libsi/si.c index 0fd832d8..39911786 100644 --- a/libsi/si.c +++ b/libsi/si.c @@ -6,7 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: si.c 2.2 2010/02/13 10:31:52 kls Exp $ + * $Id: si.c 2.3 2010/11/01 15:24:32 kls Exp $ * * ***************************************************************************/ @@ -606,6 +606,9 @@ Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain, case ExtensionDescriptorTag: d=new ExtensionDescriptor(); break; + case RegistrationDescriptorTag: + d=new RegistrationDescriptor(); + break; //note that it is no problem to implement one //of the unimplemented descriptors. @@ -614,7 +617,6 @@ Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain, case VideoStreamDescriptorTag: case AudioStreamDescriptorTag: case HierarchyDescriptorTag: - case RegistrationDescriptorTag: case DataStreamAlignmentDescriptorTag: case TargetBackgroundGridDescriptorTag: case VideoWindowDescriptorTag: diff --git a/libsi/util.h b/libsi/util.h index 48626723..e9134cd4 100644 --- a/libsi/util.h +++ b/libsi/util.h @@ -6,7 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: util.h 2.1 2008/05/22 10:49:08 kls Exp $ + * $Id: util.h 2.2 2010/11/01 15:24:32 kls Exp $ * * ***************************************************************************/ @@ -19,6 +19,7 @@ #include #define HILO(x) (x##_hi << 8 | x##_lo) +#define HILOHILO(x) (x##_hi_hi << 24 | x##_hi_lo << 16 | x##_lo_hi << 8 | x##_lo_lo) #define BCD_TIME_TO_SECONDS(x) ((3600 * ((10*((x##_h & 0xF0)>>4)) + (x##_h & 0xF))) + \ (60 * ((10*((x##_m & 0xF0)>>4)) + (x##_m & 0xF))) + \ ((10*((x##_s & 0xF0)>>4)) + (x##_s & 0xF))) diff --git a/pat.c b/pat.c index 736ddc21..7d6cfa92 100644 --- a/pat.c +++ b/pat.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: pat.c 2.13 2010/06/13 11:12:12 kls Exp $ + * $Id: pat.c 2.14 2010/11/01 15:34:28 kls Exp $ */ #include "pat.h" @@ -456,21 +456,63 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length } } break; + case 0x80: // STREAMTYPE_USER_PRIVATE + { + SI::Descriptor *d; + for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) { + switch (d->getDescriptorTag()) { + case SI::RegistrationDescriptorTag: { + SI::RegistrationDescriptor *rd = (SI::RegistrationDescriptor *)d; + // http://www.smpte-ra.org/mpegreg/mpegreg.html + switch (rd->getFormatIdentifier()) { + case 0x44434949: // 'DCII' DigiChipher II + Vpid = esPid; + Ppid = pmt.getPCRPid(); + Vtype = stream.getStreamType(); + ProcessCaDescriptors = true; + break; + default: + //printf("Format identifier: 0x08X\n", rd->getFormatIdentifier()); + break; + } + } + break; + default: ; + } + delete d; + } + } + break; case 0x81: // STREAMTYPE_USER_PRIVATE - if (Channel->IsAtsc()) { // ATSC AC-3 - char lang[MAXLANGCODE1] = { 0 }; - SI::Descriptor *d; - for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) { - switch (d->getDescriptorTag()) { - case SI::ISO639LanguageDescriptorTag: { - SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d; - strn0cpy(lang, I18nNormalizeLanguageCode(ld->languageCode), MAXLANGCODE1); - } - break; - default: ; - } - delete d; - } + { + char lang[MAXLANGCODE1] = { 0 }; + bool IsAc3 = false; + SI::Descriptor *d; + for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) { + switch (d->getDescriptorTag()) { + case SI::RegistrationDescriptorTag: { + SI::RegistrationDescriptor *rd = (SI::RegistrationDescriptor *)d; + // http://www.smpte-ra.org/mpegreg/mpegreg.html + switch (rd->getFormatIdentifier()) { + case 0x41432D33: // 'AC-3' + IsAc3 = true; + break; + default: + //printf("Format identifier: 0x08X\n", rd->getFormatIdentifier()); + break; + } + } + break; + case SI::ISO639LanguageDescriptorTag: { + SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d; + strn0cpy(lang, I18nNormalizeLanguageCode(ld->languageCode), MAXLANGCODE1); + } + break; + default: ; + } + delete d; + } + if (IsAc3) { if (NumDpids < MAXDPIDS) { Dpids[NumDpids] = esPid; Dtypes[NumDpids] = SI::AC3DescriptorTag; @@ -479,6 +521,7 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length } ProcessCaDescriptors = true; } + } break; default: ;//printf("PID: %5d %5d %2d %3d %3d\n", pmt.getServiceId(), stream.getPid(), stream.getStreamType(), pmt.getVersionNumber(), Channel->Number()); }