From 7f3d21f86715d10e9c7ec9a0da1177c9313178d3 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 16 May 2010 13:36:55 +0200 Subject: [PATCH] Added handling MPEG audio types "ISO/IEC 14496-3 Audio with LATM transport syntax" and "ISO/IEC 13818-7 Audio with ADTS transport sytax" --- CONTRIBUTORS | 4 ++++ HISTORY | 4 ++++ channels.c | 38 +++++++++++++++++++++++++++----------- channels.h | 6 ++++-- pat.c | 8 ++++++-- remux.c | 6 ++++-- vdr.5 | 9 ++++++++- 7 files changed, 57 insertions(+), 18 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 80e43803..2332b631 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -2602,6 +2602,10 @@ Paul Menzel Radek Stastny for translating OSD texts to the Czech language +Luis Fernandes + for suggesting to add handling MPEG audio type "ISO/IEC 14496-3 Audio with LATM + transport syntax" + Christopher Reimer for reporting a problem with external Dolby Digital processing via the '-a' option in live mode and with TS recordings diff --git a/HISTORY b/HISTORY index a92ed18f..2ff351da 100644 --- a/HISTORY +++ b/HISTORY @@ -6458,3 +6458,7 @@ Video Disk Recorder Revision History - The EPG data now handles stream components 5 (H.264-video) and 6 (HEAAC-audio). - Fixed a problem with external Dolby Digital processing via the '-a' option in live mode and with TS recordings (reported by Christopher Reimer). +- Added handling MPEG audio types "ISO/IEC 14496-3 Audio with LATM transport syntax" + and "ISO/IEC 13818-7 Audio with ADTS transport sytax" (suggested by Luis Fernandes). + See man vdr(5) on how the APID section of channels has been extended to store + this information. diff --git a/channels.c b/channels.c index 58a42562..f84ea96d 100644 --- a/channels.c +++ b/channels.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: channels.c 2.14 2010/05/02 15:07:38 kls Exp $ + * $Id: channels.c 2.15 2010/05/16 11:44:31 kls Exp $ */ #include "channels.h" @@ -271,14 +271,21 @@ static int IntArraysDiffer(const int *a, const int *b, const char na[][MAXLANGCO 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 @@ static int IntArrayToString(char *s, const int *a, int Base = 10, const char n[] 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 @@ void cChannel::SetPids(int Vpid, int Ppid, int Vtype, int *Apids, char ALangs[][ 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 @@ cString cChannel::ToText(const cChannel *Channel) 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 @@ bool cChannel::Parse(const char *s) 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 @@ bool cChannel::Parse(const char *s) 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 @@ bool cChannel::Parse(const char *s) p = NULL; } apids[NumApids] = 0; + atypes[NumApids] = 0; if (dpidbuf) { char *p = dpidbuf; char *q; diff --git a/channels.h b/channels.h index 5c9727f1..d6aa52fa 100644 --- a/channels.h +++ b/channels.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: channels.h 2.10 2010/03/07 13:47:13 kls Exp $ + * $Id: channels.h 2.11 2010/05/16 11:06:52 kls Exp $ */ #ifndef __CHANNELS_H @@ -104,6 +104,7 @@ private: 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 @@ public: 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 @@ public: 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); diff --git a/pat.c b/pat.c index ae0d9803..d998d40a 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.9 2010/03/27 15:17:46 kls Exp $ + * $Id: pat.c 2.10 2010/05/16 11:12:57 kls Exp $ */ #include "pat.h" @@ -332,6 +332,7 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length 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 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length 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 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length } } 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); } diff --git a/remux.c b/remux.c index 80ebeb77..558cfbfd 100644 --- a/remux.c +++ b/remux.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: remux.c 2.45 2010/05/13 14:16:56 kls Exp $ + * $Id: remux.c 2.46 2010/05/16 12:23:12 kls Exp $ */ #include "remux.h" @@ -321,7 +321,7 @@ void cPatPmtGenerator::GeneratePmt(const cChannel *Channel) 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 @@ void cPatPmtParser::ParsePmt(const uchar *Data, int Length) 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(); diff --git a/vdr.5 b/vdr.5 index 10f717b7..68711b59 100644 --- a/vdr.5 +++ b/vdr.5 @@ -8,7 +8,7 @@ .\" License as specified in the file COPYING that comes with the .\" vdr distribution. .\" -.\" $Id: vdr.5 2.18 2010/04/02 14:46:21 kls Exp $ +.\" $Id: vdr.5 2.19 2010/05/16 12:15:48 kls Exp $ .\" .TH vdr 5 "10 Feb 2008" "1.6" "Video Disk Recorder Files" .SH NAME @@ -204,6 +204,13 @@ can be indicated by adding a second language code, delimited by a '+' sign, as i .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.