@@ -271,14 +271,21 @@
return result;
}
-static int IntArrayToString(char *s, const int *a, int Base = 10, const char n[][MAXLANGCODE2] = NULL)
+static int IntArrayToString(char *s, const int *a, int Base = 10, const char n[][MAXLANGCODE2] = NULL, const int *t = NULL)
{
char *q = s;
int i = 0;
while (a[i] || i == 0) {
q += sprintf(q, Base == 16 ? "%s%X" : "%s%d", i ? "," : "", a[i]);
- if (a[i] && n && *n[i])
- q += sprintf(q, "=%s", n[i]);
+ const char *Delim = "=";
+ if (a[i]) {
+ if (n && *n[i]) {
+ q += sprintf(q, "%s%s", Delim, n[i]);
+ Delim = "";
+ }
+ if (t && t[i])
+ q += sprintf(q, "%s@%d", Delim, t[i]);
+ }
if (!a[i])
break;
i++;
@@ -287,29 +294,29 @@
return q - s;
}
-void cChannel::SetPids(int Vpid, int Ppid, int Vtype, int *Apids, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid)
+void cChannel::SetPids(int Vpid, int Ppid, int Vtype, int *Apids, int *Atypes, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid)
{
int mod = CHANNELMOD_NONE;
if (vpid != Vpid || ppid != Ppid || vtype != Vtype || tpid != Tpid)
mod |= CHANNELMOD_PIDS;
- int m = IntArraysDiffer(apids, Apids, alangs, ALangs) | IntArraysDiffer(dpids, Dpids, dlangs, DLangs) | IntArraysDiffer(spids, Spids, slangs, SLangs);
+ int m = IntArraysDiffer(apids, Apids, alangs, ALangs) | IntArraysDiffer(atypes, Atypes) | IntArraysDiffer(dpids, Dpids, dlangs, DLangs) | IntArraysDiffer(spids, Spids, slangs, SLangs);
if (m & STRDIFF)
mod |= CHANNELMOD_LANGS;
if (m & VALDIFF)
mod |= CHANNELMOD_PIDS;
if (mod) {
- const int BufferSize = (MAXAPIDS + MAXDPIDS) * (5 + 1 + MAXLANGCODE2) + 10; // 5 digits plus delimiting ',' or ';' plus optional '=cod+cod', +10: paranoia
+ const int BufferSize = (MAXAPIDS + MAXDPIDS) * (5 + 1 + MAXLANGCODE2 + 5) + 10; // 5 digits plus delimiting ',' or ';' plus optional '=cod+cod@type', +10: paranoia
char OldApidsBuf[BufferSize];
char NewApidsBuf[BufferSize];
char *q = OldApidsBuf;
- q += IntArrayToString(q, apids, 10, alangs);
+ q += IntArrayToString(q, apids, 10, alangs, atypes);
if (dpids[0]) {
*q++ = ';';
q += IntArrayToString(q, dpids, 10, dlangs);
}
*q = 0;
q = NewApidsBuf;
- q += IntArrayToString(q, Apids, 10, ALangs);
+ q += IntArrayToString(q, Apids, 10, ALangs, Atypes);
if (Dpids[0]) {
*q++ = ';';
q += IntArrayToString(q, Dpids, 10, DLangs);
@@ -331,6 +338,7 @@
vtype = Vtype;
for (int i = 0; i < MAXAPIDS; i++) {
apids[i] = Apids[i];
+ atypes[i] = Atypes[i];
strn0cpy(alangs[i], ALangs[i], MAXLANGCODE2);
}
apids[MAXAPIDS] = 0;
@@ -485,10 +493,10 @@
if (Channel->vpid && Channel->vtype)
q += snprintf(q, sizeof(vpidbuf) - (q - vpidbuf), "=%d", Channel->vtype);
*q = 0;
- const int BufferSize = (MAXAPIDS + MAXDPIDS) * (5 + 1 + MAXLANGCODE2) + 10; // 5 digits plus delimiting ',' or ';' plus optional '=cod+cod', +10: paranoia
+ const int BufferSize = (MAXAPIDS + MAXDPIDS) * (5 + 1 + MAXLANGCODE2 + 5) + 10; // 5 digits plus delimiting ',' or ';' plus optional '=cod+cod@type', +10: paranoia
char apidbuf[BufferSize];
q = apidbuf;
- q += IntArrayToString(q, Channel->apids, 10, Channel->alangs);
+ q += IntArrayToString(q, Channel->apids, 10, Channel->alangs, Channel->atypes);
if (Channel->dpids[0]) {
*q++ = ';';
q += IntArrayToString(q, Channel->dpids, 10, Channel->dlangs);
@@ -547,6 +555,7 @@
vpid = ppid = 0;
vtype = 0;
apids[0] = 0;
+ atypes[0] = 0;
dpids[0] = 0;
ok = false;
if (parambuf && sourcebuf && vpidbuf && apidbuf) {
@@ -580,9 +589,15 @@
char *strtok_next;
while ((q = strtok_r(p, ",", &strtok_next)) != NULL) {
if (NumApids < MAXAPIDS) {
+ atypes[NumApids] = 4; // backwards compatibility
char *l = strchr(q, '=');
if (l) {
*l++ = 0;
+ char *t = strchr(l, '@');
+ if (t) {
+ *t++ = 0;
+ atypes[NumApids] = strtol(t, NULL, 10);
+ }
strn0cpy(alangs[NumApids], l, MAXLANGCODE2);
}
else
@@ -594,6 +609,7 @@
p = NULL;
}
apids[NumApids] = 0;
+ atypes[NumApids] = 0;
if (dpidbuf) {
char *p = dpidbuf;
char *q;
@@ -104,6 +104,7 @@
int ppid;
int vtype;
int apids[MAXAPIDS + 1]; // list is zero-terminated
+ int atypes[MAXAPIDS + 1]; // list is zero-terminated
char alangs[MAXAPIDS][MAXLANGCODE2];
int dpids[MAXDPIDS + 1]; // list is zero-terminated
char dlangs[MAXDPIDS][MAXLANGCODE2];
@@ -156,6 +157,7 @@
const char *Alang(int i) const { return (0 <= i && i < MAXAPIDS) ? alangs[i] : ""; }
const char *Dlang(int i) const { return (0 <= i && i < MAXDPIDS) ? dlangs[i] : ""; }
const char *Slang(int i) const { return (0 <= i && i < MAXSPIDS) ? slangs[i] : ""; }
+ int Atype(int i) const { return (0 <= i && i < MAXAPIDS) ? atypes[i] : 0; }
uchar SubtitlingType(int i) const { return (0 <= i && i < MAXSPIDS) ? subtitlingTypes[i] : uchar(0); }
uint16_t CompositionPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? compositionPageIds[i] : uint16_t(0); }
uint16_t AncillaryPageId(int i) const { return (0 <= i && i < MAXSPIDS) ? ancillaryPageIds[i] : uint16_t(0); }
@@ -185,7 +187,7 @@
void SetId(int Nid, int Tid, int Sid, int Rid = 0);
void SetName(const char *Name, const char *ShortName, const char *Provider);
void SetPortalName(const char *PortalName);
- void SetPids(int Vpid, int Ppid, int Vtype, int *Apids, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid);
+ void SetPids(int Vpid, int Ppid, int Vtype, int *Apids, int *Atypes, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid);
void SetCaIds(const int *CaIds); // list must be zero-terminated
void SetCaDescriptors(int Level);
void SetLinkChannels(cLinkChannels *LinkChannels);
@@ -332,6 +332,7 @@
int Ppid = 0;
int Vtype = 0;
int Apids[MAXAPIDS + 1] = { 0 }; // these lists are zero-terminated
+ int Atypes[MAXDPIDS + 1] = { 0 };
int Dpids[MAXDPIDS + 1] = { 0 };
int Spids[MAXSPIDS + 1] = { 0 };
uchar SubtitlingTypes[MAXSPIDS + 1] = { 0 };
@@ -358,9 +359,12 @@
break;
case 3: // STREAMTYPE_11172_AUDIO
case 4: // STREAMTYPE_13818_AUDIO
+ case 0x0F: // ISO/IEC 13818-7 Audio with ADTS transport sytax
+ case 0x11: // ISO/IEC 14496-3 Audio with LATM transport syntax
{
if (NumApids < MAXAPIDS) {
Apids[NumApids] = esPid;
+ Atypes[NumApids] = stream.getStreamType();
SI::Descriptor *d;
for (SI::Loop::Iterator it; (d = stream.streamDescriptors.getNext(it)); ) {
switch (d->getDescriptorTag()) {
@@ -481,7 +485,7 @@
}
}
if (Setup.UpdateChannels >= 2) {
- Channel->SetPids(Vpid, Ppid, Vtype, Apids, ALangs, Dpids, DLangs, Spids, SLangs, Tpid);
+ Channel->SetPids(Vpid, Ppid, Vtype, Apids, Atypes, ALangs, Dpids, DLangs, Spids, SLangs, Tpid);
Channel->SetCaIds(CaDescriptors->CaIds());
Channel->SetSubtitlingDescriptors(SubtitlingTypes, CompositionPageIds, AncillaryPageIds);
}
@@ -321,7 +321,7 @@
if (Vpid)
i += MakeStream(buf + i, Channel->Vtype(), Vpid);
for (int n = 0; Channel->Apid(n); n++) {
- i += MakeStream(buf + i, 0x04, Channel->Apid(n));
+ i += MakeStream(buf + i, Channel->Atype(n), Channel->Apid(n));
const char *Alang = Channel->Alang(n);
i += MakeLanguageDescriptor(buf + i, Alang);
}
@@ -510,6 +510,8 @@
break;
case 0x03: // STREAMTYPE_11172_AUDIO
case 0x04: // STREAMTYPE_13818_AUDIO
+ case 0x0F: // ISO/IEC 13818-7 Audio with ADTS transport sytax
+ case 0x11: // ISO/IEC 14496-3 Audio with LATM transport syntax
{
if (NumApids < MAXAPIDS) {
apids[NumApids] = stream.getPid();
@@ -204,6 +204,13 @@
.B ...:101=deu,102=eng+spa;103=deu,104=eng:...
+The audio type is appended with a separating '@' character, as in
+
+.B ...:101=deu@4,102=eng+spa@4,105=@4:...
+
+Note that if there is no language code, there still is the separating '='
+if there is an audio type.
+
.TP
.B TPID
The teletext PID.