with knob defaulted to on. (multimedia/vdr-plugin-ttxtsubs, to be committed next.) - Bump PORTVERSION for vdr, and also for its plugins because this is an ABI change.
179 lines
9.2 KiB
Text
179 lines
9.2 KiB
Text
--- a/channels.c
|
|
+++ b/channels.c
|
|
@@ -383,6 +383,26 @@ void cChannel::SetSubtitlingDescriptors(
|
|
}
|
|
}
|
|
|
|
+void cChannel::SetTeletextSubtitlePages(tTeletextSubtitlePage pages[], int numberOfPages)
|
|
+{
|
|
+ int mod = CHANNELMOD_NONE;
|
|
+ if (totalTtxtSubtitlePages != (fixedTtxtSubtitlePages + numberOfPages))
|
|
+ mod |= CHANNELMOD_PIDS;
|
|
+ totalTtxtSubtitlePages = fixedTtxtSubtitlePages;
|
|
+ for (int i = 0; (i < numberOfPages) && (totalTtxtSubtitlePages < MAXTXTPAGES); i++) {
|
|
+ if (teletextSubtitlePages[totalTtxtSubtitlePages].ttxtMagazine != pages[i].ttxtMagazine ||
|
|
+ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtPage != pages[i].ttxtPage ||
|
|
+ teletextSubtitlePages[totalTtxtSubtitlePages].ttxtType != pages[i].ttxtType ||
|
|
+ strcmp(teletextSubtitlePages[totalTtxtSubtitlePages].ttxtLanguage, pages[i].ttxtLanguage)) {
|
|
+ mod |= CHANNELMOD_PIDS;
|
|
+ teletextSubtitlePages[totalTtxtSubtitlePages] = pages[i];
|
|
+ }
|
|
+ totalTtxtSubtitlePages++;
|
|
+ }
|
|
+ modification |= mod;
|
|
+ Channels.SetModified();
|
|
+}
|
|
+
|
|
void cChannel::SetCaIds(const int *CaIds)
|
|
{
|
|
if (caids[0] && caids[0] <= CA_USER_MAX)
|
|
@@ -511,11 +531,24 @@ cString cChannel::ToText(const cChannel
|
|
q += IntArrayToString(q, Channel->dpids, 10, Channel->dlangs, Channel->dtypes);
|
|
}
|
|
*q = 0;
|
|
+ const int TBufferSize = 5 + 1 + (MAXTXTPAGES * (3 + 1 + MAXLANGCODE1 + 1)) + 10; // '12345;150=deu,151=fin,...', +10: paranoia
|
|
+ char tpidbuf[TBufferSize];
|
|
+ q = tpidbuf;
|
|
+ q += snprintf(q, sizeof(tpidbuf), "%d", Channel->tpid);
|
|
+ if (Channel->fixedTtxtSubtitlePages > 0) {
|
|
+ q += snprintf(q, sizeof(tpidbuf) - (q - tpidbuf), ";");
|
|
+ for (int i = 0; i < Channel->fixedTtxtSubtitlePages; ++i) {
|
|
+ tTeletextSubtitlePage page = Channel->teletextSubtitlePages[i];
|
|
+ q += snprintf(q, sizeof(tpidbuf) - (q - tpidbuf),
|
|
+ i + 1 < Channel->fixedTtxtSubtitlePages ? "%d=%s," : "%d=%s",
|
|
+ page.PageNumber(), page.ttxtLanguage);
|
|
+ }
|
|
+ }
|
|
char caidbuf[MAXCAIDS * 5 + 10]; // 5: 4 digits plus delimiting ',', 10: paranoia
|
|
q = caidbuf;
|
|
q += IntArrayToString(q, Channel->caids, 16);
|
|
*q = 0;
|
|
- buffer = cString::sprintf("%s:%d:%s:%s:%d:%s:%s:%d:%s:%d:%d:%d:%d\n", FullName, Channel->frequency, *Channel->parameters, *cSource::ToString(Channel->source), Channel->srate, vpidbuf, apidbuf, Channel->tpid, caidbuf, Channel->sid, Channel->nid, Channel->tid, Channel->rid);
|
|
+ buffer = cString::sprintf("%s:%d:%s:%s:%d:%s:%s:%s:%s:%d:%d:%d:%d\n", FullName, Channel->frequency, *Channel->parameters, *cSource::ToString(Channel->source), Channel->srate, vpidbuf, apidbuf, tpidbuf, caidbuf, Channel->sid, Channel->nid, Channel->tid, Channel->rid);
|
|
}
|
|
return buffer;
|
|
}
|
|
@@ -549,6 +582,7 @@ bool cChannel::Parse(const char *s)
|
|
char *parambuf = NULL;
|
|
char *vpidbuf = NULL;
|
|
char *apidbuf = NULL;
|
|
+ char *tpidbuf = NULL;
|
|
char *caidbuf = NULL;
|
|
#ifdef __FreeBSD__
|
|
namebuf = MALLOC(char, 256);
|
|
@@ -556,10 +590,11 @@ bool cChannel::Parse(const char *s)
|
|
parambuf = MALLOC(char, 256);
|
|
vpidbuf = MALLOC(char, 256);
|
|
apidbuf = MALLOC(char, 256);
|
|
+ tpidbuf = MALLOC(char, 256);
|
|
caidbuf = MALLOC(char, 256);
|
|
- int fields = sscanf(s, "%255[^:]:%d :%255[^:]:%9[^:] :%d :%255[^:]:%255[^:]:%d :%255[^:]:%d :%d :%d :%d ", namebuf, &frequency, parambuf, sourcebuf, &srate, vpidbuf, apidbuf, &tpid, caidbuf, &sid, &nid, &tid, &rid);
|
|
+ int fields = sscanf(s, "%255[^:]:%d :%255[^:]:%9[^:] :%d :%255[^:]:%255[^:]:%255[^:]:%255[^:]:%d :%d :%d :%d ", namebuf, &frequency, parambuf, sourcebuf, &srate, vpidbuf, apidbuf, tpidbuf, caidbuf, &sid, &nid, &tid, &rid);
|
|
#else
|
|
- int fields = sscanf(s, "%a[^:]:%d :%a[^:]:%a[^:] :%d :%a[^:]:%a[^:]:%d :%a[^:]:%d :%d :%d :%d ", &namebuf, &frequency, ¶mbuf, &sourcebuf, &srate, &vpidbuf, &apidbuf, &tpid, &caidbuf, &sid, &nid, &tid, &rid);
|
|
+ int fields = sscanf(s, "%a[^:]:%d :%a[^:]:%a[^:] :%d :%a[^:]:%a[^:]:%a[^:]:%a[^:]:%d :%d :%d :%d ", &namebuf, &frequency, ¶mbuf, &sourcebuf, &srate, &vpidbuf, &apidbuf, &tpidbuf, &caidbuf, &sid, &nid, &tid, &rid);
|
|
#endif
|
|
if (fields >= 9) {
|
|
if (fields == 9) {
|
|
@@ -659,7 +694,37 @@ bool cChannel::Parse(const char *s)
|
|
dpids[NumDpids] = 0;
|
|
dtypes[NumDpids] = 0;
|
|
}
|
|
-
|
|
+ if (tpidbuf) {
|
|
+ char *p;
|
|
+ fixedTtxtSubtitlePages = 0;
|
|
+ // 2001;150=deu,151=fin
|
|
+ if ((p = strchr(tpidbuf, ';')) != NULL) {
|
|
+ char *q, *strtok_next;
|
|
+ *p++ = 0;
|
|
+ while ((q = strtok_r(p, ",", &strtok_next)) != NULL) {
|
|
+ if (fixedTtxtSubtitlePages < MAXTXTPAGES) {
|
|
+ int page;
|
|
+ char *l = strchr(q, '=');
|
|
+ if (l)
|
|
+ *l++ = 0;
|
|
+ if (sscanf(q, "%d", &page) == 1) {
|
|
+ teletextSubtitlePages[fixedTtxtSubtitlePages] = tTeletextSubtitlePage(page);
|
|
+ if (l)
|
|
+ strn0cpy(teletextSubtitlePages[fixedTtxtSubtitlePages].ttxtLanguage, l, MAXLANGCODE1);
|
|
+ fixedTtxtSubtitlePages++;
|
|
+ }
|
|
+ else
|
|
+ esyslog("ERROR: invalid Teletext page!"); // no need to set ok to 'false'
|
|
+ }
|
|
+ else
|
|
+ esyslog("ERROR: too many Teletext pages!"); // no need to set ok to 'false'
|
|
+ p = NULL;
|
|
+ }
|
|
+ totalTtxtSubtitlePages = fixedTtxtSubtitlePages;
|
|
+ }
|
|
+ if (sscanf(tpidbuf, "%d", &tpid) != 1)
|
|
+ return false;
|
|
+ }
|
|
if (caidbuf) {
|
|
char *p = caidbuf;
|
|
char *q;
|
|
@@ -696,6 +761,7 @@ bool cChannel::Parse(const char *s)
|
|
free(sourcebuf);
|
|
free(vpidbuf);
|
|
free(apidbuf);
|
|
+ free(tpidbuf);
|
|
free(caidbuf);
|
|
free(namebuf);
|
|
if (!GetChannelID().Valid()) {
|
|
--- a/pat.c
|
|
+++ b/pat.c
|
|
@@ -17,6 +17,7 @@
|
|
#include "libsi/section.h"
|
|
#include "libsi/descriptor.h"
|
|
#include "thread.h"
|
|
+#include "vdrttxtsubshooks.h"
|
|
|
|
#define PMT_SCAN_TIMEOUT 10 // seconds
|
|
|
|
@@ -347,6 +348,8 @@ void cPatFilter::Process(u_short Pid, u_
|
|
char DLangs[MAXDPIDS][MAXLANGCODE2] = { "" };
|
|
char SLangs[MAXSPIDS][MAXLANGCODE2] = { "" };
|
|
int Tpid = 0;
|
|
+ tTeletextSubtitlePage TeletextSubtitlePages[MAXTXTPAGES];
|
|
+ int NumTPages = 0;
|
|
int NumApids = 0;
|
|
int NumDpids = 0;
|
|
int NumSpids = 0;
|
|
@@ -438,8 +441,21 @@ void cPatFilter::Process(u_short Pid, u_
|
|
NumSpids++;
|
|
}
|
|
break;
|
|
- case SI::TeletextDescriptorTag:
|
|
+ case SI::TeletextDescriptorTag: {
|
|
Tpid = esPid;
|
|
+ SI::TeletextDescriptor *sd = (SI::TeletextDescriptor *)d;
|
|
+ SI::TeletextDescriptor::Teletext ttxt;
|
|
+ for (SI::Loop::Iterator it; sd->teletextLoop.getNext(ttxt, it); ) {
|
|
+ bool isSubtitlePage = (ttxt.getTeletextType() == 0x02) || (ttxt.getTeletextType() == 0x05);
|
|
+ if ((NumTPages < MAXTXTPAGES) && ttxt.languageCode[0] && isSubtitlePage) {
|
|
+ strn0cpy(TeletextSubtitlePages[NumTPages].ttxtLanguage, I18nNormalizeLanguageCode(ttxt.languageCode), MAXLANGCODE1);
|
|
+ TeletextSubtitlePages[NumTPages].ttxtPage = ttxt.getTeletextPageNumber();
|
|
+ TeletextSubtitlePages[NumTPages].ttxtMagazine = ttxt.getTeletextMagazineNumber();
|
|
+ TeletextSubtitlePages[NumTPages].ttxtType = ttxt.getTeletextType();
|
|
+ NumTPages++;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
break;
|
|
case SI::ISO639LanguageDescriptorTag: {
|
|
SI::ISO639LanguageDescriptor *ld = (SI::ISO639LanguageDescriptor *)d;
|
|
@@ -541,6 +557,12 @@ void cPatFilter::Process(u_short Pid, u_
|
|
}
|
|
if (Setup.UpdateChannels >= 2) {
|
|
Channel->SetPids(Vpid, Ppid, Vtype, Apids, Atypes, ALangs, Dpids, Dtypes, DLangs, Spids, SLangs, Tpid);
|
|
+ if (NumTPages < MAXTXTPAGES) {
|
|
+ int manualPageNumber = cVDRTtxtsubsHookListener::Hook()->ManualPageNumber(Channel);
|
|
+ if (manualPageNumber)
|
|
+ TeletextSubtitlePages[NumTPages++] = tTeletextSubtitlePage(manualPageNumber);
|
|
+ }
|
|
+ Channel->SetTeletextSubtitlePages(TeletextSubtitlePages, NumTPages);
|
|
if (!cSource::IsType(Channel->Source(), 'I'))
|
|
Channel->SetCaIds(CaDescriptors->CaIds());
|
|
Channel->SetSubtitlingDescriptors(SubtitlingTypes, CompositionPageIds, AncillaryPageIds);
|