diff -ru orig/vdr-1.3.12/config.c vdr-1.3.12/config.c --- orig/vdr-1.3.12/config.c Sun May 16 14:43:55 2004 +++ vdr-1.3.12/config.c Sun Aug 1 12:22:46 2004 @@ -379,6 +379,21 @@ Store(Name, buffer); } +void cSetup::StoreTracks(const char *Name, char Ids[][4]) +{ + char buffer[4 * MaxPrefAudio + 1]; + char *q = buffer; + for (int i = 0; i < MaxPrefAudio; i++) { + if (!Ids[i][0]) + break; + *q++ = ' '; + strncpy(q, Ids[i], 3); + q += 3; + } + *q = '\0'; + Store(Name, buffer + 1); +} + bool cSetup::ParseLanguages(const char *Value, int *Values) { int n = 0; @@ -395,6 +410,18 @@ return true; } +bool cSetup::ParseTracks(const char *Value, char Ids[][4]) +{ + memset(Ids, '\0', sizeof(char [MaxPrefAudio][4])); + int n = 0; + while (Value && *Value && n < MaxPrefAudio) { + strn0cpy(Ids[n++], Value, 4); + if ((Value = strchr(Value, ' ')) != NULL) + Value++; + } + return true; +} + bool cSetup::Parse(const char *Name, const char *Value) { if (!strcasecmp(Name, "OSDLanguage")) OSDLanguage = atoi(Value); @@ -433,6 +460,7 @@ else if (!strcasecmp(Name, "RecordingDirs")) RecordingDirs = atoi(Value); else if (!strcasecmp(Name, "VideoFormat")) VideoFormat = atoi(Value); else if (!strcasecmp(Name, "UpdateChannels")) UpdateChannels = atoi(Value); + else if (!strcasecmp(Name, "PreferredAudio")) return ParseTracks(Value, PreferredAudio); else if (!strcasecmp(Name, "RecordDolbyDigital")) RecordDolbyDigital = atoi(Value); else if (!strcasecmp(Name, "ChannelInfoPos")) ChannelInfoPos = atoi(Value); else if (!strcasecmp(Name, "OSDLeft")) OSDLeft = atoi(Value); @@ -493,6 +521,7 @@ Store("RecordingDirs", RecordingDirs); Store("VideoFormat", VideoFormat); Store("UpdateChannels", UpdateChannels); + StoreTracks("PreferredAudio", PreferredAudio); Store("RecordDolbyDigital", RecordDolbyDigital); Store("ChannelInfoPos", ChannelInfoPos); Store("OSDLeft", OSDLeft); diff -ru orig/vdr-1.3.12/config.h vdr-1.3.12/config.h --- orig/vdr-1.3.12/config.h Sat Jul 17 13:09:42 2004 +++ vdr-1.3.12/config.h Sun Aug 1 12:22:46 2004 @@ -34,6 +34,7 @@ #define MaxFileName 256 #define MaxSkinName 16 #define MaxThemeName 16 +#define MaxPrefAudio 8 class cCommand : public cListObject { private: @@ -198,6 +199,8 @@ private: void StoreLanguages(const char *Name, int *Values); bool ParseLanguages(const char *Value, int *Values); + void cSetup::StoreTracks(const char *Name, char Ids[][4]); + bool cSetup::ParseTracks(const char *Value, char Ids[][4]); bool Parse(const char *Name, const char *Value); cSetupLine *Get(const char *Name, const char *Plugin = NULL); void Store(const char *Name, const char *Value, const char *Plugin = NULL, bool AllowMultiple = false); @@ -238,6 +241,7 @@ int RecordingDirs; int VideoFormat; int UpdateChannels; + char PreferredAudio[MaxPrefAudio][4]; int RecordDolbyDigital; int ChannelInfoPos; int OSDLeft, OSDTop, OSDWidth, OSDHeight; diff -ru orig/vdr-1.3.12/i18n.c vdr-1.3.12/i18n.c --- orig/vdr-1.3.12/i18n.c Fri May 28 15:19:29 2004 +++ vdr-1.3.12/i18n.c Sun Aug 1 12:22:46 2004 @@ -4634,6 +4634,44 @@ "",// TODO "ST:TNG Konzole", }, + { "Setup.DVB$Preferred audio tracks", // note the plural + "Bevorzugte Tonspuren", + "",// TODO + "",// TODO + "Voorkeur geluidskanalen", + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "Предпочитаемые языки",// TODO + "",// TODO + }, + { "Setup.DVB$Preferred audio track", // note the singular + "Bevorzugte Tonspur", + "",// TODO + "",// TODO + "Voorkeur geluidskanaal", + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "Код языка",// TODO + "",// TODO + }, { NULL } }; diff -ru orig/vdr-1.3.12/menu.c vdr-1.3.12/menu.c --- orig/vdr-1.3.12/menu.c Sun Jun 13 22:26:51 2004 +++ vdr-1.3.12/menu.c Sun Aug 1 12:22:46 2004 @@ -1860,7 +1860,9 @@ class cMenuSetupDVB : public cMenuSetupBase { private: + int numTracks; const char *updateChannelsTexts[5]; + void Setup(void); public: cMenuSetupDVB(void); virtual eOSState ProcessKey(eKeys Key); @@ -1868,29 +1870,55 @@ cMenuSetupDVB::cMenuSetupDVB(void) { + for (numTracks = 0; numTracks < MaxPrefAudio && data.PreferredAudio[numTracks][0]; numTracks++) + ; + SetSection(tr("DVB")); + Setup(); +} + +void cMenuSetupDVB::Setup(void) +{ + int current = Current(); + updateChannelsTexts[0] = tr("no"); updateChannelsTexts[1] = tr("names only"); updateChannelsTexts[2] = tr("names and PIDs"); updateChannelsTexts[3] = tr("add new channels"); updateChannelsTexts[4] = tr("add new transponders"); - SetSection(tr("DVB")); + Clear(); Add(new cMenuEditIntItem( tr("Setup.DVB$Primary DVB interface"), &data.PrimaryDVB, 1, cDevice::NumDevices())); Add(new cMenuEditBoolItem(tr("Setup.DVB$Video format"), &data.VideoFormat, "4:3", "16:9")); Add(new cMenuEditStraItem(tr("Setup.DVB$Update channels"), &data.UpdateChannels, 5, updateChannelsTexts)); + if (data.UpdateChannels >= 2) { + Add(new cMenuEditIntItem( tr("Setup.DVB$Preferred audio tracks"),&numTracks, 0, MaxPrefAudio)); + for (int i = 0; i < numTracks; i++) + Add(new cMenuEditStrItem(tr("Setup.DVB$Preferred audio track"), data.PreferredAudio[i], 4, tr(FileNameChars))); + } + SetCurrent(Get(current)); + Display(); } eOSState cMenuSetupDVB::ProcessKey(eKeys Key) { - int oldPrimaryDVB = Setup.PrimaryDVB; - bool oldVideoFormat = Setup.VideoFormat; + int oldPrimaryDVB = ::Setup.PrimaryDVB; + bool oldVideoFormat = ::Setup.VideoFormat; + int oldUpdateChannels = data.UpdateChannels; + int oldNumTracks = numTracks; + + if (Key == kOk) + for (int i = numTracks; i < MaxPrefAudio; i++) + data.PreferredAudio[i][0] = '\0'; + eOSState state = cMenuSetupBase::ProcessKey(Key); + if (Key != kNone && (oldNumTracks != numTracks || oldUpdateChannels != data.UpdateChannels)) + Setup(); if (state == osBack && Key == kOk) { - if (Setup.PrimaryDVB != oldPrimaryDVB) + if (::Setup.PrimaryDVB != oldPrimaryDVB) state = osSwitchDvb; - if (Setup.VideoFormat != oldVideoFormat) - cDevice::PrimaryDevice()->SetVideoFormat(Setup.VideoFormat); + if (::Setup.VideoFormat != oldVideoFormat) + cDevice::PrimaryDevice()->SetVideoFormat(::Setup.VideoFormat); } return state; } diff -ru orig/vdr-1.3.12/pat.c vdr-1.3.12/pat.c --- orig/vdr-1.3.12/pat.c Sun May 23 11:29:04 2004 +++ vdr-1.3.12/pat.c Sun Aug 1 12:22:46 2004 @@ -269,6 +269,26 @@ return true; } +static void SortPids(int *pids, char langs[][4], int n, char pref[MaxPrefAudio][4]) +{ + int done = 0; + for (int p = 0; done < n && p < MaxPrefAudio && pref[p][0]; p++) { + for (int i = done; i < n; i++) { + if (strcasecmp(pref[p], langs[i]) == 0) { + int pid = pids[i]; + char lang[4]; + strn0cpy(lang, langs[i], 4); + memmove(&langs[done+1], &langs[done], sizeof(langs[0]) * (i-done)); + memmove(&pids[done+1], &pids[done], sizeof(pids[0]) * (i-done)); + pids[done] = pid; + strn0cpy(langs[done], lang, 4); + done++; + break; + } + } + } +} + void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length) { if (Pid == 0x00) { @@ -404,6 +424,7 @@ } } if (Setup.UpdateChannels >= 2) { + SortPids(Apids, ALangs, NumApids, Setup.PreferredAudio); Channel->SetPids(Vpid, Vpid ? Ppid : 0, Apids, ALangs, Dpids, DLangs, Tpid); Channel->SetCaIds(CaDescriptors->CaIds()); }